1 /* $Header: /src/pub/tcsh/tc.str.c,v 3.13 2004/02/21 20:34:25 christos Exp $ */ 2 /* 3 * tc.str.c: Short string package 4 * This has been a lesson of how to write buggy code! 5 */ 6 /*- 7 * Copyright (c) 1980, 1991 The Regents of the University of California. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 #include "sh.h" 35 36 RCSID("$Id: tc.str.c,v 3.13 2004/02/21 20:34:25 christos Exp $") 37 38 #define MALLOC_INCR 128 39 40 #ifdef SHORT_STRINGS 41 Char ** 42 blk2short(src) 43 register char **src; 44 { 45 size_t n; 46 register Char **sdst, **dst; 47 48 /* 49 * Count 50 */ 51 for (n = 0; src[n] != NULL; n++) 52 continue; 53 sdst = dst = (Char **) xmalloc((size_t) ((n + 1) * sizeof(Char *))); 54 55 for (; *src != NULL; src++) 56 *dst++ = SAVE(*src); 57 *dst = NULL; 58 return (sdst); 59 } 60 61 char ** 62 short2blk(src) 63 register Char **src; 64 { 65 size_t n; 66 register char **sdst, **dst; 67 68 /* 69 * Count 70 */ 71 for (n = 0; src[n] != NULL; n++) 72 continue; 73 sdst = dst = (char **) xmalloc((size_t) ((n + 1) * sizeof(char *))); 74 75 for (; *src != NULL; src++) 76 *dst++ = strsave(short2str(*src)); 77 *dst = NULL; 78 return (sdst); 79 } 80 81 Char * 82 str2short(src) 83 register const char *src; 84 { 85 static Char *sdst; 86 static size_t dstsize = 0; 87 register Char *dst, *edst; 88 89 if (src == NULL) 90 return (NULL); 91 92 if (sdst == (NULL)) { 93 dstsize = MALLOC_INCR; 94 sdst = (Char *) xmalloc((size_t) (dstsize * sizeof(Char))); 95 } 96 97 dst = sdst; 98 edst = &dst[dstsize]; 99 while ((unsigned char) *src) { 100 *dst++ = (Char) ((unsigned char) *src++); 101 if (dst == edst) { 102 dstsize += MALLOC_INCR; 103 sdst = (Char *) xrealloc((ptr_t) sdst, 104 (size_t) (dstsize * sizeof(Char))); 105 edst = &sdst[dstsize]; 106 dst = &edst[-MALLOC_INCR]; 107 } 108 } 109 *dst = 0; 110 return (sdst); 111 } 112 113 char * 114 short2str(src) 115 register const Char *src; 116 { 117 static char *sdst = NULL; 118 static size_t dstsize = 0; 119 register char *dst, *edst; 120 121 if (src == NULL) 122 return (NULL); 123 124 if (sdst == NULL) { 125 dstsize = MALLOC_INCR; 126 sdst = (char *) xmalloc((size_t) (dstsize * sizeof(char))); 127 } 128 dst = sdst; 129 edst = &dst[dstsize]; 130 while (*src) { 131 *dst++ = (char) *src++; 132 if (dst == edst) { 133 dstsize += MALLOC_INCR; 134 sdst = (char *) xrealloc((ptr_t) sdst, 135 (size_t) (dstsize * sizeof(char))); 136 edst = &sdst[dstsize]; 137 dst = &edst[-MALLOC_INCR]; 138 } 139 } 140 *dst = 0; 141 return (sdst); 142 } 143 144 Char * 145 s_strcpy(dst, src) 146 register Char *dst; 147 register const Char *src; 148 { 149 register Char *sdst; 150 151 sdst = dst; 152 while ((*dst++ = *src++) != '\0') 153 continue; 154 return (sdst); 155 } 156 157 Char * 158 s_strncpy(dst, src, n) 159 register Char *dst; 160 register const Char *src; 161 register size_t n; 162 { 163 register Char *sdst; 164 165 if (n == 0) 166 return(dst); 167 168 sdst = dst; 169 do 170 if ((*dst++ = *src++) == '\0') { 171 while (--n != 0) 172 *dst++ = '\0'; 173 return(sdst); 174 } 175 while (--n != 0); 176 return (sdst); 177 } 178 179 Char * 180 s_strcat(dst, src) 181 register Char *dst; 182 register const Char *src; 183 { 184 register short *sdst; 185 186 sdst = dst; 187 while (*dst++) 188 continue; 189 --dst; 190 while ((*dst++ = *src++) != '\0') 191 continue; 192 return (sdst); 193 } 194 195 #ifdef NOTUSED 196 Char * 197 s_strncat(dst, src, n) 198 register Char *dst; 199 register const Char *src; 200 register size_t n; 201 { 202 register Char *sdst; 203 204 if (n == 0) 205 return (dst); 206 207 sdst = dst; 208 209 while (*dst++) 210 continue; 211 --dst; 212 213 do 214 if ((*dst++ = *src++) == '\0') 215 return(sdst); 216 while (--n != 0) 217 continue; 218 219 *dst = '\0'; 220 return (sdst); 221 } 222 223 #endif 224 225 Char * 226 s_strchr(str, ch) 227 register const Char *str; 228 int ch; 229 { 230 do 231 if (*str == ch) 232 return ((Char *) str); 233 while (*str++); 234 return (NULL); 235 } 236 237 Char * 238 s_strrchr(str, ch) 239 register const Char *str; 240 int ch; 241 { 242 register const Char *rstr; 243 244 rstr = NULL; 245 do 246 if (*str == ch) 247 rstr = str; 248 while (*str++); 249 return ((Char *) rstr); 250 } 251 252 size_t 253 s_strlen(str) 254 register const Char *str; 255 { 256 register size_t n; 257 258 for (n = 0; *str++; n++) 259 continue; 260 return (n); 261 } 262 263 int 264 s_strcmp(str1, str2) 265 register const Char *str1, *str2; 266 { 267 for (; *str1 && *str1 == *str2; str1++, str2++) 268 continue; 269 /* 270 * The following case analysis is necessary so that characters which look 271 * negative collate low against normal characters but high against the 272 * end-of-string NUL. 273 */ 274 if (*str1 == '\0' && *str2 == '\0') 275 return (0); 276 else if (*str1 == '\0') 277 return (-1); 278 else if (*str2 == '\0') 279 return (1); 280 else 281 return (*str1 - *str2); 282 } 283 284 int 285 s_strncmp(str1, str2, n) 286 register const Char *str1, *str2; 287 register size_t n; 288 { 289 if (n == 0) 290 return (0); 291 do { 292 if (*str1 != *str2) { 293 /* 294 * The following case analysis is necessary so that characters 295 * which look negative collate low against normal characters 296 * but high against the end-of-string NUL. 297 */ 298 if (*str1 == '\0') 299 return (-1); 300 else if (*str2 == '\0') 301 return (1); 302 else 303 return (*str1 - *str2); 304 } 305 if (*str1 == '\0') 306 return(0); 307 str1++, str2++; 308 } while (--n != 0); 309 return(0); 310 } 311 312 int 313 s_strcasecmp(str1, str2) 314 register const Char *str1, *str2; 315 { 316 unsigned char c1, c2, l1 = 0, l2 = 0; 317 for (; *str1 && ((*str1 == *str2 && (l1 = l2 = 0) == 0) || 318 ((c1 = (unsigned char)*str1) == *str1 && 319 (c2 = (unsigned char)*str2) == *str2 && 320 (l1 = tolower(c1)) == (l2 = tolower(c2)))); str1++, str2++) 321 continue; 322 /* 323 * The following case analysis is necessary so that characters which look 324 * negative collate low against normal characters but high against the 325 * end-of-string NUL. 326 */ 327 if (*str1 == '\0' && *str2 == '\0') 328 return (0); 329 else if (*str1 == '\0') 330 return (-1); 331 else if (*str2 == '\0') 332 return (1); 333 else if (l1 == l2) /* They are zero when they are equal */ 334 return (*str1 - *str2); 335 else 336 return (l1 - l2); 337 } 338 339 Char * 340 s_strsave(s) 341 register const Char *s; 342 { 343 Char *n; 344 register Char *p; 345 346 if (s == 0) 347 s = STRNULL; 348 for (p = (Char *) s; *p++;) 349 continue; 350 n = p = (Char *) xmalloc((size_t) 351 ((((const Char *) p) - s) * sizeof(Char))); 352 while ((*p++ = *s++) != '\0') 353 continue; 354 return (n); 355 } 356 357 Char * 358 s_strspl(cp, dp) 359 const Char *cp, *dp; 360 { 361 Char *ep; 362 register Char *p, *q; 363 364 if (!cp) 365 cp = STRNULL; 366 if (!dp) 367 dp = STRNULL; 368 for (p = (Char *) cp; *p++;) 369 continue; 370 for (q = (Char *) dp; *q++;) 371 continue; 372 ep = (Char *) xmalloc((size_t) 373 (((((const Char *) p) - cp) + 374 (((const Char *) q) - dp) - 1) * sizeof(Char))); 375 for (p = ep, q = (Char*) cp; (*p++ = *q++) != '\0';) 376 continue; 377 for (p--, q = (Char *) dp; (*p++ = *q++) != '\0';) 378 continue; 379 return (ep); 380 } 381 382 Char * 383 s_strend(cp) 384 register const Char *cp; 385 { 386 if (!cp) 387 return ((Char *) cp); 388 while (*cp) 389 cp++; 390 return ((Char *) cp); 391 } 392 393 Char * 394 s_strstr(s, t) 395 register const Char *s, *t; 396 { 397 do { 398 register const Char *ss = s; 399 register const Char *tt = t; 400 401 do 402 if (*tt == '\0') 403 return ((Char *) s); 404 while (*ss++ == *tt++); 405 } while (*s++ != '\0'); 406 return (NULL); 407 } 408 409 #endif /* SHORT_STRINGS */ 410 411 char * 412 short2qstr(src) 413 register const Char *src; 414 { 415 static char *sdst = NULL; 416 static size_t dstsize = 0; 417 register char *dst, *edst; 418 419 if (src == NULL) 420 return (NULL); 421 422 if (sdst == NULL) { 423 dstsize = MALLOC_INCR; 424 sdst = (char *) xmalloc((size_t) (dstsize * sizeof(char))); 425 } 426 dst = sdst; 427 edst = &dst[dstsize]; 428 while (*src) { 429 if (*src & QUOTE) { 430 *dst++ = '\\'; 431 if (dst == edst) { 432 dstsize += MALLOC_INCR; 433 sdst = (char *) xrealloc((ptr_t) sdst, 434 (size_t) (dstsize * sizeof(char))); 435 edst = &sdst[dstsize]; 436 dst = &edst[-MALLOC_INCR]; 437 } 438 } 439 *dst++ = (char) *src++; 440 if (dst == edst) { 441 dstsize += MALLOC_INCR; 442 sdst = (char *) xrealloc((ptr_t) sdst, 443 (size_t) (dstsize * sizeof(char))); 444 edst = &sdst[dstsize]; 445 dst = &edst[-MALLOC_INCR]; 446 } 447 } 448 *dst = 0; 449 return (sdst); 450 } 451