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
00033
00034 # include "lclintMacros.nf"
00035 # include "basic.h"
00036 # include "osd.h"
00037 # include "portab.h"
00038
00039 static
00040 cstring cstring_newEmpty (void)
00041 {
00042 return (cstring_create (0));
00043 }
00044
00045 char cstring_firstChar (cstring s)
00046 {
00047 llassert (cstring_isDefined (s));
00048 llassert (cstring_length (s) > 0);
00049
00050 return (s[0]);
00051 }
00052
00053 char cstring_getChar (cstring s, int n)
00054 {
00055 int length = cstring_length (s);
00056
00057 llassert (cstring_isDefined (s));
00058 llassert (n >= 1 && n <= length);
00059
00060 return (s[n - 1]);
00061 }
00062
00063 cstring cstring_suffix (cstring s, int n)
00064 {
00065 llassert (cstring_isDefined (s));
00066 llassert (n <= cstring_length (s));
00067
00068 return (s + n);
00069 }
00070
00071 cstring cstring_prefix (cstring s, int n)
00072 {
00073 cstring t;
00074 char c;
00075 llassert (cstring_isDefined (s));
00076 llassert (n <= cstring_length (s));
00077
00078 c = *(s + n);
00079
00080 *(s + n) = '\0';
00081 t = cstring_copy (s);
00082 *(s + n) = c;
00083
00084
00085 return t;
00086 }
00087
00088
00089
00090
00091
00092 int cstring_toPosInt (cstring s)
00093 {
00094 int val = 0;
00095
00096 cstring_chars (s, c)
00097 {
00098 if (isdigit ((unsigned char) c))
00099 {
00100 val = (val * 10) + (int)(c - '0');
00101 }
00102 else
00103 {
00104 return -1;
00105 }
00106 } end_cstring_chars ;
00107
00108 return val;
00109 }
00110
00111 cstring cstring_beforeChar (cstring s, char c)
00112 {
00113 if (cstring_isDefined (s))
00114 {
00115 char *cp = strchr (s, c);
00116
00117 if (cp != NULL)
00118 {
00119 cstring ret;
00120
00121
00122 *cp = '\0';
00123 ret = cstring_copy (s);
00124 *cp = c;
00125
00126
00127 return ret;
00128 }
00129 }
00130
00131 return cstring_undefined;
00132 }
00133
00134 void cstring_setChar (cstring s, int n, char c)
00135 {
00136 llassert (cstring_isDefined (s));
00137 llassert (n > 0 && n <= cstring_length (s));
00138
00139 s[n - 1] = c;
00140 }
00141
00142 char cstring_lastChar (cstring s)
00143 {
00144 int length;
00145
00146 llassert (cstring_isDefined (s));
00147
00148 length = cstring_length (s);
00149 llassert (length > 0);
00150
00151 return (s[length - 1]);
00152 }
00153
00154 cstring cstring_copy (cstring s)
00155 {
00156 if (cstring_isDefined (s))
00157 {
00158 return (mstring_copy (s));
00159 }
00160 else
00161 {
00162 return cstring_undefined;
00163 }
00164 }
00165
00166 cstring cstring_copyLength (char *s, int len)
00167 {
00168 char *res = mstring_create (len + 1);
00169
00170 strncpy (res, s, size_fromInt (len));
00171 res[len] = '\0';
00172 return res;
00173 }
00174
00175 bool cstring_containsChar (cstring c, char ch)
00176 {
00177 if (cstring_isDefined (c))
00178 {
00179 return (strchr (c, ch) != NULL);
00180 }
00181 else
00182 {
00183 return FALSE;
00184 }
00185 }
00186
00187
00188
00189
00190
00191 # if defined (WIN32) || defined (OS2)
00192 void cstring_replaceAll (cstring s, char old, char snew)
00193 {
00194
00195 llassert (old != snew);
00196
00197 if (cstring_isDefined (s))
00198 {
00199 char *sp = strchr (s, old);
00200
00201 while (sp != NULL)
00202 {
00203 *sp = snew;
00204 sp = strchr (sp, old);
00205 }
00206
00207 }
00208 }
00209 # endif
00210
00211 void cstring_replaceLit ( cstring s, char *old, char *snew)
00212 {
00213
00214 llassert (strlen (old) >= strlen (snew));
00215
00216 if (cstring_isDefined (s))
00217 {
00218 char *sp = strstr (s, old);
00219
00220 while (sp != NULL)
00221 {
00222 int lendiff = size_toInt (strlen (old) - strlen (snew));
00223 char *tsnew = snew;
00224
00225 while (*tsnew != '\0')
00226 {
00227 *sp++ = *tsnew++;
00228 }
00229
00230 if (lendiff > 0)
00231 {
00232 while (*(sp + lendiff) != '\0')
00233 {
00234 *sp = *(sp + lendiff);
00235 sp++;
00236 }
00237
00238 *sp = '\0';
00239 }
00240
00241 sp = strstr (s, old);
00242 }
00243 }
00244 }
00245
00246
00247
00248
00249
00250 void cstring_stripChars (cstring s, const char *clist)
00251 {
00252 if (cstring_isDefined (s))
00253 {
00254 int i;
00255 int size = cstring_length (s);
00256
00257 for (i = 0; i < size; i++)
00258 {
00259 char c = s[i];
00260
00261 if (strchr (clist, c) != NULL)
00262 {
00263
00264 int j;
00265
00266 size--;
00267
00268 for (j = i; j < size; j++)
00269 {
00270 s[j] = s[j+1];
00271 }
00272
00273 s[size] = '\0';
00274 i--;
00275 }
00276 }
00277 }
00278 }
00279
00280 bool cstring_contains ( cstring c, cstring sub)
00281 {
00282 if (cstring_isDefined (c))
00283 {
00284 llassert (cstring_isDefined (sub));
00285
00286 return (strstr (c, sub) != NULL);
00287 }
00288 else
00289 {
00290 return FALSE;
00291 }
00292 }
00293
00294 static char lookLike (char c)
00295 {
00296 if (c == 'I' || c == 'l')
00297 {
00298 return '1';
00299 }
00300 else if (c == 'O' || c == 'o')
00301 {
00302 return '0';
00303 }
00304 else if (c == 'Z')
00305 {
00306 return '2';
00307 }
00308 else if (c == 'S')
00309 {
00310 return '5';
00311 }
00312 else
00313 {
00314 return c;
00315 }
00316 }
00317
00318 cmpcode cstring_genericEqual (cstring s, cstring t,
00319 int nchars,
00320 bool caseinsensitive,
00321 bool lookalike)
00322 {
00323 if (s == t) return CGE_SAME;
00324 else if (cstring_isUndefined (s))
00325 {
00326 return cstring_isEmpty (t) ? CGE_SAME : CGE_DISTINCT;
00327 }
00328 else if (cstring_isUndefined (t))
00329 {
00330 return cstring_isEmpty (s) ? CGE_SAME : CGE_DISTINCT;
00331 }
00332 else
00333 {
00334 int i = 0;
00335 bool diffcase = FALSE;
00336 bool difflookalike = FALSE;
00337
00338 while (*s != '\0')
00339 {
00340 if (nchars > 0 && i >= nchars)
00341 {
00342 break;
00343 }
00344
00345 if (*t == *s)
00346 {
00347 ;
00348 }
00349 else if (caseinsensitive
00350 && (toupper ((int) *t) == toupper ((int) *s)))
00351 {
00352 diffcase = TRUE;
00353 }
00354 else if (lookalike && (lookLike (*t) == lookLike (*s)))
00355 {
00356 difflookalike = TRUE;
00357 }
00358 else
00359 {
00360 return CGE_DISTINCT;
00361 }
00362 i++;
00363 s++;
00364 t++;
00365 }
00366
00367 if (*s == '\0' && *t != '\0')
00368 {
00369 return CGE_DISTINCT;
00370 }
00371
00372 if (diffcase)
00373 {
00374 return CGE_CASE;
00375 }
00376 else if (difflookalike)
00377 {
00378 return CGE_LOOKALIKE;
00379 }
00380 else
00381 {
00382 return CGE_SAME;
00383 }
00384 }
00385 }
00386
00387
00388
00389 bool cstring_equalFree ( cstring c1, cstring c2)
00390 {
00391 bool res = cstring_equal (c1, c2);
00392 cstring_free (c1);
00393 cstring_free (c2);
00394 return res;
00395 }
00396
00397 bool cstring_equal (cstring c1, cstring c2)
00398 {
00399 if (c1 == c2) return TRUE;
00400 else if (cstring_isUndefined (c1)) return cstring_isEmpty (c2);
00401 else if (cstring_isUndefined (c2)) return cstring_isEmpty (c1);
00402 else return (strcmp (c1, c2) == 0);
00403 }
00404
00405 bool cstring_equalLen (cstring c1, cstring c2, int len)
00406 {
00407 if (c1 == c2) return TRUE;
00408 else if (cstring_isUndefined (c1)) return cstring_isEmpty (c2);
00409 else if (cstring_isUndefined (c2)) return cstring_isEmpty (c1);
00410 else return (strncmp (c1, c2, size_fromInt (len)) == 0);
00411 }
00412
00413 bool cstring_equalCaseInsensitive (cstring c1, cstring c2)
00414 {
00415 if (c1 == c2) return TRUE;
00416 else if (cstring_isUndefined (c1)) return cstring_isEmpty (c2);
00417 else if (cstring_isUndefined (c2)) return cstring_isEmpty (c1);
00418 else return (cstring_genericEqual (c1, c2, 0, TRUE, FALSE) != CGE_DISTINCT);
00419 }
00420
00421 bool cstring_equalLenCaseInsensitive (cstring c1, cstring c2, int len)
00422 {
00423 llassert (len >= 0);
00424
00425 if (c1 == c2) return TRUE;
00426 else if (cstring_isUndefined (c1)) return cstring_isEmpty (c2);
00427 else if (cstring_isUndefined (c2)) return cstring_isEmpty (c1);
00428 else return (cstring_genericEqual (c1, c2, len, TRUE, FALSE) != CGE_DISTINCT);
00429 }
00430
00431 bool cstring_equalPrefix (cstring c1, char *c2)
00432 {
00433 llassert (c2 != NULL);
00434
00435 if (cstring_isUndefined (c1))
00436 {
00437 return (strlen (c2) == 0);
00438 }
00439
00440 return (strncmp (c1, c2, strlen (c2)) == 0);
00441 }
00442
00443 bool cstring_equalCanonicalPrefix (cstring c1, char *c2)
00444 {
00445 llassert (c2 != NULL);
00446
00447 if (cstring_isUndefined (c1))
00448 {
00449 return (strlen (c2) == 0);
00450 }
00451
00452 # if defined (WIN32) || defined (OS2)
00453
00454
00455
00456
00457 if (strchr (c1, ':') == NULL
00458 && strchr (c2, ':') != NULL)
00459 {
00460 c2 = strchr (c2 + 1, ':');
00461 }
00462 else
00463 {
00464 if (strchr (c2, ':') == NULL
00465 && strchr (c1, ':') != NULL)
00466 {
00467 c1 = strchr (c1 + 1, ':');
00468 }
00469 }
00470
00471 {
00472 int len = size_toInt (strlen (c2));
00473 int i = 0;
00474 int slen = 0;
00475
00476 if (cstring_length (c1) < len)
00477 {
00478 return FALSE;
00479 }
00480
00481 for (i = 0; i < len; i++)
00482 {
00483 if (c1[slen] == c2[i]
00484 || (osd_isConnectChar (c1[slen]) && osd_isConnectChar (c2[i])))
00485 {
00486 ;
00487 }
00488 else
00489 {
00490
00491
00492
00493
00494
00495 if (c1[slen] == '\\'
00496 && (slen > 0
00497 && c1[slen - 1] == '\\'
00498 && c2[i - 1] == '\\'))
00499 {
00500 slen++;
00501 if (c1[slen] != c2[i])
00502 {
00503 return FALSE;
00504 }
00505 }
00506 else
00507 {
00508 return FALSE;
00509 }
00510 }
00511
00512 slen++;
00513 if (slen >= cstring_length (c1))
00514 {
00515 return FALSE;
00516 }
00517 }
00518 }
00519
00520 return TRUE;
00521 # else
00522 return (strncmp (c1, c2, strlen (c2)) == 0);
00523 # endif
00524 }
00525
00526 int cstring_xcompare (cstring *c1, cstring *c2)
00527 {
00528 return (cstring_compare (*c1, *c2));
00529 }
00530
00531 int cstring_compare (cstring c1, cstring c2)
00532 {
00533 int res;
00534
00535 if (c1 == c2)
00536 {
00537 res = 0;
00538 }
00539 else if (cstring_isUndefined (c1))
00540 {
00541 if (cstring_isEmpty (c2))
00542 {
00543 res = 0;
00544 }
00545 else
00546 {
00547 res = 1;
00548 }
00549 }
00550 else if (cstring_isUndefined (c2))
00551 {
00552 if (cstring_isEmpty (c1))
00553 {
00554 res = 0;
00555 }
00556 else
00557 {
00558 res = -1;
00559 }
00560 }
00561 else
00562 {
00563 res = strcmp (c1, c2);
00564 }
00565
00566 return (res);
00567 }
00568
00569 void cstring_markOwned ( cstring s)
00570 {
00571 sfreeEventually (s);
00572 }
00573
00574 void cstring_free ( cstring s)
00575 {
00576 if (cstring_isDefined (s))
00577 {
00578 sfree (s);
00579 }
00580 }
00581
00582 cstring cstring_fromChars ( const char *cp)
00583 {
00584 return (cstring) cp;
00585 }
00586
00587 char *cstring_toCharsSafe (cstring s)
00588 {
00589 static cstring emptystring = cstring_undefined;
00590
00591 if (cstring_isDefined (s))
00592 {
00593 return (char *) s;
00594 }
00595 else
00596 {
00597 if (cstring_isUndefined (emptystring))
00598 {
00599 emptystring = cstring_newEmpty ();
00600 }
00601
00602 return emptystring;
00603 }
00604 }
00605
00606 int cstring_length (cstring s)
00607 {
00608 if (cstring_isDefined (s))
00609 {
00610 return size_toInt (strlen (s));
00611 }
00612 return 0;
00613 }
00614
00615 cstring
00616 cstring_capitalize (cstring s)
00617 {
00618 if (!cstring_isEmpty (s))
00619 {
00620 cstring ret = cstring_copy (s);
00621
00622 cstring_setChar (ret, 1, (char) toupper ((int) cstring_firstChar (ret)));
00623 return ret;
00624 }
00625
00626 return cstring_undefined;
00627 }
00628
00629 cstring
00630 cstring_capitalizeFree (cstring s)
00631 {
00632 if (!cstring_isEmpty (s))
00633 {
00634 cstring_setChar (s, 1, (char) toupper ((int) cstring_firstChar (s)));
00635 return s;
00636 }
00637
00638 return s;
00639 }
00640
00641 cstring
00642 cstring_clip (cstring s, int len)
00643 {
00644 if (cstring_isUndefined (s) || cstring_length (s) <= len)
00645 {
00646 ;
00647 }
00648 else
00649 {
00650 llassert (s != NULL);
00651 *(s + len) = '\0';
00652 }
00653
00654 return s;
00655 }
00656
00657 cstring
00658 cstring_elide (cstring s, int len)
00659 {
00660 if (cstring_isUndefined (s) || cstring_length (s) <= len)
00661 {
00662 return cstring_copy (s);
00663 }
00664 else
00665 {
00666 cstring sc = cstring_create (len);
00667
00668 strncpy (sc, s, size_fromInt (len));
00669 *(sc + len - 1) = '\0';
00670 *(sc + len - 2) = '.';
00671 *(sc + len - 3) = '.';
00672 *(sc + len - 4) = '.';
00673 return sc;
00674 }
00675 }
00676
00677 cstring
00678 cstring_fill (cstring s, int n)
00679 {
00680 cstring t = cstring_create (n + 1);
00681 cstring ot = t;
00682 int len = cstring_length (s);
00683 int i;
00684
00685 if (len > n)
00686 {
00687 for (i = 0; i < n; i++)
00688 {
00689 *t++ = *s++;
00690 }
00691 *t = '\0';
00692 }
00693 else
00694 {
00695 for (i = 0; i < len; i++)
00696 {
00697 *t++ = *s++;
00698 }
00699 for (i = 0; i < n - len; i++)
00700 {
00701 *t++ = ' ';
00702 }
00703 *t = '\0';
00704 }
00705
00706 return ot;
00707 }
00708
00709 cstring
00710 cstring_downcase (cstring s)
00711 {
00712 if (cstring_isDefined (s))
00713 {
00714 cstring t = cstring_create (strlen (s) + 1);
00715 cstring ot = t;
00716 char c;
00717
00718 while ((c = *s) != '\0')
00719 {
00720 if (c >= 'A' && c <= 'Z')
00721 {
00722 c = c - 'A' + 'a';
00723 }
00724 *t++ = c;
00725 s++;
00726 }
00727 *t = '\0';
00728
00729 return ot;
00730 }
00731 else
00732 {
00733 return cstring_undefined;
00734 }
00735 }
00736
00737 cstring
00738 cstring_appendChar ( cstring s1, char c)
00739 {
00740 int l = cstring_length (s1);
00741 char *s;
00742
00743 s = (char *) dmalloc (sizeof (*s) * (l + 2));
00744
00745 if (cstring_isDefined (s1))
00746 {
00747 strcpy (s, s1);
00748 *(s + l) = c;
00749 *(s + l + 1) = '\0';
00750 sfree (s1);
00751 }
00752 else
00753 {
00754 *(s) = c;
00755 *(s + 1) = '\0';
00756 }
00757
00758 return s;
00759 }
00760
00761 cstring
00762 cstring_concatFree (cstring s, cstring t)
00763 {
00764 cstring res = cstring_concat (s, t);
00765 cstring_free (s);
00766 cstring_free (t);
00767 return res;
00768 }
00769
00770 cstring
00771 cstring_concatFree1 (cstring s, cstring t)
00772 {
00773 cstring res = cstring_concat (s, t);
00774 cstring_free (s);
00775 return res;
00776 }
00777
00778 # ifndef NOLCL
00779 cstring
00780 cstring_concatChars (cstring s, char *t)
00781 {
00782 cstring res = cstring_concat (s, cstring_fromChars (t));
00783 cstring_free (s);
00784 return res;
00785 }
00786 # endif
00787
00788 cstring
00789 cstring_concatLength (cstring s1, char *s2, int len)
00790 {
00791 cstring tmp = cstring_copyLength (s2, len);
00792 cstring res = cstring_concat (s1, tmp);
00793 cstring_free (tmp);
00794 cstring_free (s1);
00795
00796 return res;
00797 }
00798
00799 cstring
00800 cstring_concat (cstring s, cstring t)
00801 {
00802 char *ret = mstring_create (cstring_length (s) + cstring_length (t));
00803
00804 if (cstring_isDefined (s))
00805 {
00806 strcpy (ret, s);
00807 }
00808 if (cstring_isDefined (t))
00809 {
00810 strcat (ret, t);
00811 }
00812
00813 return ret;
00814 }
00815
00816 cstring
00817 cstring_prependCharO (char c, cstring s1)
00818 {
00819 cstring res = cstring_prependChar (c, s1);
00820
00821 cstring_free (s1);
00822 return (res);
00823 }
00824
00825 cstring
00826 cstring_prependChar (char c, cstring s1)
00827 {
00828 int l = cstring_length (s1);
00829 char *s = (char *) dmalloc (sizeof (*s) * (l + 2));
00830
00831 *(s) = c;
00832
00833 if (cstring_isDefined (s1))
00834 {
00835
00836 strcpy (s + 1, s1);
00837
00838 }
00839
00840 *(s + l + 1) = '\0';
00841 return s;
00842 }
00843
00844 # ifndef NOLCL
00845 bool
00846 cstring_hasNonAlphaNumBar (cstring s)
00847 {
00848 int c;
00849
00850 if (cstring_isUndefined (s)) return FALSE;
00851
00852 while ((c = (int) *s) != (int) '\0')
00853 {
00854 if ((isalnum (c) == 0) && (c != (int) '_')
00855 && (c != (int) '.') && (c != (int) CONNECTCHAR))
00856 {
00857 return TRUE;
00858 }
00859
00860 s++;
00861 }
00862 return FALSE;
00863 }
00864 # endif
00865
00866 cstring
00867 cstring_create (int n)
00868 {
00869 char *s = dmalloc (sizeof (*s) * (n + 1));
00870
00871 *s = '\0';
00872 return s;
00873 }
00874
00875 # ifndef NOLCL
00876 lsymbol cstring_toSymbol (cstring s)
00877 {
00878 lsymbol res = lsymbol_fromChars (cstring_toCharsSafe (s));
00879
00880 cstring_free (s);
00881 return res;
00882 }
00883 # endif
00884
00885 cstring cstring_bsearch (cstring key, char **table, int nentries)
00886 {
00887 if (cstring_isDefined (key))
00888 {
00889 int low = 0;
00890 int high = nentries;
00891 int mid = (high + low + 1) / 2;
00892 int last = -1;
00893 cstring res = cstring_undefined;
00894
00895 while (low <= high && mid < nentries)
00896 {
00897 int cmp;
00898
00899 llassert (mid != last);
00900 llassert (mid >= 0 && mid < nentries);
00901
00902 cmp = cstring_compare (key, table[mid]);
00903
00904 if (cmp == 0)
00905 {
00906 res = table[mid];
00907 break;
00908 }
00909 else if (cmp < 0)
00910 {
00911 high = mid - 1;
00912 }
00913 else
00914 {
00915 low = mid + 1;
00916 }
00917
00918 last = mid;
00919 mid = (high + low + 1) / 2;
00920 }
00921
00922 if (mid != 0 && mid < nentries - 1)
00923 {
00924 llassert (cstring_compare (key, table[mid - 1]) > 0);
00925 llassert (cstring_compare (key, table[mid + 1]) < 0);
00926 }
00927
00928 return res;
00929 }
00930
00931 return cstring_undefined;
00932 }
00933
00934 extern cstring cstring_advanceWhiteSpace (cstring s)
00935 {
00936 if (cstring_isDefined (s)) {
00937 char *t = s;
00938
00939 while (*t != '\0' && isspace ((int) *t)) {
00940 t++;
00941 }
00942
00943 return t;
00944 }
00945
00946 return cstring_undefined;
00947 }
00948
00949
00950