1: /* $Header: str.c,v 1.0.1.1 88/01/21 21:28:39 root Exp $
   2:  *
   3:  * $Log:	str.c,v $
   4:  * Revision 1.0.1.1  88/01/21  21:28:39  root
   5:  * Suppressed warning messages on signed vs unsigned chars in str_gets().
   6:  *
   7:  * Revision 1.0  87/12/18  13:06:22  root
   8:  * Initial revision
   9:  *
  10:  */
  11: 
  12: #include "handy.h"
  13: #include "EXTERN.h"
  14: #include "search.h"
  15: #include "util.h"
  16: #include "perl.h"
  17: 
  18: str_reset(s)
  19: register char *s;
  20: {
  21:     register STAB *stab;
  22:     register STR *str;
  23:     register int i;
  24:     register int max;
  25:     register SPAT *spat;
  26: 
  27:     if (!*s) {      /* reset ?? searches */
  28:     for (spat = spat_root; spat != Nullspat; spat = spat->spat_next) {
  29:         spat->spat_flags &= ~SPAT_USED;
  30:     }
  31:     return;
  32:     }
  33: 
  34:     /* reset variables */
  35: 
  36:     while (*s) {
  37:     i = *s;
  38:     if (s[1] == '-') {
  39:         s += 2;
  40:     }
  41:     max = *s++;
  42:     for ( ; i <= max; i++) {
  43:         for (stab = stab_index[i]; stab; stab = stab->stab_next) {
  44:         str = stab->stab_val;
  45:         str->str_cur = 0;
  46:         if (str->str_ptr != Nullch)
  47:             str->str_ptr[0] = '\0';
  48:         }
  49:     }
  50:     }
  51: }
  52: 
  53: str_numset(str,num)
  54: register STR *str;
  55: double num;
  56: {
  57:     str->str_nval = num;
  58:     str->str_pok = 0;       /* invalidate pointer */
  59:     str->str_nok = 1;       /* validate number */
  60: }
  61: 
  62: char *
  63: str_2ptr(str)
  64: register STR *str;
  65: {
  66:     register char *s;
  67: 
  68:     if (!str)
  69:     return "";
  70:     GROWSTR(&(str->str_ptr), &(str->str_len), 24);
  71:     s = str->str_ptr;
  72:     if (str->str_nok) {
  73:     sprintf(s,"%.20g",str->str_nval);
  74:     while (*s) s++;
  75:     }
  76:     *s = '\0';
  77:     str->str_cur = s - str->str_ptr;
  78:     str->str_pok = 1;
  79: #ifdef DEBUGGING
  80:     if (debug & 32)
  81:     fprintf(stderr,"0x%lx ptr(%s)\n",str,str->str_ptr);
  82: #endif
  83:     return str->str_ptr;
  84: }
  85: 
  86: double
  87: str_2num(str)
  88: register STR *str;
  89: {
  90:     if (!str)
  91:     return 0.0;
  92:     if (str->str_len && str->str_pok)
  93:     str->str_nval = atof(str->str_ptr);
  94:     else
  95:     str->str_nval = 0.0;
  96:     str->str_nok = 1;
  97: #ifdef DEBUGGING
  98:     if (debug & 32)
  99:     fprintf(stderr,"0x%lx num(%g)\n",str,str->str_nval);
 100: #endif
 101:     return str->str_nval;
 102: }
 103: 
 104: str_sset(dstr,sstr)
 105: STR *dstr;
 106: register STR *sstr;
 107: {
 108:     if (!sstr)
 109:     str_nset(dstr,No,0);
 110:     else if (sstr->str_nok)
 111:     str_numset(dstr,sstr->str_nval);
 112:     else if (sstr->str_pok)
 113:     str_nset(dstr,sstr->str_ptr,sstr->str_cur);
 114:     else
 115:     str_nset(dstr,"",0);
 116: }
 117: 
 118: str_nset(str,ptr,len)
 119: register STR *str;
 120: register char *ptr;
 121: register int len;
 122: {
 123:     GROWSTR(&(str->str_ptr), &(str->str_len), len + 1);
 124:     bcopy(ptr,str->str_ptr,len);
 125:     str->str_cur = len;
 126:     *(str->str_ptr+str->str_cur) = '\0';
 127:     str->str_nok = 0;       /* invalidate number */
 128:     str->str_pok = 1;       /* validate pointer */
 129: }
 130: 
 131: str_set(str,ptr)
 132: register STR *str;
 133: register char *ptr;
 134: {
 135:     register int len;
 136: 
 137:     if (!ptr)
 138:     ptr = "";
 139:     len = strlen(ptr);
 140:     GROWSTR(&(str->str_ptr), &(str->str_len), len + 1);
 141:     bcopy(ptr,str->str_ptr,len+1);
 142:     str->str_cur = len;
 143:     str->str_nok = 0;       /* invalidate number */
 144:     str->str_pok = 1;       /* validate pointer */
 145: }
 146: 
 147: str_chop(str,ptr)   /* like set but assuming ptr is in str */
 148: register STR *str;
 149: register char *ptr;
 150: {
 151:     if (!(str->str_pok))
 152:     str_2ptr(str);
 153:     str->str_cur -= (ptr - str->str_ptr);
 154:     bcopy(ptr,str->str_ptr, str->str_cur + 1);
 155:     str->str_nok = 0;       /* invalidate number */
 156:     str->str_pok = 1;       /* validate pointer */
 157: }
 158: 
 159: str_ncat(str,ptr,len)
 160: register STR *str;
 161: register char *ptr;
 162: register int len;
 163: {
 164:     if (!(str->str_pok))
 165:     str_2ptr(str);
 166:     GROWSTR(&(str->str_ptr), &(str->str_len), str->str_cur + len + 1);
 167:     bcopy(ptr,str->str_ptr+str->str_cur,len);
 168:     str->str_cur += len;
 169:     *(str->str_ptr+str->str_cur) = '\0';
 170:     str->str_nok = 0;       /* invalidate number */
 171:     str->str_pok = 1;       /* validate pointer */
 172: }
 173: 
 174: str_scat(dstr,sstr)
 175: STR *dstr;
 176: register STR *sstr;
 177: {
 178:     if (!(sstr->str_pok))
 179:     str_2ptr(sstr);
 180:     if (sstr)
 181:     str_ncat(dstr,sstr->str_ptr,sstr->str_cur);
 182: }
 183: 
 184: str_cat(str,ptr)
 185: register STR *str;
 186: register char *ptr;
 187: {
 188:     register int len;
 189: 
 190:     if (!ptr)
 191:     return;
 192:     if (!(str->str_pok))
 193:     str_2ptr(str);
 194:     len = strlen(ptr);
 195:     GROWSTR(&(str->str_ptr), &(str->str_len), str->str_cur + len + 1);
 196:     bcopy(ptr,str->str_ptr+str->str_cur,len+1);
 197:     str->str_cur += len;
 198:     str->str_nok = 0;       /* invalidate number */
 199:     str->str_pok = 1;       /* validate pointer */
 200: }
 201: 
 202: char *
 203: str_append_till(str,from,delim,keeplist)
 204: register STR *str;
 205: register char *from;
 206: register int delim;
 207: char *keeplist;
 208: {
 209:     register char *to;
 210:     register int len;
 211: 
 212:     if (!from)
 213:     return Nullch;
 214:     len = strlen(from);
 215:     GROWSTR(&(str->str_ptr), &(str->str_len), str->str_cur + len + 1);
 216:     str->str_nok = 0;       /* invalidate number */
 217:     str->str_pok = 1;       /* validate pointer */
 218:     to = str->str_ptr+str->str_cur;
 219:     for (; *from; from++,to++) {
 220:     if (*from == '\\' && from[1] && delim != '\\') {
 221:         if (!keeplist) {
 222:         if (from[1] == delim || from[1] == '\\')
 223:             from++;
 224:         else
 225:             *to++ = *from++;
 226:         }
 227:         else if (index(keeplist,from[1]))
 228:         *to++ = *from++;
 229:         else
 230:         from++;
 231:     }
 232:     else if (*from == delim)
 233:         break;
 234:     *to = *from;
 235:     }
 236:     *to = '\0';
 237:     str->str_cur = to - str->str_ptr;
 238:     return from;
 239: }
 240: 
 241: STR *
 242: str_new(len)
 243: int len;
 244: {
 245:     register STR *str;
 246: 
 247:     if (freestrroot) {
 248:     str = freestrroot;
 249:     freestrroot = str->str_link.str_next;
 250:     str->str_link.str_magic = Nullstab;
 251:     }
 252:     else {
 253:     str = (STR *) safemalloc(sizeof(STR));
 254:     bzero((char*)str,sizeof(STR));
 255:     }
 256:     if (len)
 257:     GROWSTR(&(str->str_ptr), &(str->str_len), len + 1);
 258:     return str;
 259: }
 260: 
 261: void
 262: str_grow(str,len)
 263: register STR *str;
 264: int len;
 265: {
 266:     if (len && str)
 267:     GROWSTR(&(str->str_ptr), &(str->str_len), len + 1);
 268: }
 269: 
 270: /* make str point to what nstr did */
 271: 
 272: void
 273: str_replace(str,nstr)
 274: register STR *str;
 275: register STR *nstr;
 276: {
 277:     safefree(str->str_ptr);
 278:     str->str_ptr = nstr->str_ptr;
 279:     str->str_len = nstr->str_len;
 280:     str->str_cur = nstr->str_cur;
 281:     str->str_pok = nstr->str_pok;
 282:     if (str->str_nok = nstr->str_nok)
 283:     str->str_nval = nstr->str_nval;
 284:     safefree((char*)nstr);
 285: }
 286: 
 287: void
 288: str_free(str)
 289: register STR *str;
 290: {
 291:     if (!str)
 292:     return;
 293:     if (str->str_len)
 294:     str->str_ptr[0] = '\0';
 295:     str->str_cur = 0;
 296:     str->str_nok = 0;
 297:     str->str_pok = 0;
 298:     str->str_link.str_next = freestrroot;
 299:     freestrroot = str;
 300: }
 301: 
 302: str_len(str)
 303: register STR *str;
 304: {
 305:     if (!str)
 306:     return 0;
 307:     if (!(str->str_pok))
 308:     str_2ptr(str);
 309:     if (str->str_len)
 310:     return str->str_cur;
 311:     else
 312:     return 0;
 313: }
 314: 
 315: char *
 316: str_gets(str,fp)
 317: register STR *str;
 318: register FILE *fp;
 319: {
 320: #ifdef STDSTDIO     /* Here is some breathtakingly efficient cheating */
 321: 
 322:     register char *bp;      /* we're going to steal some values */
 323:     register int cnt;       /*  from the stdio struct and put EVERYTHING */
 324:     register STDCHAR *ptr;  /*   in the innermost loop into registers */
 325:     register char newline = record_separator;/* (assuming >= 6 registers) */
 326:     int i;
 327:     int bpx;
 328:     int obpx;
 329:     register int get_paragraph;
 330:     register char *oldbp;
 331: 
 332:     if (get_paragraph = !newline) { /* yes, that's an assignment */
 333:     newline = '\n';
 334:     oldbp = Nullch;         /* remember last \n position (none) */
 335:     }
 336:     cnt = fp->_cnt;         /* get count into register */
 337:     str->str_nok = 0;           /* invalidate number */
 338:     str->str_pok = 1;           /* validate pointer */
 339:     if (str->str_len <= cnt)        /* make sure we have the room */
 340:     GROWSTR(&(str->str_ptr), &(str->str_len), cnt+1);
 341:     bp = str->str_ptr;          /* move these two too to registers */
 342:     ptr = fp->_ptr;
 343:     for (;;) {
 344:       screamer:
 345:     while (--cnt >= 0) {            /* this */  /* eat */
 346:         if ((*bp++ = *ptr++) == newline)    /* really */    /* dust */
 347:         goto thats_all_folks;       /* screams */   /* sed :-) */
 348:     }
 349: 
 350:     fp->_cnt = cnt;         /* deregisterize cnt and ptr */
 351:     fp->_ptr = ptr;
 352:     i = _filbuf(fp);        /* get more characters */
 353:     cnt = fp->_cnt;
 354:     ptr = fp->_ptr;         /* reregisterize cnt and ptr */
 355: 
 356:     bpx = bp - str->str_ptr;    /* prepare for possible relocation */
 357:     if (get_paragraph && oldbp)
 358:         obpx = oldbp - str->str_ptr;
 359:     GROWSTR(&(str->str_ptr), &(str->str_len), str->str_cur + cnt + 1);
 360:     bp = str->str_ptr + bpx;    /* reconstitute our pointer */
 361:     if (get_paragraph && oldbp)
 362:         oldbp = str->str_ptr + obpx;
 363: 
 364:     if (i == newline) {     /* all done for now? */
 365:         *bp++ = i;
 366:         goto thats_all_folks;
 367:     }
 368:     else if (i == EOF)      /* all done for ever? */
 369:         goto thats_really_all_folks;
 370:     *bp++ = i;          /* now go back to screaming loop */
 371:     }
 372: 
 373: thats_all_folks:
 374:     if (get_paragraph && bp - 1 != oldbp) {
 375:     oldbp = bp; /* remember where this newline was */
 376:     goto screamer;  /* and go back to the fray */
 377:     }
 378: thats_really_all_folks:
 379:     fp->_cnt = cnt;         /* put these back or we're in trouble */
 380:     fp->_ptr = ptr;
 381:     *bp = '\0';
 382:     str->str_cur = bp - str->str_ptr;   /* set length */
 383: 
 384: #else /* !STDSTDIO */   /* The big, slow, and stupid way */
 385: 
 386:     static char buf[4192];
 387: 
 388:     if (fgets(buf, sizeof buf, fp) != Nullch)
 389:     str_set(str, buf);
 390:     else
 391:     str_set(str, No);
 392: 
 393: #endif /* STDSTDIO */
 394: 
 395:     return str->str_cur ? str->str_ptr : Nullch;
 396: }
 397: 
 398: 
 399: STR *
 400: interp(str,s)
 401: register STR *str;
 402: register char *s;
 403: {
 404:     register char *t = s;
 405:     char *envsave = envname;
 406:     envname = Nullch;
 407: 
 408:     str_set(str,"");
 409:     while (*s) {
 410:     if (*s == '\\' && s[1] == '$') {
 411:         str_ncat(str, t, s++ - t);
 412:         t = s++;
 413:     }
 414:     else if (*s == '$' && s[1] && s[1] != '|') {
 415:         str_ncat(str,t,s-t);
 416:         s = scanreg(s,tokenbuf);
 417:         str_cat(str,reg_get(tokenbuf));
 418:         t = s;
 419:     }
 420:     else
 421:         s++;
 422:     }
 423:     envname = envsave;
 424:     str_ncat(str,t,s-t);
 425:     return str;
 426: }
 427: 
 428: void
 429: str_inc(str)
 430: register STR *str;
 431: {
 432:     register char *d;
 433: 
 434:     if (!str)
 435:     return;
 436:     if (str->str_nok) {
 437:     str->str_nval += 1.0;
 438:     str->str_pok = 0;
 439:     return;
 440:     }
 441:     if (!str->str_pok) {
 442:     str->str_nval = 1.0;
 443:     str->str_nok = 1;
 444:     return;
 445:     }
 446:     for (d = str->str_ptr; *d && *d != '.'; d++) ;
 447:     d--;
 448:     if (!isdigit(*str->str_ptr) || !isdigit(*d) ) {
 449:         str_numset(str,atof(str->str_ptr) + 1.0);  /* punt */
 450:     return;
 451:     }
 452:     while (d >= str->str_ptr) {
 453:     if (++*d <= '9')
 454:         return;
 455:     *(d--) = '0';
 456:     }
 457:     /* oh,oh, the number grew */
 458:     GROWSTR(&(str->str_ptr), &(str->str_len), str->str_cur + 2);
 459:     str->str_cur++;
 460:     for (d = str->str_ptr + str->str_cur; d > str->str_ptr; d--)
 461:     *d = d[-1];
 462:     *d = '1';
 463: }
 464: 
 465: void
 466: str_dec(str)
 467: register STR *str;
 468: {
 469:     register char *d;
 470: 
 471:     if (!str)
 472:     return;
 473:     if (str->str_nok) {
 474:     str->str_nval -= 1.0;
 475:     str->str_pok = 0;
 476:     return;
 477:     }
 478:     if (!str->str_pok) {
 479:     str->str_nval = -1.0;
 480:     str->str_nok = 1;
 481:     return;
 482:     }
 483:     for (d = str->str_ptr; *d && *d != '.'; d++) ;
 484:     d--;
 485:     if (!isdigit(*str->str_ptr) || !isdigit(*d) || (*d == '0' && d == str->str_ptr)) {
 486:         str_numset(str,atof(str->str_ptr) - 1.0);  /* punt */
 487:     return;
 488:     }
 489:     while (d >= str->str_ptr) {
 490:     if (--*d >= '0')
 491:         return;
 492:     *(d--) = '9';
 493:     }
 494: }
 495: 
 496: /* make a string that will exist for the duration of the expression eval */
 497: 
 498: STR *
 499: str_static(oldstr)
 500: STR *oldstr;
 501: {
 502:     register STR *str = str_new(0);
 503:     static long tmps_size = -1;
 504: 
 505:     str_sset(str,oldstr);
 506:     if (++tmps_max > tmps_size) {
 507:     tmps_size = tmps_max;
 508:     if (!(tmps_size & 127)) {
 509:         if (tmps_size)
 510:         tmps_list = (STR**)saferealloc((char*)tmps_list,
 511:             (tmps_size + 128) * sizeof(STR*) );
 512:         else
 513:         tmps_list = (STR**)safemalloc(128 * sizeof(char*));
 514:     }
 515:     }
 516:     tmps_list[tmps_max] = str;
 517:     return str;
 518: }
 519: 
 520: STR *
 521: str_make(s)
 522: char *s;
 523: {
 524:     register STR *str = str_new(0);
 525: 
 526:     str_set(str,s);
 527:     return str;
 528: }
 529: 
 530: STR *
 531: str_nmake(n)
 532: double n;
 533: {
 534:     register STR *str = str_new(0);
 535: 
 536:     str_numset(str,n);
 537:     return str;
 538: }

Defined functions

str_2ptr defined in line 62; used 7 times
str_cat defined in line 184; used 12 times
str_chop defined in line 147; used 3 times
str_dec defined in line 465; used 2 times
str_grow defined in line 261; used 1 times
str_inc defined in line 428; used 3 times
str_ncat defined in line 159; used 6 times
str_nmake defined in line 530; used 27 times
str_nset defined in line 118; used 6 times
str_replace defined in line 272; used 1 times
str_reset defined in line 18; used 1 times
Last modified: 1988-02-03
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4735
Valid CSS Valid XHTML 1.0 Strict