Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members  

cstring.c

Go to the documentation of this file.
00001 /*
00002 ** LCLint - annotation-assisted static program checker
00003 ** Copyright (C) 1994-2000 University of Virginia,
00004 **         Massachusetts Institute of Technology
00005 **
00006 ** This program is free software; you can redistribute it and/or modify it
00007 ** under the terms of the GNU General Public License as published by the
00008 ** Free Software Foundation; either version 2 of the License, or (at your
00009 ** option) any later version.
00010 ** 
00011 ** This program is distributed in the hope that it will be useful, but
00012 ** WITHOUT ANY WARRANTY; without even the implied warranty of
00013 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 ** General Public License for more details.
00015 ** 
00016 ** The GNU General Public License is available from http://www.gnu.org/ or
00017 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00018 ** MA 02111-1307, USA.
00019 **
00020 ** For information on lclint: lclint-request@cs.virginia.edu
00021 ** To report a bug: lclint-bug@cs.virginia.edu
00022 ** For more information: http://lclint.cs.virginia.edu
00023 */
00024 /*
00025 ** cstring.c
00026 */
00027 
00028 /*
00029  * Herbert 06/12/2000
00030  * - use drive spec specials with OS2 like with WIN32
00031  * - cstring_replaceAll () needed in cpplib.c
00032  */
00033 
00034 # include "lclintMacros.nf"
00035 # include "basic.h"
00036 # include "osd.h"
00037 # include "portab.h"
00038 
00039 static /*@only@*/ /*@notnull@*/ 
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   /*@-mods@*/  /* The modifications cancel out. */
00080   *(s + n) = '\0';
00081   t = cstring_copy (s);
00082   *(s + n) = c;
00083   /*@=mods@*/
00084 
00085   return t;
00086 }
00087 
00088 /* effects If s = [0-9]*, returns s as an int.
00089 **         else returns -1.
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           /*@-mods@*/
00122           *cp = '\0';
00123           ret = cstring_copy (s);
00124           *cp = c;
00125           /*@=mods@*/ /* modification is undone */
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 /*@only@*/ 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 /*@only@*/ 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 ** Replaces all occurances of old in s with new.
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 (/*@unique@*/ 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 ** removes all chars in clist from s
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               /* strip this char */
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 (/*@unique@*/ 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               ; /* no difference */
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 (/*@only@*/ cstring c1, /*@only@*/ 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   ** If one has a drive specification, but the other doesn't, skip it.
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             ** We allow \\ to match \ because MS-DOS screws up the directory
00492             ** names.
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 (/*@owned@*/ cstring s)
00570 {
00571   sfreeEventually (s);
00572 }
00573 
00574 void cstring_free (/*@only@*/ cstring s)
00575 {
00576   if (cstring_isDefined (s)) 
00577     {
00578       sfree (s);
00579     }
00580 }
00581 
00582 cstring cstring_fromChars (/*@exposed@*/ const char *cp)
00583 {
00584   return (cstring) cp;
00585 }
00586 
00587 /*@exposed@*/ char *cstring_toCharsSafe (cstring s)
00588 {
00589   static /*@only@*/ 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 /*@only@*/ 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 /*@only@*/ 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 /*@notnull@*/ cstring 
00738 cstring_appendChar (/*@only@*/ 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 /*@only@*/ 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 /*@only@*/ 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 /*@only@*/ 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 /*@only@*/ 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 /*@only@*/ 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 /*@notnull@*/ /*@only@*/ cstring 
00817 cstring_prependCharO (char c, /*@only@*/ cstring s1)
00818 {
00819   cstring res = cstring_prependChar (c, s1);
00820 
00821   cstring_free (s1);
00822   return (res);
00823 }
00824 
00825 /*@notnull@*/ /*@only@*/ cstring 
00826 cstring_prependChar (char c, /*@temp@*/ 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       /*@-mayaliasunique@*/ 
00836       strcpy (s + 1, s1);
00837       /*@=mayaliasunique@*/ 
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 /*@only@*/ /*@notnull@*/ 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) /* key is before table[mid] */
00910             {
00911               high = mid - 1;
00912             }
00913           else /* key of after table[mid] */
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 /*@observer@*/ 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 

Generated at Fri Nov 3 18:57:40 2000 for LCLint by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000