tc.str.c revision 131962
155714Skris/* $Header: /src/pub/tcsh/tc.str.c,v 3.13 2004/02/21 20:34:25 christos Exp $ */ 255714Skris/* 355714Skris * tc.str.c: Short string package 455714Skris * This has been a lesson of how to write buggy code! 555714Skris */ 655714Skris/*- 755714Skris * Copyright (c) 1980, 1991 The Regents of the University of California. 855714Skris * All rights reserved. 955714Skris * 1055714Skris * Redistribution and use in source and binary forms, with or without 1155714Skris * modification, are permitted provided that the following conditions 1255714Skris * are met: 1355714Skris * 1. Redistributions of source code must retain the above copyright 1455714Skris * notice, this list of conditions and the following disclaimer. 1555714Skris * 2. Redistributions in binary form must reproduce the above copyright 1655714Skris * notice, this list of conditions and the following disclaimer in the 1755714Skris * documentation and/or other materials provided with the distribution. 1855714Skris * 3. Neither the name of the University nor the names of its contributors 1955714Skris * may be used to endorse or promote products derived from this software 2055714Skris * without specific prior written permission. 2155714Skris * 2255714Skris * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2355714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2455714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2555714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2655714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2755714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2855714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2955714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3055714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3155714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3255714Skris * SUCH DAMAGE. 3355714Skris */ 3455714Skris#include "sh.h" 3555714Skris 3655714SkrisRCSID("$Id: tc.str.c,v 3.13 2004/02/21 20:34:25 christos Exp $") 3755714Skris 3855714Skris#define MALLOC_INCR 128 3955714Skris 4055714Skris#ifdef SHORT_STRINGS 4155714SkrisChar ** 4255714Skrisblk2short(src) 4355714Skris register char **src; 4455714Skris{ 4555714Skris size_t n; 4655714Skris register Char **sdst, **dst; 4755714Skris 4855714Skris /* 4955714Skris * Count 5055714Skris */ 5155714Skris for (n = 0; src[n] != NULL; n++) 5255714Skris continue; 5355714Skris sdst = dst = (Char **) xmalloc((size_t) ((n + 1) * sizeof(Char *))); 5455714Skris 5555714Skris for (; *src != NULL; src++) 5655714Skris *dst++ = SAVE(*src); 5755714Skris *dst = NULL; 5855714Skris return (sdst); 5955714Skris} 6055714Skris 6155714Skrischar ** 6255714Skrisshort2blk(src) 6355714Skris register Char **src; 6455714Skris{ 6555714Skris size_t n; 6655714Skris register char **sdst, **dst; 6755714Skris 6855714Skris /* 6955714Skris * Count 7055714Skris */ 7155714Skris for (n = 0; src[n] != NULL; n++) 7255714Skris continue; 7355714Skris sdst = dst = (char **) xmalloc((size_t) ((n + 1) * sizeof(char *))); 7455714Skris 7555714Skris for (; *src != NULL; src++) 7655714Skris *dst++ = strsave(short2str(*src)); 7755714Skris *dst = NULL; 7855714Skris return (sdst); 7955714Skris} 8055714Skris 8155714SkrisChar * 8255714Skrisstr2short(src) 8355714Skris 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 113char * 114short2str(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 144Char * 145s_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 157Char * 158s_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 179Char * 180s_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 196Char * 197s_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 225Char * 226s_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 237Char * 238s_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 252size_t 253s_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 263int 264s_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 284int 285s_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 312int 313s_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 339Char * 340s_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 357Char * 358s_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 382Char * 383s_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 393Char * 394s_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 411char * 412short2qstr(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