1/* tmbstr.c -- Tidy string utility functions 2 3 (c) 1998-2006 (W3C) MIT, ERCIM, Keio University 4 See tidy.h for the copyright notice. 5 6 CVS Info : 7 8 $Author$ 9 $Date$ 10 $Revision$ 11 12*/ 13 14#include "forward.h" 15#include "tmbstr.h" 16#include "lexer.h" 17 18/* like strdup but using MemAlloc */ 19tmbstr TY_(tmbstrdup)( ctmbstr str ) 20{ 21 tmbstr s = NULL; 22 if ( str ) 23 { 24 uint len = TY_(tmbstrlen)( str ); 25 tmbstr cp = s = (tmbstr) MemAlloc( 1+len ); 26 while ( 0 != (*cp++ = *str++) ) 27 /**/; 28 } 29 return s; 30} 31 32/* like strndup but using MemAlloc */ 33tmbstr TY_(tmbstrndup)( ctmbstr str, uint len ) 34{ 35 tmbstr s = NULL; 36 if ( str && len > 0 ) 37 { 38 tmbstr cp = s = (tmbstr) MemAlloc( 1+len ); 39 while ( len-- > 0 && (*cp++ = *str++) ) 40 /**/; 41 *cp = 0; 42 } 43 return s; 44} 45 46/* exactly same as strncpy */ 47uint TY_(tmbstrncpy)( tmbstr s1, ctmbstr s2, uint size ) 48{ 49 if ( s1 != NULL && s2 != NULL ) 50 { 51 tmbstr cp = s1; 52 while ( *s2 && --size ) /* Predecrement: reserve byte */ 53 *cp++ = *s2++; /* for NULL terminator. */ 54 *cp = 0; 55 } 56 return size; 57} 58 59/* Allows expressions like: cp += tmbstrcpy( cp, "joebob" ); 60*/ 61uint TY_(tmbstrcpy)( tmbstr s1, ctmbstr s2 ) 62{ 63 uint ncpy = 0; 64 while (0 != (*s1++ = *s2++) ) 65 ++ncpy; 66 return ncpy; 67} 68 69/* Allows expressions like: cp += tmbstrcat( cp, "joebob" ); 70*/ 71uint TY_(tmbstrcat)( tmbstr s1, ctmbstr s2 ) 72{ 73 uint ncpy = 0; 74 while ( *s1 ) 75 ++s1; 76 77 while (0 != (*s1++ = *s2++) ) 78 ++ncpy; 79 return ncpy; 80} 81 82/* exactly same as strcmp */ 83int TY_(tmbstrcmp)( ctmbstr s1, ctmbstr s2 ) 84{ 85 int c; 86 while ((c = *s1) == *s2) 87 { 88 if (c == '\0') 89 return 0; 90 91 ++s1; 92 ++s2; 93 } 94 95 return (*s1 > *s2 ? 1 : -1); 96} 97 98/* returns byte count, not char count */ 99uint TY_(tmbstrlen)( ctmbstr str ) 100{ 101 uint len = 0; 102 if ( str ) 103 { 104 while ( *str++ ) 105 ++len; 106 } 107 return len; 108} 109 110/* 111 MS C 4.2 doesn't include strcasecmp. 112 Note that tolower and toupper won't 113 work on chars > 127. 114 115 Neither does ToLower()! 116*/ 117int TY_(tmbstrcasecmp)( ctmbstr s1, ctmbstr s2 ) 118{ 119 uint c; 120 121 while (c = (uint)(*s1), TY_(ToLower)(c) == TY_(ToLower)((uint)(*s2))) 122 { 123 if (c == '\0') 124 return 0; 125 126 ++s1; 127 ++s2; 128 } 129 130 return (*s1 > *s2 ? 1 : -1); 131} 132 133int TY_(tmbstrncmp)( ctmbstr s1, ctmbstr s2, uint n ) 134{ 135 uint c; 136 137 while ((c = (byte)*s1) == (byte)*s2) 138 { 139 if (c == '\0') 140 return 0; 141 142 if (n == 0) 143 return 0; 144 145 ++s1; 146 ++s2; 147 --n; 148 } 149 150 if (n == 0) 151 return 0; 152 153 return (*s1 > *s2 ? 1 : -1); 154} 155 156int TY_(tmbstrncasecmp)( ctmbstr s1, ctmbstr s2, uint n ) 157{ 158 uint c; 159 160 while (c = (uint)(*s1), TY_(ToLower)(c) == TY_(ToLower)((uint)(*s2))) 161 { 162 if (c == '\0') 163 return 0; 164 165 if (n == 0) 166 return 0; 167 168 ++s1; 169 ++s2; 170 --n; 171 } 172 173 if (n == 0) 174 return 0; 175 176 return (*s1 > *s2 ? 1 : -1); 177} 178 179#if 0 180/* return offset of cc from beginning of s1, 181** -1 if not found. 182*/ 183int TY_(tmbstrnchr)( ctmbstr s1, uint maxlen, tmbchar cc ) 184{ 185 int i; 186 ctmbstr cp = s1; 187 188 for ( i = 0; (uint)i < maxlen; ++i, ++cp ) 189 { 190 if ( *cp == cc ) 191 return i; 192 } 193 194 return -1; 195} 196#endif 197 198ctmbstr TY_(tmbsubstrn)( ctmbstr s1, uint len1, ctmbstr s2 ) 199{ 200 uint len2 = TY_(tmbstrlen)(s2); 201 int ix, diff = len1 - len2; 202 203 for ( ix = 0; ix <= diff; ++ix ) 204 { 205 if ( TY_(tmbstrncmp)(s1+ix, s2, len2) == 0 ) 206 return (ctmbstr) s1+ix; 207 } 208 return NULL; 209} 210 211#if 0 212ctmbstr TY_(tmbsubstrncase)( ctmbstr s1, uint len1, ctmbstr s2 ) 213{ 214 uint len2 = TY_(tmbstrlen)(s2); 215 int ix, diff = len1 - len2; 216 217 for ( ix = 0; ix <= diff; ++ix ) 218 { 219 if ( TY_(tmbstrncasecmp)(s1+ix, s2, len2) == 0 ) 220 return (ctmbstr) s1+ix; 221 } 222 return NULL; 223} 224#endif 225 226ctmbstr TY_(tmbsubstr)( ctmbstr s1, ctmbstr s2 ) 227{ 228 uint len1 = TY_(tmbstrlen)(s1), len2 = TY_(tmbstrlen)(s2); 229 int ix, diff = len1 - len2; 230 231 for ( ix = 0; ix <= diff; ++ix ) 232 { 233 if ( TY_(tmbstrncasecmp)(s1+ix, s2, len2) == 0 ) 234 return (ctmbstr) s1+ix; 235 } 236 return NULL; 237} 238 239/* Transform ASCII chars in string to lower case */ 240tmbstr TY_(tmbstrtolower)( tmbstr s ) 241{ 242 tmbstr cp; 243 for ( cp=s; *cp; ++cp ) 244 *cp = (tmbchar) TY_(ToLower)( *cp ); 245 return s; 246} 247 248/* Transform ASCII chars in string to upper case */ 249tmbstr TY_(tmbstrtoupper)(tmbstr s) 250{ 251 tmbstr cp; 252 253 for (cp = s; *cp; ++cp) 254 *cp = (tmbchar)TY_(ToUpper)(*cp); 255 256 return s; 257} 258 259#if 0 260Bool TY_(tmbsamefile)( ctmbstr filename1, ctmbstr filename2 ) 261{ 262#if FILENAMES_CASE_SENSITIVE 263 return ( TY_(tmbstrcmp)( filename1, filename2 ) == 0 ); 264#else 265 return ( TY_(tmbstrcasecmp)( filename1, filename2 ) == 0 ); 266#endif 267} 268#endif 269 270int TY_(tmbvsnprintf)(tmbstr buffer, size_t count, ctmbstr format, va_list args) 271{ 272 int retval; 273#if HAS_VSNPRINTF 274 retval = vsnprintf(buffer, count - 1, format, args); 275 /* todo: conditionally null-terminate the string? */ 276 buffer[count - 1] = 0; 277#else 278 retval = vsprintf(buffer, format, args); 279#endif /* HAS_VSNPRINTF */ 280 return retval; 281} 282 283int TY_(tmbsnprintf)(tmbstr buffer, size_t count, ctmbstr format, ...) 284{ 285 int retval; 286 va_list args; 287 va_start(args, format); 288#if HAS_VSNPRINTF 289 retval = vsnprintf(buffer, count - 1, format, args); 290 /* todo: conditionally null-terminate the string? */ 291 buffer[count - 1] = 0; 292#else 293 retval = vsprintf(buffer, format, args); 294#endif /* HAS_VSNPRINTF */ 295 va_end(args); 296 return retval; 297} 298 299/* 300 * local variables: 301 * mode: c 302 * indent-tabs-mode: nil 303 * c-basic-offset: 4 304 * eval: (c-set-offset 'substatement-open 0) 305 * end: 306 */ 307