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