00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "string.hpp"
00033
00034
00035
00036
00037 #ifdef __CC_GNUC__DISABLED
00038
00039
00040
00041 #else // #include "gstring.cpp"
00042
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 #ifdef __GNUG__
00073
00074 #endif
00075 #ifndef __GSTRING_HPP__
00076 #define __GSTRING_HPP__
00077
00078 #endif
00079
00080 #include <ctype.h>
00081 #include <limits.h>
00082
00083 #include <stdlib.h>
00084
00085
00086
00087 void String::error(const char* ) const
00088 {
00089
00090
00091 }
00092
00093 String::operator const char*() const
00094 {
00095 return (const char*)chars();
00096 }
00097
00098
00099
00100 StrRep _nilStrRep = { 0, 1, { 0 } };
00101 String _nilString;
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 inline static void ncopy(const char* from, char* to, int n)
00121 {
00122 if (from != to) while (--n >= 0) *to++ = *from++;
00123 }
00124
00125
00126 inline static void ncopy0(const char* from, char* to, int n)
00127 {
00128 if (from != to)
00129 {
00130 while (--n >= 0) *to++ = *from++;
00131 *to = 0;
00132 }
00133 else
00134 to[n] = 0;
00135 }
00136
00137
00138 inline static void scopy(const char* from, char* to)
00139 {
00140 if (from != 0) while((*to++ = *from++) != 0);
00141 }
00142
00143
00144 inline static void revcopy(const char* from, char* to, short n)
00145 {
00146 if (from != 0) while (--n >= 0) *to-- = *from--;
00147 }
00148
00149
00150 inline static int slen(const char* t)
00151 {
00152 if (t == 0)
00153 return 0;
00154 else
00155 {
00156 const char* a = t;
00157 while (*a++ != 0);
00158 return (int)(a - 1 - t);
00159 }
00160 }
00161
00162
00163
00164 #define MAXStrRep_SIZE ((1 << (sizeof(short) * CHAR_BIT - 1)) - 1)
00165 #define MINStrRep_SIZE 16
00166
00167 #ifndef MALLOC_MIN_OVERHEAD
00168 #define MALLOC_MIN_OVERHEAD 4
00169 #endif
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 inline static StrRep* Snew(int newsiz)
00180 {
00181 unsigned int siz = sizeof(StrRep) + newsiz + MALLOC_MIN_OVERHEAD;
00182 unsigned int allocsiz = MINStrRep_SIZE;
00183 while (allocsiz < siz) allocsiz <<= 1;
00184 allocsiz -= MALLOC_MIN_OVERHEAD;
00185 if (allocsiz >= MAXStrRep_SIZE) {
00186 cerr << "\nString: Requested length out of range\7\n";
00187 abort();
00188 }
00189
00190
00191 StrRep* rep = (StrRep *) new char[allocsiz];
00192 rep->sz = allocsiz - sizeof(StrRep);
00193 return rep;
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 StrRep* Salloc(StrRep* old, const char* src, int srclen, int newlen)
00207 {
00208 if (old == &_nilStrRep) old = 0;
00209 if (srclen < 0) srclen = slen(src);
00210 if (newlen < srclen) newlen = srclen;
00211 StrRep* rep;
00212 if (old == 0 || newlen > old->sz)
00213 rep = Snew(newlen);
00214 else
00215 rep = old;
00216
00217 rep->len = newlen;
00218 ncopy0(src, rep->s, srclen);
00219
00220 if (old != rep && old != 0) delete old;
00221
00222 return rep;
00223 }
00224
00225
00226
00227
00228
00229 static StrRep*
00230 Sresize(StrRep* old, int newlen)
00231 {
00232 if (old == &_nilStrRep) old = 0;
00233 StrRep* rep;
00234 if (old == 0)
00235 rep = Snew(newlen);
00236 else if (newlen > old->sz)
00237 {
00238 rep = Snew(newlen);
00239 ncopy0(old->s, rep->s, old->len);
00240 delete old;
00241 }
00242 else
00243 rep = old;
00244
00245 rep->len = newlen;
00246
00247 return rep;
00248 }
00249
00250 void
00251 String::alloc (int newsize)
00252 {
00253 unsigned short old_len = rep->len;
00254 rep = Sresize(rep, newsize);
00255 rep->len = old_len;
00256 }
00257
00258
00259
00260 StrRep* Scopy(StrRep* old, const StrRep* s)
00261 {
00262 if (old == &_nilStrRep) old = 0;
00263 if (s == &_nilStrRep) s = 0;
00264 if (old == s)
00265 return (old == 0)? &_nilStrRep : old;
00266 else if (s == 0)
00267 {
00268 old->s[0] = 0;
00269 old->len = 0;
00270 return old;
00271 }
00272 else
00273 {
00274 StrRep* rep;
00275 int newlen = s->len;
00276 if (old == 0 || newlen > old->sz)
00277 {
00278 if (old != 0) delete old;
00279 rep = Snew(newlen);
00280 }
00281 else
00282 rep = old;
00283 rep->len = newlen;
00284 ncopy0(s->s, rep->s, newlen);
00285 return rep;
00286 }
00287 }
00288
00289
00290
00291 StrRep* Scat(StrRep* old, const char* s, int srclen, const char* t, int tlen)
00292 {
00293 if (old == &_nilStrRep) old = 0;
00294 if (srclen < 0) srclen = slen(s);
00295 if (tlen < 0) tlen = slen(t);
00296 int newlen = srclen + tlen;
00297 StrRep* rep;
00298
00299 if (old == 0 || newlen > old->sz ||
00300 (t >= old->s && t < &(old->s[old->len])))
00301 rep = Snew(newlen);
00302 else
00303 rep = old;
00304
00305 rep->len = newlen;
00306
00307 ncopy(s, rep->s, srclen);
00308 ncopy0(t, &(rep->s[srclen]), tlen);
00309
00310 if (old != rep && old != 0) delete old;
00311
00312 return rep;
00313 }
00314
00315
00316
00317 StrRep* Scat(StrRep* old, const char* s, int srclen, const char* t, int tlen,
00318 const char* u, int ulen)
00319 {
00320 if (old == &_nilStrRep) old = 0;
00321 if (srclen < 0) srclen = slen(s);
00322 if (tlen < 0) tlen = slen(t);
00323 if (ulen < 0) ulen = slen(u);
00324 int newlen = srclen + tlen + ulen;
00325 StrRep* rep;
00326 if (old == 0 || newlen > old->sz ||
00327 (t >= old->s && t < &(old->s[old->len])) ||
00328 (u >= old->s && u < &(old->s[old->len])))
00329 rep = Snew(newlen);
00330 else
00331 rep = old;
00332
00333 rep->len = newlen;
00334
00335 ncopy(s, rep->s, srclen);
00336 ncopy(t, &(rep->s[srclen]), tlen);
00337 ncopy0(u, &(rep->s[srclen+tlen]), ulen);
00338
00339 if (old != rep && old != 0) delete old;
00340
00341 return rep;
00342 }
00343
00344
00345
00346 StrRep* Sprepend(StrRep* old, const char* t, int tlen)
00347 {
00348 char* s;
00349 int srclen;
00350 if (old == &_nilStrRep || old == 0)
00351 {
00352 s = 0; old = 0; srclen = 0;
00353 }
00354 else
00355 {
00356 s = old->s; srclen = old->len;
00357 }
00358 if (tlen < 0) tlen = slen(t);
00359 int newlen = srclen + tlen;
00360 StrRep* rep;
00361 if (old == 0 || newlen > old->sz ||
00362 (t >= old->s && t < &(old->s[old->len])))
00363 rep = Snew(newlen);
00364 else
00365 rep = old;
00366
00367 rep->len = newlen;
00368
00369 revcopy(&(s[srclen]), &(rep->s[newlen]), srclen+1);
00370 ncopy(t, rep->s, tlen);
00371
00372 if (old != rep && old != 0) delete old;
00373
00374 return rep;
00375 }
00376
00377
00378
00379
00380 inline static int scmp(const char* a, const char* b)
00381 {
00382 if (b == 0)
00383 return *a != 0;
00384 else
00385 {
00386 signed char diff = 0;
00387 while ((diff = *a - *b++) == 0 && *a++ != 0);
00388 return diff;
00389 }
00390 }
00391
00392
00393 inline static int ncmp(const char* a, int al, const char* b, int bl)
00394 {
00395 int n = (al <= bl)? al : bl;
00396 signed char diff;
00397 while (n-- > 0) if ((diff = *a++ - *b++) != 0) return diff;
00398 return al - bl;
00399 }
00400
00401 int fcompare(const String& x, const String& y)
00402 {
00403 const char* a = x.chars();
00404 const char* b = y.chars();
00405 int al = x.length();
00406 int bl = y.length();
00407 int n = (al <= bl)? al : bl;
00408 signed char diff = 0;
00409 while (n-- > 0)
00410 {
00411 char ac = *a++;
00412 char bc = *b++;
00413 if ((diff = ac - bc) != 0)
00414 {
00415 if (ac >= 'a' && ac <= 'z')
00416 ac = ac - 'a' + 'A';
00417 if (bc >= 'a' && bc <= 'z')
00418 bc = bc - 'a' + 'A';
00419 if ((diff = ac - bc) != 0)
00420 return diff;
00421 }
00422 }
00423 return al - bl;
00424 }
00425
00426
00427
00428
00429 int compare(const String& x, const char* b)
00430 {
00431 return scmp(x.chars(), b);
00432 }
00433
00434 int compare(const String& x, const String& y)
00435 {
00436 return scmp(x.chars(), y.chars());
00437 }
00438
00439 int compare(const String& x, const SubString& y)
00440 {
00441 return ncmp(x.chars(), x.length(), y.chars(), y.length());
00442 }
00443
00444 int compare(const SubString& x, const String& y)
00445 {
00446 return ncmp(x.chars(), x.length(), y.chars(), y.length());
00447 }
00448
00449 int compare(const SubString& x, const SubString& y)
00450 {
00451 return ncmp(x.chars(), x.length(), y.chars(), y.length());
00452 }
00453
00454 int compare(const SubString& x, const char* b)
00455 {
00456 if (b == 0)
00457 return x.length();
00458 else
00459 {
00460 const char* a = x.chars();
00461 int n = x.length();
00462 signed char diff;
00463 while (n-- > 0) if ((diff = *a++ - *b++) != 0) return diff;
00464 return (*b == 0) ? 0 : -1;
00465 }
00466 }
00467
00468
00469
00470
00471
00472 int String::search(int start, int sl, char c) const
00473 {
00474 const char* s = chars();
00475 if (sl > 0)
00476 {
00477 if (start >= 0)
00478 {
00479 const char* a = &(s[start]);
00480 const char* lasta = &(s[sl]);
00481 while (a < lasta) if (*a++ == c) return (int)(--a - s);
00482 }
00483 else
00484 {
00485 const char* a = &(s[sl + start + 1]);
00486 while (--a >= s) if (*a == c) return (int)(a - s);
00487 }
00488 }
00489 return -1;
00490 }
00491
00492 int String::search(int start, int sl, const char* t, int tl) const
00493 {
00494 const char* s = chars();
00495 if (tl < 0) tl = slen(t);
00496 if (sl > 0 && tl > 0)
00497 {
00498 if (start >= 0)
00499 {
00500 const char* lasts = &(s[sl - tl]);
00501 const char* lastt = &(t[tl]);
00502 const char* p = &(s[start]);
00503
00504 while (p <= lasts)
00505 {
00506 const char* x = p++;
00507 const char* y = t;
00508 while (*x++ == *y++) if (y >= lastt) return (int)(--p - s);
00509 }
00510 }
00511 else
00512 {
00513 const char* firsts = &(s[tl - 1]);
00514 const char* lastt = &(t[tl - 1]);
00515 const char* p = &(s[sl + start + 1]);
00516
00517 while (--p >= firsts)
00518 {
00519 const char* x = p;
00520 const char* y = lastt;
00521 while (*x-- == *y--) if (y < t) return (int)(++x - s);
00522 }
00523 }
00524 }
00525 return -1;
00526 }
00527
00528 int String::match(int start, int sl, int exact, const char* t, int tl) const
00529 {
00530 if (tl < 0) tl = slen(t);
00531
00532 if (start < 0)
00533 {
00534 start = sl + start - tl + 1;
00535 if (start < 0 || (exact && start != 0))
00536 return -1;
00537 }
00538 else if (exact && sl - start != tl)
00539 return -1;
00540
00541 if (sl == 0 || tl == 0 || sl - start < tl || start >= sl)
00542 return -1;
00543
00544 int n = tl;
00545 const char* s = &(rep->s[start]);
00546 while (--n >= 0) if (*s++ != *t++) return -1;
00547 return tl;
00548 }
00549
00550 void SubString::assign(const StrRep* ysrc, const char* ys, int ylen)
00551 {
00552 if (&S == &_nilString) return;
00553
00554 if (ylen < 0) ylen = slen(ys);
00555 StrRep* targ = S.rep;
00556 int sl = targ->len - len + ylen;
00557
00558 if (ysrc == targ || sl >= targ->sz)
00559 {
00560 StrRep* oldtarg = targ;
00561 targ = Sresize(0, sl);
00562 ncopy(oldtarg->s, targ->s, pos);
00563 ncopy(ys, &(targ->s[pos]), ylen);
00564 scopy(&(oldtarg->s[pos + len]), &(targ->s[pos + ylen]));
00565 delete oldtarg;
00566 }
00567 else if (len == ylen)
00568 ncopy(ys, &(targ->s[pos]), len);
00569 else if (ylen < len)
00570 {
00571 ncopy(ys, &(targ->s[pos]), ylen);
00572 scopy(&(targ->s[pos + len]), &(targ->s[pos + ylen]));
00573 }
00574 else
00575 {
00576 revcopy(&(targ->s[targ->len]), &(targ->s[sl]), targ->len-pos-len +1);
00577 ncopy(ys, &(targ->s[pos]), ylen);
00578 }
00579 targ->len = sl;
00580 S.rep = targ;
00581 }
00582
00583
00584
00585
00586
00587
00588
00589
00590 int String::_gsub(const char* pat, int pl, const char* r, int rl)
00591 {
00592 int nmatches = 0;
00593 if (pl < 0) pl = slen(pat);
00594 if (rl < 0) rl = slen(r);
00595 int sl = length();
00596 if (sl <= 0 || pl <= 0 || sl < pl)
00597 return nmatches;
00598
00599 const char* s = chars();
00600
00601
00602 StrRep* nrep = 0;
00603 int nsz = 0;
00604 char* x = 0;
00605
00606 int si = 0;
00607 int xi = 0;
00608 int remaining = sl;
00609
00610 while (remaining >= pl)
00611 {
00612 int pos = search(si, sl, pat, pl);
00613 if (pos < 0)
00614 break;
00615 else
00616 {
00617 ++nmatches;
00618 int mustfit = xi + remaining + rl - pl;
00619 if (mustfit >= nsz)
00620 {
00621 if (nrep != 0) nrep->len = xi;
00622 nrep = Sresize(nrep, mustfit);
00623 nsz = nrep->sz;
00624 x = nrep->s;
00625 }
00626 pos -= si;
00627 ncopy(&(s[si]), &(x[xi]), pos);
00628 ncopy(r, &(x[xi + pos]), rl);
00629 si += pos + pl;
00630 remaining -= pos + pl;
00631 xi += pos + rl;
00632 }
00633 }
00634
00635 if (nrep == 0)
00636 {
00637 if (nmatches == 0)
00638 return nmatches;
00639 else
00640 nrep = Sresize(nrep, xi+remaining);
00641 }
00642
00643 ncopy0(&(s[si]), &(x[xi]), remaining);
00644 nrep->len = xi + remaining;
00645
00646 if (nrep->len <= rep->sz)
00647 {
00648 rep->len = nrep->len;
00649 ncopy0(nrep->s, rep->s, rep->len);
00650 delete(nrep);
00651 }
00652 else
00653 {
00654 delete(rep);
00655 rep = nrep;
00656 }
00657 return nmatches;
00658 }
00659
00660
00661
00662
00663
00664 void String::del(int pos, int len)
00665 {
00666 if (pos < 0 || len <= 0 || (unsigned)(pos + len) > length()) return;
00667 int nlen = length() - len;
00668 int first = pos + len;
00669 ncopy0(&(rep->s[first]), &(rep->s[pos]), length() - first);
00670 rep->len = nlen;
00671 }
00672
00673 void String::del(const char* t, int startpos)
00674 {
00675 int tlen = slen(t);
00676 int p = search(startpos, length(), t, tlen);
00677 del(p, tlen);
00678 }
00679
00680 void String::del(const String& y, int startpos)
00681 {
00682 del(search(startpos, length(), y.chars(), y.length()), y.length());
00683 }
00684
00685 void String::del(const SubString& y, int startpos)
00686 {
00687 del(search(startpos, length(), y.chars(), y.length()), y.length());
00688 }
00689
00690 void String::del(char c, int startpos)
00691 {
00692 del(search(startpos, length(), c), 1);
00693 }
00694
00695
00696
00697
00698
00699
00700 SubString String::at(int first, int len)
00701 {
00702 return _substr(first, len);
00703 }
00704
00705 SubString String::operator() (int first, int len)
00706 {
00707 return _substr(first, len);
00708 }
00709
00710 SubString String::before(int pos)
00711 {
00712 return _substr(0, pos);
00713 }
00714
00715 SubString String::through(int pos)
00716 {
00717 return _substr(0, pos+1);
00718 }
00719
00720 SubString String::after(int pos)
00721 {
00722 return _substr(pos + 1, length() - (pos + 1));
00723 }
00724
00725 SubString String::from(int pos)
00726 {
00727 return _substr(pos, length() - pos);
00728 }
00729
00730 SubString String::at(const String& y, int startpos)
00731 {
00732 int first = search(startpos, length(), y.chars(), y.length());
00733 return _substr(first, y.length());
00734 }
00735
00736 SubString String::at(const SubString& y, int startpos)
00737 {
00738 int first = search(startpos, length(), y.chars(), y.length());
00739 return _substr(first, y.length());
00740 }
00741
00742 SubString String::at(const char* t, int startpos)
00743 {
00744 int tlen = slen(t);
00745 int first = search(startpos, length(), t, tlen);
00746 return _substr(first, tlen);
00747 }
00748
00749 SubString String::at(char c, int startpos)
00750 {
00751 int first = search(startpos, length(), c);
00752 return _substr(first, 1);
00753 }
00754
00755 SubString String::before(const String& y, int startpos)
00756 {
00757 int last = search(startpos, length(), y.chars(), y.length());
00758 return _substr(0, last);
00759 }
00760
00761 SubString String::before(const SubString& y, int startpos)
00762 {
00763 int last = search(startpos, length(), y.chars(), y.length());
00764 return _substr(0, last);
00765 }
00766
00767 SubString String::before(char c, int startpos)
00768 {
00769 int last = search(startpos, length(), c);
00770 return _substr(0, last);
00771 }
00772
00773 SubString String::before(const char* t, int startpos)
00774 {
00775 int tlen = slen(t);
00776 int last = search(startpos, length(), t, tlen);
00777 return _substr(0, last);
00778 }
00779
00780 SubString String::through(const String& y, int startpos)
00781 {
00782 int last = search(startpos, length(), y.chars(), y.length());
00783 if (last >= 0) last += y.length();
00784 return _substr(0, last);
00785 }
00786
00787 SubString String::through(const SubString& y, int startpos)
00788 {
00789 int last = search(startpos, length(), y.chars(), y.length());
00790 if (last >= 0) last += y.length();
00791 return _substr(0, last);
00792 }
00793
00794 SubString String::through(char c, int startpos)
00795 {
00796 int last = search(startpos, length(), c);
00797 if (last >= 0) last += 1;
00798 return _substr(0, last);
00799 }
00800
00801 SubString String::through(const char* t, int startpos)
00802 {
00803 int tlen = slen(t);
00804 int last = search(startpos, length(), t, tlen);
00805 if (last >= 0) last += tlen;
00806 return _substr(0, last);
00807 }
00808
00809 SubString String::after(const String& y, int startpos)
00810 {
00811 int first = search(startpos, length(), y.chars(), y.length());
00812 if (first >= 0) first += y.length();
00813 return _substr(first, length() - first);
00814 }
00815
00816 SubString String::after(const SubString& y, int startpos)
00817 {
00818 int first = search(startpos, length(), y.chars(), y.length());
00819 if (first >= 0) first += y.length();
00820 return _substr(first, length() - first);
00821 }
00822
00823 SubString String::after(char c, int startpos)
00824 {
00825 int first = search(startpos, length(), c);
00826 if (first >= 0) first += 1;
00827 return _substr(first, length() - first);
00828 }
00829
00830 SubString String::after(const char* t, int startpos)
00831 {
00832 int tlen = slen(t);
00833 int first = search(startpos, length(), t, tlen);
00834 if (first >= 0) first += tlen;
00835 return _substr(first, length() - first);
00836 }
00837
00838 SubString String::from(const String& y, int startpos)
00839 {
00840 int first = search(startpos, length(), y.chars(), y.length());
00841 return _substr(first, length() - first);
00842 }
00843
00844 SubString String::from(const SubString& y, int startpos)
00845 {
00846 int first = search(startpos, length(), y.chars(), y.length());
00847 return _substr(first, length() - first);
00848 }
00849
00850 SubString String::from(char c, int startpos)
00851 {
00852 int first = search(startpos, length(), c);
00853 return _substr(first, length() - first);
00854 }
00855
00856 SubString String::from(const char* t, int startpos)
00857 {
00858 int tlen = slen(t);
00859 int first = search(startpos, length(), t, tlen);
00860 return _substr(first, length() - first);
00861 }
00862
00863
00864
00865
00866
00867
00868
00869
00870 int split(const String& src, String results[], int n, const String& sep)
00871 {
00872 String x = src;
00873 const char* s = x.chars();
00874 int sl = x.length();
00875 int i = 0;
00876 int pos = 0;
00877 while (i < n && pos < sl)
00878 {
00879 int p = x.search(pos, sl, sep.chars(), sep.length());
00880 if (p < 0)
00881 p = sl;
00882 results[i].rep = Salloc(results[i].rep, &(s[pos]), p - pos, p - pos);
00883 i++;
00884 pos = p + sep.length();
00885 }
00886 return i;
00887 }
00888
00889 #if defined(__GNUG__) && !defined(_G_NO_NRV)
00890 #define RETURN(r) return
00891 #define RETURNS(r) return r;
00892 #define RETURN_OBJECT(TYPE, NAME)
00893 #else
00894 #define RETURN(r) return r
00895 #define RETURNS(r)
00896 #define RETURN_OBJECT(TYPE, NAME) TYPE NAME;
00897 #endif
00898
00899 String join(String src[], int n, const String& separator) RETURNS(x)
00900 {
00901 RETURN_OBJECT(String,x)
00902 String sep = separator;
00903 int xlen = 0;
00904 int i;
00905 for (i = 0; i < n; ++i)
00906 xlen += src[i].length();
00907 xlen += (n - 1) * sep.length();
00908
00909 x.rep = Sresize (x.rep, xlen);
00910
00911 int j = 0;
00912
00913 for (i = 0; i < n - 1; ++i)
00914 {
00915 ncopy(src[i].chars(), &(x.rep->s[j]), src[i].length());
00916 j += src[i].length();
00917 ncopy(sep.chars(), &(x.rep->s[j]), sep.length());
00918 j += sep.length();
00919 }
00920 ncopy0(src[i].chars(), &(x.rep->s[j]), src[i].length());
00921 RETURN(x);
00922 }
00923
00924
00925
00926
00927
00928
00929 StrRep* Sreverse(const StrRep* src, StrRep* dest)
00930 {
00931 int n = src->len;
00932 if (src != dest)
00933 dest = Salloc(dest, src->s, n, n);
00934 if (n > 0)
00935 {
00936 char* a = dest->s;
00937 char* b = &(a[n - 1]);
00938 while (a < b)
00939 {
00940 char t = *a;
00941 *a++ = *b;
00942 *b-- = t;
00943 }
00944 }
00945 return dest;
00946 }
00947
00948
00949 StrRep* Supcase(const StrRep* src, StrRep* dest)
00950 {
00951 int n = src->len;
00952 if (src != dest) dest = Salloc(dest, src->s, n, n);
00953 char* p = dest->s;
00954 char* e = &(p[n]);
00955 for (; p < e; ++p) if (islower(*p)) *p = toupper(*p);
00956 return dest;
00957 }
00958
00959 StrRep* Sdowncase(const StrRep* src, StrRep* dest)
00960 {
00961 int n = src->len;
00962 if (src != dest) dest = Salloc(dest, src->s, n, n);
00963 char* p = dest->s;
00964 char* e = &(p[n]);
00965 for (; p < e; ++p) if (isupper(*p)) *p = tolower(*p);
00966 return dest;
00967 }
00968
00969 StrRep* Scapitalize(const StrRep* src, StrRep* dest)
00970 {
00971 int n = src->len;
00972 if (src != dest) dest = Salloc(dest, src->s, n, n);
00973
00974 char* p = dest->s;
00975 char* e = &(p[n]);
00976 for (; p < e; ++p)
00977 {
00978 int at_word;
00979 if ((at_word = islower(*p))!=0)
00980 *p = toupper(*p);
00981 else
00982 at_word = isupper(*p) || isdigit(*p);
00983
00984 if (at_word)
00985 {
00986 while (++p < e)
00987 {
00988 if (isupper(*p))
00989 *p = tolower(*p);
00990
00991
00992 else if (!islower(*p) && !isdigit(*p) && (*p != '\''))
00993 break;
00994 }
00995 }
00996 }
00997 return dest;
00998 }
00999
01000 #if defined(__GNUG__) && !defined(_G_NO_NRV)
01001
01002 String replicate(char c, int n) return w;
01003 {
01004 w.rep = Sresize(w.rep, n);
01005 char* p = w.rep->s;
01006 while (n-- > 0) *p++ = c;
01007 *p = 0;
01008 }
01009
01010 String replicate(const String& y, int n) return w
01011 {
01012 int len = y.length();
01013 w.rep = Sresize(w.rep, n * len);
01014 char* p = w.rep->s;
01015 while (n-- > 0)
01016 {
01017 ncopy(y.chars(), p, len);
01018 p += len;
01019 }
01020 *p = 0;
01021 }
01022
01023 String common_prefix(const String& x, const String& y, int startpos) return r;
01024 {
01025 const char* xchars = x.chars();
01026 const char* ychars = y.chars();
01027 const char* xs = &(xchars[startpos]);
01028 const char* ss = xs;
01029 const char* topx = &(xchars[x.length()]);
01030 const char* ys = &(ychars[startpos]);
01031 const char* topy = &(ychars[y.length()]);
01032 int l;
01033 for (l = 0; xs < topx && ys < topy && *xs++ == *ys++; ++l);
01034 r.rep = Salloc(r.rep, ss, l, l);
01035 }
01036
01037 String common_suffix(const String& x, const String& y, int startpos) return r;
01038 {
01039 const char* xchars = x.chars();
01040 const char* ychars = y.chars();
01041 const char* xs = &(xchars[x.length() + startpos]);
01042 const char* botx = xchars;
01043 const char* ys = &(ychars[y.length() + startpos]);
01044 const char* boty = ychars;
01045 int l;
01046 for (l = 0; xs >= botx && ys >= boty && *xs == *ys ; --xs, --ys, ++l);
01047 r.rep = Salloc(r.rep, ++xs, l, l);
01048 }
01049
01050 #else
01051
01052 String replicate(char c, int n)
01053 {
01054 String w;
01055 w.rep = Sresize(w.rep, n);
01056 char* p = w.rep->s;
01057 while (n-- > 0) *p++ = c;
01058 *p = 0;
01059 return w;
01060 }
01061
01062 String replicate(const String& y, int n)
01063 {
01064 String w;
01065 int len = y.length();
01066 w.rep = Sresize(w.rep, n * len);
01067 char* p = w.rep->s;
01068 while (n-- > 0)
01069 {
01070 ncopy(y.chars(), p, len);
01071 p += len;
01072 }
01073 *p = 0;
01074 return w;
01075 }
01076
01077 String common_prefix(const String& x, const String& y, int startpos)
01078 {
01079 String r;
01080 const char* xchars = x.chars();
01081 const char* ychars = y.chars();
01082 const char* xs = &(xchars[startpos]);
01083 const char* ss = xs;
01084 const char* topx = &(xchars[x.length()]);
01085 const char* ys = &(ychars[startpos]);
01086 const char* topy = &(ychars[y.length()]);
01087 for (int l = 0; xs < topx && ys < topy && *xs++ == *ys++; ++l);
01088 r.rep = Salloc(r.rep, ss, l, l);
01089 return r;
01090 }
01091
01092 String common_suffix(const String& x, const String& y, int startpos)
01093 {
01094 String r;
01095 const char* xchars = x.chars();
01096 const char* ychars = y.chars();
01097 const char* xs = &(xchars[x.length() + startpos]);
01098 const char* botx = xchars;
01099 const char* ys = &(ychars[y.length() + startpos]);
01100 const char* boty = ychars;
01101 for (int l = 0; xs >= botx && ys >= boty && *xs == *ys ; --xs, --ys, ++l);
01102 r.rep = Salloc(r.rep, ++xs, l, l);
01103 return r;
01104 }
01105
01106 #endif
01107
01108
01109
01110 istream& operator>>(istream& s, String& x)
01111 {
01112 if (!s.ipfx(0) || (!(s.flags() & ios::skipws) && !ws(s)))
01113 {
01114 s.clear(ios::failbit|s.rdstate());
01115 return s;
01116 }
01117 int ch;
01118 int i = 0;
01119 x.rep = Sresize(x.rep, 20);
01120 register streambuf *sb = s.rdbuf();
01121 while ((ch = sb->sbumpc()) != EOF)
01122 {
01123 if (isspace(ch))
01124 break;
01125 if (i >= x.rep->sz - 1)
01126 x.rep = Sresize(x.rep, i+1);
01127 x.rep->s[i++] = ch;
01128 }
01129 x.rep->s[i] = 0;
01130 x.rep->len = i;
01131 int new_state = s.rdstate();
01132 if (i == 0) new_state |= ios::failbit;
01133 if (ch == EOF) new_state |= ios::eofbit;
01134 s.clear(new_state);
01135 return s;
01136 }
01137
01138 int readline(istream& s, String& x, char terminator, int discard)
01139 {
01140 if (!s.ipfx(0))
01141 return 0;
01142 int ch;
01143 int i = 0;
01144 x.rep = Sresize(x.rep, 80);
01145 register streambuf *sb = s.rdbuf();
01146 while ((ch = sb->sbumpc()) != EOF)
01147 {
01148 if (ch != terminator || !discard)
01149 {
01150 if (i >= x.rep->sz - 1)
01151 x.rep = Sresize(x.rep, i+1);
01152 x.rep->s[i++] = ch;
01153 }
01154 if (ch == terminator)
01155 break;
01156 }
01157 x.rep->s[i] = 0;
01158 x.rep->len = i;
01159 if (ch == EOF) s.clear(ios::eofbit|s.rdstate());
01160 return i;
01161 }
01162
01163
01164 ostream& operator<<(ostream& s, const SubString& x)
01165 {
01166 const char* a = x.chars();
01167 const char* lasta = &(a[x.length()]);
01168 while (a < lasta)
01169 s.put(*a++);
01170 return(s);
01171 }
01172
01173
01174
01175 int String::freq(const SubString& y) const
01176 {
01177 int found = 0;
01178 for (unsigned int i = 0; i < length(); i++)
01179 if (match(i,length(),0,y.chars(), y.length())>= 0) found++;
01180 return(found);
01181 }
01182
01183 int String::freq(const String& y) const
01184 {
01185 int found = 0;
01186 for (unsigned int i = 0; i < length(); i++)
01187 if (match(i,length(),0,y.chars(),y.length()) >= 0) found++;
01188 return(found);
01189 }
01190
01191 int String::freq(const char* t) const
01192 {
01193 int found = 0;
01194 for (unsigned int i = 0; i < length(); i++)
01195 if (match(i,length(),0,t) >= 0) found++;
01196 return(found);
01197 }
01198
01199 int String::freq(char c) const
01200 {
01201 int found = 0;
01202 for (unsigned int i = 0; i < length(); i++)
01203 if (match(i,length(),0,&c,1) >= 0) found++;
01204 return(found);
01205 }
01206
01207
01208 int String::OK() const
01209 {
01210 if (rep == 0
01211 || rep->len > rep->sz
01212 || rep->s[rep->len] != 0)
01213 error("invariant failure");
01214 return 1;
01215 }
01216
01217 int SubString::OK() const
01218 {
01219 int v = S != (const char*)0;
01220 v &= S.OK();
01221 v &= pos + len >= S.rep->len;
01222 if (!v) S.error("SubString invariant failure");
01223 return v;
01224 }
01225
01227
01228 #endif // #include "gstring.cpp"
01229
01230