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