X-Git-Url: http://andersk.mit.edu/gitweb/splint.git/blobdiff_plain/86d93ed383c14be2a4548bd8ab98e4c1a79cb1f0..35e063d82040a7c7a6da8634cf377e19ee0662d1:/src/cstring.c diff --git a/src/cstring.c b/src/cstring.c index d9d614b..d867531 100644 --- a/src/cstring.c +++ b/src/cstring.c @@ -17,8 +17,8 @@ ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, ** MA 02111-1307, USA. ** -** For information on splint: splint@cs.virginia.edu -** To report a bug: splint-bug@cs.virginia.edu +** For information on splint: info@splint.org +** To report a bug: splint-bug@splint.org ** For more information: http://www.splint.org */ /* @@ -50,9 +50,9 @@ char cstring_firstChar (cstring s) return (s[0]); } -char cstring_getChar (cstring s, int n) +char cstring_getChar (cstring s, size_t n) { - int length = cstring_length (s); + size_t length = cstring_length (s); llassert (cstring_isDefined (s)); llassert (n >= 1 && n <= length); @@ -60,7 +60,7 @@ char cstring_getChar (cstring s, int n) return (s[n - 1]); } -cstring cstring_suffix (cstring s, int n) +cstring cstring_suffix (cstring s, size_t n) { llassert (cstring_isDefined (s)); llassert (n <= cstring_length (s)); @@ -68,7 +68,9 @@ cstring cstring_suffix (cstring s, int n) return (s + n); } -cstring cstring_prefix (cstring s, int n) /*@requires maxRead(s) >= n /\ maxSet(s) >= n @*/ /*@ensures maxRead(result) == n /\ maxSet(result) == n @*/ +cstring cstring_prefix (cstring s, size_t n) + /*@requires maxRead(s) >= n /\ maxSet(s) >= n @*/ + /*@ensures maxRead(result) == n /\ maxSet(result) == n @*/ { cstring t; char c; @@ -137,7 +139,7 @@ cstring cstring_beforeChar (cstring s, char c) return cstring_undefined; } -void cstring_setChar (cstring s, int n, char c) /*@requires maxRead(s) >= (n - 1) /\ maxSet(s) >= (n - 1) @*/ +void cstring_setChar (cstring s, size_t n, char c) /*@requires maxRead(s) >= (n - 1) /\ maxSet(s) >= (n - 1) @*/ { llassert (cstring_isDefined (s)); llassert (n > 0 && n <= cstring_length (s)); @@ -147,7 +149,7 @@ void cstring_setChar (cstring s, int n, char c) /*@requires maxRead(s) >= (n - 1 char cstring_lastChar (cstring s) { - int length; + size_t length; llassert (cstring_isDefined (s)); @@ -169,11 +171,11 @@ char cstring_lastChar (cstring s) } } -/*@only@*/ cstring cstring_copyLength (char *s, int len) /*@requires maxSet(s) >= (len - 1) @*/ +/*@only@*/ cstring cstring_copyLength (char *s, size_t len) /*@requires maxSet(s) >= (len - 1) @*/ { char *res = mstring_create (len + 1); - strncpy (res, s, size_fromInt (len)); + strncpy (res, s, len); res[len] = '\0'; return res; } @@ -212,11 +214,11 @@ void cstring_replaceAll (cstring s, char old, char snew) } } -void cstring_replaceLit (/*@unique@*/ cstring s, char *old, char *snew) /*@requires maxRead(snew) >= 0 /\ maxRead(old) >= 0 /\ maxRead(old) >= maxRead(snew) @*/ +void cstring_replaceLit (/*@unique@*/ cstring s, char *old, char *snew) + /*@requires maxRead(snew) >= 0 /\ maxRead(old) >= 0 /\ maxRead(old) >= maxRead(snew) @*/ { - llassert (strlen (old) >= strlen (snew)); - + if (cstring_isDefined (s)) { char *sp = strstr (s, old); @@ -225,12 +227,15 @@ void cstring_replaceLit (/*@unique@*/ cstring s, char *old, char *snew) /*@requi { int lendiff = size_toInt (strlen (old) - strlen (snew)); char *tsnew = snew; - + + llassert (lendiff >= 0); + while (*tsnew != '\0') { + llassert (*sp != '\0'); *sp++ = *tsnew++; } - + if (lendiff > 0) { while (*(sp + lendiff) != '\0') @@ -256,11 +261,12 @@ void cstring_stripChars (cstring s, const char *clist) if (cstring_isDefined (s)) { int i; - int size = cstring_length (s); + size_t size = cstring_length (s); - for (i = 0; i < size; i++) + for (i = 0; i < size_toInt (size); i++) { -/*drl bee: is*/ char c = s[i]; + /*drl bee: is*/ + char c = s[i]; if (strchr (clist, c) != NULL) { @@ -268,13 +274,13 @@ void cstring_stripChars (cstring s, const char *clist) int j; size--; - - for (j = i; j < size; j++) + + for (j = i; j < size_toInt (size); j++) { - /*drl bee: is*/ /*drl bee: is*/ s[j] = s[j+1]; + /*drl bee: is*/ /*drl bee: is*/ s[j] = s[j+1]; } - - /*drl bee: is*/ s[size] = '\0'; + + /*drl bee: is*/ s[size] = '\0'; i--; } } @@ -320,9 +326,10 @@ static char lookLike (char c) /*@*/ } cmpcode cstring_genericEqual (cstring s, cstring t, - int nchars, + size_t nchars, bool caseinsensitive, - bool lookalike) /*@requires maxRead(s) >= nchars /\ maxRead(t) >= nchars @*/ + bool lookalike) + /*@requires maxRead(s) >= nchars /\ maxRead(t) >= nchars @*/ { if (s == t) return CGE_SAME; else if (cstring_isUndefined (s)) @@ -341,7 +348,7 @@ cmpcode cstring_genericEqual (cstring s, cstring t, while (*s != '\0') { - if (nchars > 0 && i >= nchars) + if (nchars > 0 && i >= size_toInt (nchars)) { break; } @@ -408,12 +415,12 @@ bool cstring_equal (cstring c1, cstring c2) else return (strcmp (c1, c2) == 0); } -bool cstring_equalLen (cstring c1, cstring c2, int len) +bool cstring_equalLen (cstring c1, cstring c2, size_t len) { if (c1 == c2) return TRUE; else if (cstring_isUndefined (c1)) return cstring_isEmpty (c2); else if (cstring_isUndefined (c2)) return cstring_isEmpty (c1); - else return (strncmp (c1, c2, size_fromInt (len)) == 0); + else return (strncmp (c1, c2, len) == 0); } bool cstring_equalCaseInsensitive (cstring c1, cstring c2) @@ -424,10 +431,8 @@ bool cstring_equalCaseInsensitive (cstring c1, cstring c2) else return (cstring_genericEqual (c1, c2, 0, TRUE, FALSE) != CGE_DISTINCT); } -bool cstring_equalLenCaseInsensitive (cstring c1, cstring c2, int len) +bool cstring_equalLenCaseInsensitive (cstring c1, cstring c2, size_t len) { - llassert (len >= 0); - if (c1 == c2) return TRUE; else if (cstring_isUndefined (c1)) return cstring_isEmpty (c2); else if (cstring_isUndefined (c2)) return cstring_isEmpty (c1); @@ -510,6 +515,9 @@ void cstring_free (/*@only@*/ cstring s) { if (cstring_isDefined (s)) { + /*drl 2/3/2002*/ + s[0] = '\0'; + sfree (s); } } @@ -538,12 +546,13 @@ cstring cstring_fromChars (/*@exposed@*/ const char *cp) } } -int cstring_length (cstring s) +size_t cstring_length (cstring s) { if (cstring_isDefined (s)) { - return size_toInt (strlen (s)); + return strlen (s); } + return 0; } @@ -574,7 +583,7 @@ cstring_capitalizeFree (cstring s) /*@requires maxSet(s) >= 0 /\ maxRead(s) >= 0 } cstring -cstring_clip (cstring s, int len) +cstring_clip (cstring s, size_t len) { if (cstring_isUndefined (s) || cstring_length (s) <= len) { @@ -583,14 +592,15 @@ cstring_clip (cstring s, int len) else { llassert (s != NULL); - /*drl bee: mrms*/ *(s + len) = '\0'; + /*drl bee: mrms*/ + *(s + len) = '\0'; } - + return s; } /*@only@*/ cstring -cstring_elide (cstring s, int len) +cstring_elide (cstring s, size_t len) { if (cstring_isUndefined (s) || cstring_length (s) <= len) { @@ -599,23 +609,25 @@ cstring_elide (cstring s, int len) else { cstring sc = cstring_create (len); - - strncpy (sc, s, size_fromInt (len)); - /*drl bee: mrms*/ *(sc + len - 1) = '\0'; + + strncpy (sc, s, len); + /*drl bee: mrms*/ + *(sc + len - 1) = '\0'; *(sc + len - 2) = '.'; *(sc + len - 3) = '.'; *(sc + len - 4) = '.'; + return sc; } } /*@only@*/ cstring -cstring_fill (cstring s, int n) /*@requires n >= 0 @*/ +cstring_fill (cstring s, size_t n) /*@requires n >= 0 @*/ { cstring t = cstring_create (n + 1); cstring ot = t; - int len = cstring_length (s); - int i; + size_t len = cstring_length (s); + size_t i; if (len > n) { @@ -677,7 +689,7 @@ cstring_downcase (cstring s) /*@notnull@*/ cstring cstring_appendChar (/*@only@*/ cstring s1, char c) { - int l = cstring_length (s1); + size_t l = cstring_length (s1); char *s; s = (char *) dmalloc (sizeof (*s) * (l + 2)); @@ -692,7 +704,7 @@ cstring_appendChar (/*@only@*/ cstring s1, char c) else { *(s) = c; - /*drl bee: dm*/ *(s + 1) = '\0'; + /*drl bee: dm*/ *(s + 1) = '\0'; } return s; @@ -715,7 +727,6 @@ cstring_concatFree1 (cstring s, cstring t) return res; } -# ifndef NOLCL /*@only@*/ cstring cstring_concatChars (cstring s, char *t) { @@ -723,10 +734,9 @@ cstring_concatChars (cstring s, char *t) cstring_free (s); return res; } -# endif /*@only@*/ cstring -cstring_concatLength (cstring s1, char *s2, int len) /*@requires maxSet(s2) >= (len - 1) @*/ +cstring_concatLength (cstring s1, char *s2, size_t len) /*@requires maxSet(s2) >= (len - 1) @*/ { cstring tmp = cstring_copyLength (s2, len); cstring res = cstring_concat (s1, tmp); @@ -765,7 +775,7 @@ cstring_prependCharO (char c, /*@only@*/ cstring s1) /*@notnull@*/ /*@only@*/ cstring cstring_prependChar (char c, /*@temp@*/ cstring s1) { - int l = cstring_length (s1); + size_t l = cstring_length (s1); char *s = (char *) dmalloc (sizeof (*s) * (l + 2)); /*drl bee: dm*/ *(s) = c; @@ -781,7 +791,6 @@ cstring_prependChar (char c, /*@temp@*/ cstring s1) return s; } -# ifndef NOLCL bool cstring_hasNonAlphaNumBar (cstring s) { @@ -801,19 +810,18 @@ cstring_hasNonAlphaNumBar (cstring s) } return FALSE; } -# endif /*@only@*/ /*@notnull@*/ cstring -cstring_create (int n) +cstring_create (size_t n) { char *s = dmalloc (sizeof (*s) * (n + 1)); - - /*drl bee: dm*/ *s = '\0'; + + /*drl bee: dm*/ *s = '\0'; return s; } /*@only@*/ /*@notnull@*/ cstring -cstring_copySegment (cstring s, int findex, int tindex) +cstring_copySegment (cstring s, size_t findex, size_t tindex) { cstring res = cstring_create (tindex - findex + 1); @@ -824,7 +832,6 @@ cstring_copySegment (cstring s, int findex, int tindex) return res; } -# ifndef NOLCL lsymbol cstring_toSymbol (cstring s) { lsymbol res = lsymbol_fromString (s); @@ -832,7 +839,6 @@ lsymbol cstring_toSymbol (cstring s) cstring_free (s); return res; } -# endif cstring cstring_bsearch (cstring key, char **table, int nentries) { @@ -897,6 +903,274 @@ extern /*@observer@*/ cstring cstring_advanceWhiteSpace (cstring s) return cstring_undefined; } - + +/*@i3534 @*/ +/*@ignore@*/ /* !!! DRL don't ignore large segments like this without a good reason! */ + +/* changes strings like "sdf" "sdfsd" into "sdfsdfsd"*/ +/* This function understands that "sdf\" \"sdfsdf" is okay*/ +static mstring doMergeString (cstring s) +{ + char *ptr; + mstring ret; + char * retPtr; + bool escape; + + llassert(cstring_isDefined (s)); + + ret = mstring_create (cstring_length(s) ); + + ptr = s; + + retPtr = ret; + /* + llassert(*ptr == '\"'); + + *retPtr = *ptr; + + retPtr++; + ptr++; + */ + + while (*ptr != '\0') + { + escape = FALSE; + + if (*ptr == '\\') + { + *retPtr = *ptr; + + if (!escape) + escape = TRUE; + else + /* case of escaped \ ('\\') */ + escape = FALSE; + } + else if ( (*ptr == '\"') && (!escape) ) + { + while ( (ptr[1] != '\"') && (ptr[1] != '\0') ) + { + ptr++; + } + if (ptr[1] == '\0') + { + llassert(*ptr == '\"'); + *retPtr = '\"'; + retPtr++; + *retPtr = '\0'; + BADEXIT; + return ret; + } + else + { + ptr++; + } + } + else + { + *retPtr = *ptr; + } + + retPtr++; + ptr++; + + }/* end while */ + retPtr = '\0'; + return ret; +} + +static mstring doExpandEscapes (cstring s, /*@out@*/ size_t *len) +{ + char *ptr; + mstring ret; + char * retPtr; + + llassert(cstring_isDefined (s)); + + ret = mstring_create (cstring_length(s)); + + ptr = s; + + retPtr = ret; + while (*ptr != '\0') + { + if (*ptr != '\\') + { + *retPtr = *ptr; + retPtr++; + ptr++; + continue; + } + + if (*ptr == '\\') + { + ptr++; + if (*ptr == '\0') + { + /*not a legal escape sequence but try to handle it in a sesible way*/ + *retPtr = '\\'; + retPtr++; + } + + /* Handle Octal escapes */ + else if (*ptr >= '0' && *ptr <= '9' ) + { + int total; + total = (int)(*ptr - '0'); + ptr++; + /*octal can only be 3 characters long */ + if (*ptr != '\0' && (*ptr >= '0' && *ptr <= '9' ) ) + { + total *= 8; + ptr++; + if (*ptr != '\0' && (*ptr >= '0' && *ptr <= '9' ) ) + { + total *= 8; + total += (int) (*ptr - '0'); + ptr++; + } + } + + *retPtr = (char) total; + retPtr++; + } + + else if (*ptr == 'x') + { + int total; + total = 0; + ptr++; + if (!(*ptr != '\0' && + ( (*ptr >= '0' && *ptr <= '9' ) || + (toupper(*ptr) >= (int)('A') && toupper(*ptr) <= (int)('F') ) ) + )) + { + total = (int)'x'; + } + else + { + while (*ptr != '\0' && + ( (*ptr >= '0' && *ptr <= '9' ) || + (toupper(*ptr) >= ((int)('A')) && toupper(*ptr) <= ((int)'F') ) ) + ) + { + total *= 16; + if (*ptr >= '0' && *ptr <= '9' ) + total += (int)(*ptr - '0'); + else + total += ( (toupper(*ptr) - 'A') + 10); + ptr++; + } + } + *retPtr = (char) total; + retPtr++; + } + else + { + switch ( *ptr ) + { + case 'a': + *retPtr = '\a'; + retPtr++; + /*@switchbreak@*/ break; + + case 'b': + *retPtr = '\b'; + retPtr++; + /*@switchbreak@*/ break; + + case 'f': + *retPtr = '\f'; + retPtr++; + /*@switchbreak@*/ break; + + case 'n': + *retPtr = '\n'; + retPtr++; + /*@switchbreak@*/ break; + + case 'r': + *retPtr = '\r'; + retPtr++; + /*@switchbreak@*/ break; + + case 't': + *retPtr = '\t'; + retPtr++; + /*@switchbreak@*/ break; + /* ' " ? \ */ + /* we assume invalid sequences are handled somewhere else + so we handle an invalid sequence of the form \char by replacing + it with char (this is what gcc does) the C standard says a diagnostic is + required..*/ + default: + *retPtr = *ptr; + retPtr++; + } + ptr++; + } + + }/*end outer if*/ + + }/*end while */ + + /* add the null character */ + *retPtr = '\0'; + + *len = retPtr - ret; + return ret; +} + + +/*this function is like sctring_expandEscapses */ +mstring cstring_expandEscapes (cstring s) +{ + size_t len; + + mstring ret; + ret = doExpandEscapes (s, &len); + return ret; +} + +size_t cstring_lengthExpandEscapes (cstring s) +{ + size_t len; + mstring tmpStr, tmpStr2; + + tmpStr = doMergeString (s); + tmpStr2 = doExpandEscapes (tmpStr, &len); + + cstring_free(tmpStr); + cstring_free(tmpStr2); + + return len; +} + +cstring cstring_replaceChar(/*@returned@*/ cstring c, char oldChar, char newChar) +{ + char *ptr; + llassert(oldChar != '\0'); + if (cstring_isUndefined(c) ) + { + llcontbug(cstring_makeLiteral("cstring_replaceChar called with undefined string")); + return c; + } + + ptr = c; + while (*ptr != '\0') + { + if (*ptr == oldChar) + *ptr = newChar; + ptr++; + } + + return c; +} +/*@end@*/ + + + + +