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