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 34 #ifndef lint 35 /*static char sccsid[] = "from: @(#)str.c 8.1 (Berkeley) 5/31/93";*/ 36 static char *rcsid = "$Id: str.c,v 1.5 1994/09/21 00:11:18 mycroft Exp $"; 37 #endif /* not lint */ 38 39 #define MALLOC_INCR 128 40 41 /* 42 * tc.str.c: Short string package 43 * This has been a lesson of how to write buggy code! 44 */ 45 46 #include <sys/types.h> 47 #if __STDC__ 48 # include <stdarg.h> 49 #else 50 # include <varargs.h> 51 #endif 52 #include <vis.h> 53 54 #include "csh.h" 55 #include "extern.h" 56 57 #ifdef SHORT_STRINGS 58 59 Char ** 60 blk2short(src) 61 register char **src; 62 { 63 size_t n; 64 register Char **sdst, **dst; 65 66 /* 67 * Count 68 */ 69 for (n = 0; src[n] != NULL; n++) 70 continue; 71 sdst = dst = (Char **) xmalloc((size_t) ((n + 1) * sizeof(Char *))); 72 73 for (; *src != NULL; src++) 74 *dst++ = SAVE(*src); 75 *dst = NULL; 76 return (sdst); 77 } 78 79 char ** 80 short2blk(src) 81 register Char **src; 82 { 83 size_t n; 84 register char **sdst, **dst; 85 86 /* 87 * Count 88 */ 89 for (n = 0; src[n] != NULL; n++) 90 continue; 91 sdst = dst = (char **) xmalloc((size_t) ((n + 1) * sizeof(char *))); 92 93 for (; *src != NULL; src++) 94 *dst++ = strsave(short2str(*src)); 95 *dst = NULL; 96 return (sdst); 97 } 98 99 Char * 100 str2short(src) 101 register char *src; 102 { 103 static Char *sdst; 104 static size_t dstsize = 0; 105 register Char *dst, *edst; 106 107 if (src == NULL) 108 return (NULL); 109 110 if (sdst == (NULL)) { 111 dstsize = MALLOC_INCR; 112 sdst = (Char *) xmalloc((size_t) dstsize * sizeof(Char)); 113 } 114 115 dst = sdst; 116 edst = &dst[dstsize]; 117 while (*src) { 118 *dst++ = (Char) ((unsigned char) *src++); 119 if (dst == edst) { 120 dstsize += MALLOC_INCR; 121 sdst = (Char *) xrealloc((ptr_t) sdst, 122 (size_t) dstsize * sizeof(Char)); 123 edst = &sdst[dstsize]; 124 dst = &edst[-MALLOC_INCR]; 125 } 126 } 127 *dst = 0; 128 return (sdst); 129 } 130 131 char * 132 short2str(src) 133 register Char *src; 134 { 135 static char *sdst = NULL; 136 static size_t dstsize = 0; 137 register char *dst, *edst; 138 139 if (src == NULL) 140 return (NULL); 141 142 if (sdst == NULL) { 143 dstsize = MALLOC_INCR; 144 sdst = (char *) xmalloc((size_t) dstsize * sizeof(char)); 145 } 146 dst = sdst; 147 edst = &dst[dstsize]; 148 while (*src) { 149 *dst++ = (char) *src++; 150 if (dst == edst) { 151 dstsize += MALLOC_INCR; 152 sdst = (char *) xrealloc((ptr_t) sdst, 153 (size_t) dstsize * sizeof(char)); 154 edst = &sdst[dstsize]; 155 dst = &edst[-MALLOC_INCR]; 156 } 157 } 158 *dst = 0; 159 return (sdst); 160 } 161 162 Char * 163 s_strcpy(dst, src) 164 register Char *dst, *src; 165 { 166 register Char *sdst; 167 168 sdst = dst; 169 while ((*dst++ = *src++) != '\0') 170 continue; 171 return (sdst); 172 } 173 174 Char * 175 s_strncpy(dst, src, n) 176 register Char *dst, *src; 177 register size_t n; 178 { 179 register Char *sdst; 180 181 if (n == 0) 182 return(dst); 183 184 sdst = dst; 185 do 186 if ((*dst++ = *src++) == '\0') { 187 while (--n != 0) 188 *dst++ = '\0'; 189 return(sdst); 190 } 191 while (--n != 0); 192 return (sdst); 193 } 194 195 Char * 196 s_strcat(dst, src) 197 register Char *dst, *src; 198 { 199 register short *sdst; 200 201 sdst = dst; 202 while (*dst++) 203 continue; 204 --dst; 205 while ((*dst++ = *src++) != '\0') 206 continue; 207 return (sdst); 208 } 209 210 #ifdef NOTUSED 211 Char * 212 s_strncat(dst, src, n) 213 register Char *dst, *src; 214 register size_t n; 215 { 216 register Char *sdst; 217 218 if (n == 0) 219 return (dst); 220 221 sdst = dst; 222 223 while (*dst++) 224 continue; 225 --dst; 226 227 do 228 if ((*dst++ = *src++) == '\0') 229 return(sdst); 230 while (--n != 0) 231 continue; 232 233 *dst = '\0'; 234 return (sdst); 235 } 236 237 #endif 238 239 Char * 240 s_strchr(str, ch) 241 register Char *str; 242 int ch; 243 { 244 do 245 if (*str == ch) 246 return (str); 247 while (*str++); 248 return (NULL); 249 } 250 251 Char * 252 s_strrchr(str, ch) 253 register Char *str; 254 int ch; 255 { 256 register Char *rstr; 257 258 rstr = NULL; 259 do 260 if (*str == ch) 261 rstr = str; 262 while (*str++); 263 return (rstr); 264 } 265 266 size_t 267 s_strlen(str) 268 register Char *str; 269 { 270 register size_t n; 271 272 for (n = 0; *str++; n++) 273 continue; 274 return (n); 275 } 276 277 int 278 s_strcmp(str1, str2) 279 register Char *str1, *str2; 280 { 281 for (; *str1 && *str1 == *str2; str1++, str2++) 282 continue; 283 /* 284 * The following case analysis is necessary so that characters which look 285 * negative collate low against normal characters but high against the 286 * end-of-string NUL. 287 */ 288 if (*str1 == '\0' && *str2 == '\0') 289 return (0); 290 else if (*str1 == '\0') 291 return (-1); 292 else if (*str2 == '\0') 293 return (1); 294 else 295 return (*str1 - *str2); 296 } 297 298 int 299 s_strncmp(str1, str2, n) 300 register Char *str1, *str2; 301 register size_t n; 302 { 303 if (n == 0) 304 return (0); 305 do { 306 if (*str1 != *str2) { 307 /* 308 * The following case analysis is necessary so that characters 309 * which look negative collate low against normal characters 310 * but high against the end-of-string NUL. 311 */ 312 if (*str1 == '\0') 313 return (-1); 314 else if (*str2 == '\0') 315 return (1); 316 else 317 return (*str1 - *str2); 318 break; 319 } 320 if (*str1 == '\0') 321 return(0); 322 str1++, str2++; 323 } while (--n != 0); 324 return(0); 325 } 326 327 Char * 328 s_strsave(s) 329 register Char *s; 330 { 331 Char *n; 332 register Char *p; 333 334 if (s == 0) 335 s = STRNULL; 336 for (p = s; *p++;) 337 continue; 338 n = p = (Char *) xmalloc((size_t) ((p - s) * sizeof(Char))); 339 while ((*p++ = *s++) != '\0') 340 continue; 341 return (n); 342 } 343 344 Char * 345 s_strspl(cp, dp) 346 Char *cp, *dp; 347 { 348 Char *ep; 349 register Char *p, *q; 350 351 if (!cp) 352 cp = STRNULL; 353 if (!dp) 354 dp = STRNULL; 355 for (p = cp; *p++;) 356 continue; 357 for (q = dp; *q++;) 358 continue; 359 ep = (Char *) xmalloc((size_t) 360 (((p - cp) + (q - dp) - 1) * sizeof(Char))); 361 for (p = ep, q = cp; (*p++ = *q++) != '\0';) 362 continue; 363 for (p--, q = dp; (*p++ = *q++) != '\0';) 364 continue; 365 return (ep); 366 } 367 368 Char * 369 s_strend(cp) 370 register Char *cp; 371 { 372 if (!cp) 373 return (cp); 374 while (*cp) 375 cp++; 376 return (cp); 377 } 378 379 Char * 380 s_strstr(s, t) 381 register Char *s, *t; 382 { 383 do { 384 register Char *ss = s; 385 register Char *tt = t; 386 387 do 388 if (*tt == '\0') 389 return (s); 390 while (*ss++ == *tt++); 391 } while (*s++ != '\0'); 392 return (NULL); 393 } 394 #endif /* SHORT_STRINGS */ 395 396 char * 397 short2qstr(src) 398 register Char *src; 399 { 400 static char *sdst = NULL; 401 static size_t dstsize = 0; 402 register char *dst, *edst; 403 404 if (src == NULL) 405 return (NULL); 406 407 if (sdst == NULL) { 408 dstsize = MALLOC_INCR; 409 sdst = (char *) xmalloc((size_t) dstsize * sizeof(char)); 410 } 411 dst = sdst; 412 edst = &dst[dstsize]; 413 while (*src) { 414 if (*src & QUOTE) { 415 *dst++ = '\\'; 416 if (dst == edst) { 417 dstsize += MALLOC_INCR; 418 sdst = (char *) xrealloc((ptr_t) sdst, 419 (size_t) dstsize * sizeof(char)); 420 edst = &sdst[dstsize]; 421 dst = &edst[-MALLOC_INCR]; 422 } 423 } 424 *dst++ = (char) *src++; 425 if (dst == edst) { 426 dstsize += MALLOC_INCR; 427 sdst = (char *) xrealloc((ptr_t) sdst, 428 (size_t) dstsize * sizeof(char)); 429 edst = &sdst[dstsize]; 430 dst = &edst[-MALLOC_INCR]; 431 } 432 } 433 *dst = 0; 434 return (sdst); 435 } 436 437 /* 438 * XXX: Should we worry about QUOTE'd chars? 439 */ 440 char * 441 vis_str(cp) 442 Char *cp; 443 { 444 static char *sdst = NULL; 445 static size_t dstsize = 0; 446 size_t n; 447 Char *dp; 448 449 if (cp == NULL) 450 return (NULL); 451 452 for (dp = cp; *dp++;) 453 continue; 454 n = ((dp - cp) << 2) + 1; /* 4 times + NULL */ 455 if (dstsize < n) { 456 sdst = (char *) (dstsize ? 457 xrealloc(sdst, (size_t) n * sizeof(char)) : 458 xmalloc((size_t) n * sizeof(char))); 459 dstsize = n; 460 } 461 /* 462 * XXX: When we are in AsciiOnly we want all characters >= 0200 to 463 * be encoded, but currently there is no way in vis to do that. 464 */ 465 (void) strvis(sdst, short2str(cp), VIS_NOSLASH); 466 return (sdst); 467 } 468 469