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