1 /* $Header: /src/pub/tcsh/tc.str.c,v 3.10 2002/03/08 17:36:47 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.10 2002/03/08 17:36:47 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 Char * 313 s_strsave(s) 314 register const Char *s; 315 { 316 Char *n; 317 register Char *p; 318 319 if (s == 0) 320 s = STRNULL; 321 for (p = (Char *) s; *p++;) 322 continue; 323 n = p = (Char *) xmalloc((size_t) 324 ((((const Char *) p) - s) * sizeof(Char))); 325 while ((*p++ = *s++) != '\0') 326 continue; 327 return (n); 328 } 329 330 Char * 331 s_strspl(cp, dp) 332 const Char *cp, *dp; 333 { 334 Char *ep; 335 register Char *p, *q; 336 337 if (!cp) 338 cp = STRNULL; 339 if (!dp) 340 dp = STRNULL; 341 for (p = (Char *) cp; *p++;) 342 continue; 343 for (q = (Char *) dp; *q++;) 344 continue; 345 ep = (Char *) xmalloc((size_t) 346 (((((const Char *) p) - cp) + 347 (((const Char *) q) - dp) - 1) * sizeof(Char))); 348 for (p = ep, q = (Char*) cp; (*p++ = *q++) != '\0';) 349 continue; 350 for (p--, q = (Char *) dp; (*p++ = *q++) != '\0';) 351 continue; 352 return (ep); 353 } 354 355 Char * 356 s_strend(cp) 357 register const Char *cp; 358 { 359 if (!cp) 360 return ((Char *) cp); 361 while (*cp) 362 cp++; 363 return ((Char *) cp); 364 } 365 366 Char * 367 s_strstr(s, t) 368 register const Char *s, *t; 369 { 370 do { 371 register const Char *ss = s; 372 register const Char *tt = t; 373 374 do 375 if (*tt == '\0') 376 return ((Char *) s); 377 while (*ss++ == *tt++); 378 } while (*s++ != '\0'); 379 return (NULL); 380 } 381 382 #endif /* SHORT_STRINGS */ 383 384 char * 385 short2qstr(src) 386 register const Char *src; 387 { 388 static char *sdst = NULL; 389 static size_t dstsize = 0; 390 register char *dst, *edst; 391 392 if (src == NULL) 393 return (NULL); 394 395 if (sdst == NULL) { 396 dstsize = MALLOC_INCR; 397 sdst = (char *) xmalloc((size_t) (dstsize * sizeof(char))); 398 } 399 dst = sdst; 400 edst = &dst[dstsize]; 401 while (*src) { 402 if (*src & QUOTE) { 403 *dst++ = '\\'; 404 if (dst == edst) { 405 dstsize += MALLOC_INCR; 406 sdst = (char *) xrealloc((ptr_t) sdst, 407 (size_t) (dstsize * sizeof(char))); 408 edst = &sdst[dstsize]; 409 dst = &edst[-MALLOC_INCR]; 410 } 411 } 412 *dst++ = (char) *src++; 413 if (dst == edst) { 414 dstsize += MALLOC_INCR; 415 sdst = (char *) xrealloc((ptr_t) sdst, 416 (size_t) (dstsize * sizeof(char))); 417 edst = &sdst[dstsize]; 418 dst = &edst[-MALLOC_INCR]; 419 } 420 } 421 *dst = 0; 422 return (sdst); 423 } 424