|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)m4.c 1.3 (Berkeley) 8/11/83"; ! 3: #endif ! 4: ! 5: #include <stdio.h> ! 6: #include <signal.h> ! 7: ! 8: #define ERROR NULL ! 9: #define READ "r" ! 10: #define WRITE "w" ! 11: ! 12: #define EOS 0 ! 13: int lpar = '('; ! 14: #define LPAR lpar ! 15: #define RPAR ')' ! 16: #define COMMA ',' ! 17: #define GRAVE '`' ! 18: #define ACUTE '\'' ! 19: #define LBRAK '[' ! 20: #define RBRAK ']' ! 21: #ifdef M4 ! 22: char lquote LBRAK; ! 23: char rquote RBRAK; ! 24: #endif ! 25: #ifndef M4 ! 26: char lquote = GRAVE; ! 27: char rquote = ACUTE; ! 28: #endif ! 29: #define COMMENT '#' ! 30: #define ALPH 1 ! 31: #define DIG 2 ! 32: ! 33: #define HSHSIZ 199 /* prime */ ! 34: #define STACKS 50 ! 35: #define SAVS 4096 ! 36: #define TOKS 128 ! 37: ! 38: #define putbak(c) *ip++ = c; ! 39: #define getchr() (ip>cur_ip?*--ip: getc(infile[infptr])) ! 40: #define putchr(c) if (cp==NULL) {if (curfile)putc(c,curfile);} else *op++ = c ! 41: char type[] = { ! 42: 0, 0, 0, 0, 0, 0, 0, 0, ! 43: 0, 0, 0, 0, 0, 0, 0, 0, ! 44: 0, 0, 0, 0, 0, 0, 0, 0, ! 45: 0, 0, 0, 0, 0, 0, 0, 0, ! 46: 0, 0, 0, 0, 0, 0, 0, 0, ! 47: 0, 0, 0, 0, 0, 0, 0, 0, ! 48: DIG, DIG, DIG, DIG, DIG, DIG, DIG, DIG, ! 49: DIG, DIG, 0, 0, 0, 0, 0, 0, ! 50: 0, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ! 51: ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ! 52: ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ! 53: ALPH, ALPH, ALPH, 0, 0, 0, 0, ALPH, ! 54: 0, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ! 55: ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ! 56: ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ALPH, ! 57: ALPH, ALPH, ALPH, 0, 0, 0, 0, 0, ! 58: }; ! 59: ! 60: char token[TOKS]; ! 61: char eoa[] = "\0"; ! 62: ! 63: #define RESERVED 01 /* This is a reserved word with side action */ ! 64: struct nlist { ! 65: char *name; ! 66: char *def; ! 67: char flag; ! 68: struct nlist *next; ! 69: }; ! 70: ! 71: struct nlist *hshtab[HSHSIZ]; ! 72: char ibuf[SAVS+TOKS]; ! 73: char obuf[SAVS+TOKS]; ! 74: char *op = obuf; ! 75: char *ip = ibuf; ! 76: char *ip_stk[10] = {ibuf}; ! 77: char *cur_ip = ibuf; ! 78: struct call { ! 79: char **argp; ! 80: int plev; ! 81: }; ! 82: struct call *cp = NULL; ! 83: ! 84: char *makeloc; ! 85: char *ifdefloc; ! 86: char *lenloc; ! 87: char *undefloc; ! 88: char *shiftloc; ! 89: char *cqloc; ! 90: char *defloc; ! 91: char *evaloc; ! 92: char *incrloc; ! 93: char *substrloc; ! 94: char *indexloc; ! 95: char *transloc; ! 96: char *ifloc; ! 97: char *divloc; ! 98: char *divnumloc; ! 99: char *undivloc; ! 100: char *dnlloc; ! 101: char *inclloc; ! 102: char *sinclloc; ! 103: char *syscmdloc; ! 104: char *dumploc; ! 105: char *errploc; ! 106: ! 107: char *tempname; ! 108: struct nlist *lookup(); ! 109: char *install(); ! 110: char *malloc(); ! 111: char *mktemp(); ! 112: char *copy(); ! 113: long ctol(); ! 114: int hshval; ! 115: FILE *olist[11] = { stdout }; ! 116: int okret; ! 117: int curout = 0; ! 118: FILE *curfile = { stdout }; ! 119: FILE *infile[10] = { stdin }; ! 120: int infptr = 0; ! 121: ! 122: main(argc, argv) ! 123: char **argv; ! 124: { ! 125: char *argstk[STACKS+10]; ! 126: struct call callst[STACKS]; ! 127: register char *tp, **ap; ! 128: int delexit(), catchsig(); ! 129: register t; ! 130: int i; ! 131: ! 132: #ifdef gcos ! 133: #ifdef M4 ! 134: install("GCOS", eoa, 0); ! 135: #endif ! 136: #ifndef M4 ! 137: install("gcos", eoa, 0); ! 138: #endif ! 139: #endif ! 140: #ifdef unix ! 141: #ifdef M4 ! 142: install("UNIX", eoa, 0); ! 143: #endif ! 144: #ifndef M4 ! 145: install("unix", eoa, 0); ! 146: #endif ! 147: #endif ! 148: ! 149: #ifdef M4 ! 150: makeloc = install("MAKETEMP", eoa, RESERVED); ! 151: ifdefloc = install("IFDEF", eoa, RESERVED); ! 152: lenloc = install("LEN", eoa, RESERVED); ! 153: undefloc = install("UNDEFINE", eoa, RESERVED); ! 154: shiftloc = install("SHIFT", eoa, RESERVED); ! 155: cqloc = install("CHANGEQUOTE", eoa, RESERVED); ! 156: defloc = install("DEFINE", eoa, RESERVED); ! 157: evaloc = install("EVAL", eoa, RESERVED); ! 158: inclloc = install("INCLUDE", eoa, RESERVED); ! 159: sinclloc = install("SINCLUDE", eoa, RESERVED); ! 160: syscmdloc = install("SYSCMD", eoa, RESERVED); ! 161: dumploc = install("DUMPDEF", eoa, RESERVED); ! 162: errploc = install("ERRPRINT", eoa, RESERVED); ! 163: incrloc = install("INCR", eoa, RESERVED); ! 164: substrloc = install("SUBSTR", eoa, RESERVED); ! 165: indexloc = install("INDEX", eoa, RESERVED); ! 166: transloc = install("TRANSLIT", eoa, RESERVED); ! 167: ifloc = install("IFELSE", eoa, RESERVED); ! 168: divloc = install("DIVERT", eoa, RESERVED); ! 169: divnumloc = install("DIVNUM", eoa, RESERVED); ! 170: undivloc = install("UNDIVERT", eoa, RESERVED); ! 171: dnlloc = install("DNL", eoa, RESERVED); ! 172: #endif ! 173: ! 174: #ifndef M4 ! 175: makeloc = install("maketemp", eoa, RESERVED); ! 176: ifdefloc = install("ifdef", eoa, RESERVED); ! 177: lenloc = install("len", eoa, RESERVED); ! 178: undefloc = install("undefine", eoa, RESERVED); ! 179: shiftloc = install("shift", eoa, RESERVED); ! 180: cqloc = install("changequote", eoa, RESERVED); ! 181: defloc = install("define", eoa, RESERVED); ! 182: evaloc = install("eval", eoa, RESERVED); ! 183: inclloc = install("include", eoa, RESERVED); ! 184: sinclloc = install("sinclude", eoa, RESERVED); ! 185: syscmdloc = install("syscmd", eoa, RESERVED); ! 186: dumploc = install("dumpdef", eoa, RESERVED); ! 187: errploc = install("errprint", eoa, RESERVED); ! 188: incrloc = install("incr", eoa, RESERVED); ! 189: substrloc = install("substr", eoa, RESERVED); ! 190: indexloc = install("index", eoa, RESERVED); ! 191: transloc = install("translit", eoa, RESERVED); ! 192: ifloc = install("ifelse", eoa, RESERVED); ! 193: divloc = install("divert", eoa, RESERVED); ! 194: divnumloc = install("divnum", eoa, RESERVED); ! 195: undivloc = install("undivert", eoa, RESERVED); ! 196: dnlloc = install("dnl", eoa, RESERVED); ! 197: #endif ! 198: ap = argstk; ! 199: #ifndef gcos ! 200: if (signal(SIGHUP, SIG_IGN) != SIG_IGN) ! 201: signal(SIGHUP, catchsig); ! 202: if (signal(SIGINT, SIG_IGN) != SIG_IGN) ! 203: signal(SIGINT, catchsig); ! 204: tempname = mktemp("/tmp/m4aXXXXX"); ! 205: close(creat(tempname, 0)); ! 206: #endif ! 207: #ifdef gcos ! 208: tempname = "m4.tempa"; ! 209: #endif ! 210: if (argc>1) ! 211: putbak(0); ! 212: for (;;) { ! 213: tp = token; ! 214: *tp++ = t = getchr(); ! 215: *tp = EOS; ! 216: if (t<=0) { ! 217: if (infptr > 0) { ! 218: fclose(infile[infptr]); ! 219: infptr--; ! 220: cur_ip = ip_stk[infptr]; ! 221: continue; ! 222: } ! 223: if (argc<=1) ! 224: break; ! 225: argc--; ! 226: argv++; ! 227: if (infile[infptr]!=stdin) ! 228: fclose(infile[infptr]); ! 229: if (**argv=='-') ! 230: infile[infptr] = stdin; ! 231: else if ((infile[infptr]=fopen(argv[0], READ))==ERROR) { ! 232: fprintf(stderr, "m4: file not found: %s\n", argv[0]); ! 233: delexit(); ! 234: } ! 235: continue; ! 236: } ! 237: if (type[t]==ALPH) { ! 238: while ((t=type[*tp++=getchr()])==ALPH||t==DIG); ! 239: putbak(*--tp); ! 240: *tp = EOS; ! 241: if (*ap = lookup(token)->def) { ! 242: if (++ap >= &argstk[STACKS]) { ! 243: fprintf(stderr, "m4: arg stack overflow\n"); ! 244: delexit(); ! 245: } ! 246: if (cp==NULL) ! 247: cp = callst; ! 248: else if (++cp > &callst[STACKS]) { ! 249: fprintf(stderr, "m4: call stack overflow\n"); ! 250: delexit(); ! 251: } ! 252: cp->argp = ap; ! 253: *ap++ = op; ! 254: puttok(); ! 255: *op++ = '\0'; ! 256: t = getchr(); ! 257: putbak(t); ! 258: if (t!=LPAR) { ! 259: /* if (t!=' ' && t!='\t') */ ! 260: putbak(')'); ! 261: putbak('('); ! 262: } ! 263: else /* try to fix arg count */ ! 264: *ap++ = op; ! 265: cp->plev = 0; ! 266: } else ! 267: puttok(); ! 268: } else if (t==lquote) { ! 269: i = 1; ! 270: for (;;) { ! 271: t = getchr(); ! 272: if (t==rquote) { ! 273: i--; ! 274: if (i==0) ! 275: break; ! 276: } else if (t==lquote) ! 277: i++; ! 278: else if (t<0) { ! 279: fprintf(stderr, "m4: EOF in string\n"); ! 280: delexit(); ! 281: } ! 282: putchr(t); ! 283: } ! 284: } else if (t==COMMENT) { ! 285: putbak(t); ! 286: while ((t = getchr())!='\n'&& t>=0) ! 287: if (cp==NULL) ! 288: putchr(t); ! 289: putbak(t); ! 290: } else if (cp==NULL) { ! 291: puttok(); ! 292: } else if (t==LPAR) { ! 293: if (cp->plev) ! 294: *op++ = t; ! 295: cp->plev++; ! 296: while ( (t=getchr())==' ' || t=='\t' || t=='\n') ! 297: ; /* skip leading white space during arg collection */ ! 298: putbak(t); ! 299: /* ! 300: } else if (t==' ' || t=='\t' || t=='\n') { ! 301: continue; ! 302: */ ! 303: } else if (t==RPAR) { ! 304: cp->plev--; ! 305: if (cp->plev==0) { ! 306: *op++ = '\0'; ! 307: expand(cp->argp, ap-cp->argp-1); ! 308: op = *cp->argp; ! 309: ap = cp->argp-1; ! 310: cp--; ! 311: if (cp < callst) ! 312: cp = NULL; ! 313: } else ! 314: *op++ = t; ! 315: } else if (t==COMMA && cp->plev<=1) { ! 316: *op++ = '\0'; ! 317: *ap++ = op; ! 318: while ((t=getchr())==' ' || t=='\t' || t=='\n') ! 319: ; /* skip leading white space during arg collection */ ! 320: putbak(t); ! 321: } else ! 322: *op++ = t; ! 323: } ! 324: if (cp!=NULL) { ! 325: fprintf(stderr, "m4: unexpected EOF\n"); ! 326: delexit(); ! 327: } ! 328: okret = 1; ! 329: delexit(); ! 330: } ! 331: ! 332: catchsig() ! 333: { ! 334: okret = 0; ! 335: delexit(); ! 336: } ! 337: ! 338: delexit() ! 339: { ! 340: register FILE *fp; ! 341: register i, c; ! 342: ! 343: if (!okret) { ! 344: signal(SIGHUP, SIG_IGN); ! 345: signal(SIGINT, SIG_IGN); ! 346: } ! 347: for (i=1; i<10; i++) { ! 348: if (olist[i]==NULL) ! 349: continue; ! 350: fclose(olist[i]); ! 351: tempname[7] = 'a'+i; ! 352: if (okret) { ! 353: fp = fopen(tempname, READ); ! 354: while ((c = getc(fp)) > 0) ! 355: putchar(c); ! 356: fclose(fp); ! 357: } ! 358: unlink(tempname); ! 359: } ! 360: tempname[7] = 'a'; ! 361: unlink(tempname); ! 362: exit(1-okret); ! 363: } ! 364: ! 365: puttok() ! 366: { ! 367: register char *tp; ! 368: ! 369: tp = token; ! 370: if (cp) { ! 371: if (op >= &obuf[SAVS]) { ! 372: fprintf(stderr, "m4: argument overflow\n"); ! 373: delexit(); ! 374: } ! 375: while (*tp) ! 376: *op++ = *tp++; ! 377: } else if (curfile) ! 378: while (*tp) ! 379: putc(*tp++, curfile); ! 380: } ! 381: ! 382: pbstr(str) ! 383: register char *str; ! 384: { ! 385: register char *p; ! 386: ! 387: p = str; ! 388: while (*p++); ! 389: --p; ! 390: if (ip >= &ibuf[SAVS]) { ! 391: fprintf(stderr, "m4: pushback overflow\n"); ! 392: delexit(); ! 393: } ! 394: while (p > str) ! 395: putbak(*--p); ! 396: } ! 397: ! 398: expand(a1, c) ! 399: register char **a1; ! 400: { ! 401: register char *dp; ! 402: register n; ! 403: ! 404: dp = a1[-1]; ! 405: if (dp==defloc) ! 406: dodef(a1, c); ! 407: else if (dp==evaloc) ! 408: doeval(a1, c); ! 409: else if (dp==inclloc) ! 410: doincl(a1, c, 1); ! 411: else if (dp==sinclloc) ! 412: doincl(a1, c, 0); ! 413: else if (dp==makeloc) ! 414: domake(a1, c); ! 415: else if (dp==syscmdloc) ! 416: dosyscmd(a1, c); ! 417: else if (dp==incrloc) ! 418: doincr(a1, c); ! 419: else if (dp==substrloc) ! 420: dosubstr(a1, c); ! 421: else if (dp==indexloc) ! 422: doindex(a1, c); ! 423: else if (dp==transloc) ! 424: dotransl(a1, c); ! 425: else if (dp==ifloc) ! 426: doif(a1, c); ! 427: else if (dp==divloc) ! 428: dodiv(a1, c); ! 429: else if (dp==divnumloc) ! 430: dodivnum(a1, c); ! 431: else if (dp==undivloc) ! 432: doundiv(a1, c); ! 433: else if (dp==dnlloc) ! 434: dodnl(a1, c); ! 435: else if (dp==dumploc) ! 436: dodump(a1, c); ! 437: else if (dp==errploc) ! 438: doerrp(a1, c); ! 439: else if (dp==lenloc) ! 440: dolen(a1, c); ! 441: else if (dp==ifdefloc) ! 442: doifdef(a1, c); ! 443: else if (dp==undefloc) ! 444: doundef(a1, c); ! 445: else if (dp==shiftloc) ! 446: doshift(a1, c); ! 447: else if (dp==cqloc) ! 448: docq(a1, c); ! 449: else { ! 450: while (*dp++); ! 451: for (dp--; dp>a1[-1]; ) { ! 452: if (--dp>a1[-1] && dp[-1]=='$') { ! 453: n = *dp-'0'; ! 454: if (n>=0 && n<=9) { ! 455: if (n <= c) ! 456: pbstr(a1[n]); ! 457: dp--; ! 458: } else ! 459: putbak(*dp); ! 460: } else ! 461: putbak(*dp); ! 462: } ! 463: } ! 464: } ! 465: ! 466: struct nlist *lookup(str) ! 467: char *str; ! 468: { ! 469: register char *s1, *s2; ! 470: register struct nlist *np; ! 471: static struct nlist nodef; ! 472: ! 473: s1 = str; ! 474: for (hshval = 0; *s1; ) ! 475: hshval += *s1++; ! 476: hshval %= HSHSIZ; ! 477: for (np = hshtab[hshval]; np!=NULL; np = np->next) { ! 478: s1 = str; ! 479: s2 = np->name; ! 480: while (*s1++ == *s2) ! 481: if (*s2++ == EOS) ! 482: return(np); ! 483: } ! 484: return(&nodef); ! 485: } ! 486: ! 487: char *install(nam, val, flag) ! 488: char *nam, *val; ! 489: char flag; ! 490: { ! 491: register struct nlist *np; ! 492: ! 493: if ((np = lookup(nam))->name == NULL) { ! 494: np = (struct nlist *)malloc(sizeof(*np)); ! 495: if (np == NULL) { ! 496: fprintf(stderr, "m4: no space for alloc\n"); ! 497: exit(1); ! 498: } ! 499: np->name = copy(nam); ! 500: np->def = copy(val); ! 501: np->next = hshtab[hshval]; ! 502: np->flag = flag; ! 503: hshtab[hshval] = np; ! 504: return(np->def); ! 505: } ! 506: free(np->def); ! 507: np->flag = flag; ! 508: np->def = copy(val); ! 509: return(np->def); ! 510: } ! 511: ! 512: doundef(ap, c) ! 513: char **ap; ! 514: { ! 515: register struct nlist *np, *tnp; ! 516: ! 517: if (c < 1 || (np = lookup(ap[1]))->name == NULL) ! 518: return; ! 519: tnp = hshtab[hshval]; /* lookup sets hshval */ ! 520: if (tnp == np) /* it's in first place */ ! 521: hshtab[hshval] = np->next; ! 522: else { ! 523: for ( ; tnp->next != np; tnp = tnp->next) ! 524: ; ! 525: tnp->next = np->next; ! 526: } ! 527: /* ! 528: * If this is a reserved word, it has been removed from the ! 529: * hastable. We do not want to actually free the space because ! 530: * of the code in expand. Expand wants to to pointer compairs ! 531: * to tell if this is a reserved word (e.g a special action ! 532: * needs to take place). Thus if we do not free the space, ! 533: * expand will still work, but the name will never be found ! 534: * because it out of the symbol table! ! 535: */ ! 536: if (np->flag&RESERVED == 0) { /* If not reserved free it */ ! 537: free(np->name); ! 538: free(np->def); ! 539: free((char *)np); ! 540: } ! 541: } ! 542: ! 543: char *copy(s) ! 544: register char *s; ! 545: { ! 546: register char *p, *s1; ! 547: ! 548: p = s1 = malloc((unsigned)strlen(s)+1); ! 549: if (p == NULL) { ! 550: fprintf(stderr, "m4: no space for alloc\n"); ! 551: exit(1); ! 552: } ! 553: while (*s1++ = *s++); ! 554: return(p); ! 555: } ! 556: ! 557: dodef(ap, c) ! 558: char **ap; ! 559: { ! 560: if (c >= 2) { ! 561: if (strcmp(ap[1], ap[2]) == 0) { ! 562: fprintf(stderr, "m4: %s defined as itself\n", ap[1]); ! 563: delexit(); ! 564: } ! 565: install(ap[1], ap[2], 0); ! 566: } ! 567: else if (c == 1) ! 568: install(ap[1], "", 0); ! 569: } ! 570: ! 571: doifdef(ap, c) ! 572: char **ap; ! 573: { ! 574: register struct nlist *np; ! 575: ! 576: if (c < 2) ! 577: return; ! 578: if (lookup(ap[1])->name != NULL) ! 579: pbstr(ap[2]); ! 580: else if (c >= 3) ! 581: pbstr(ap[3]); ! 582: } ! 583: ! 584: dolen(ap, c) ! 585: char **ap; ! 586: { ! 587: putnum((long) strlen(ap[1])); ! 588: } ! 589: ! 590: docq(ap, c) ! 591: char **ap; ! 592: { ! 593: if (c > 1) { ! 594: lquote = *ap[1]; ! 595: rquote = *ap[2]; ! 596: } else if (c == 1) { ! 597: lquote = rquote = *ap[1]; ! 598: } else { ! 599: #ifndef M4 ! 600: lquote = GRAVE; ! 601: rquote = ACUTE; ! 602: #endif ! 603: #ifdef M4 ! 604: lquote = LBRAK; ! 605: rquote = RBRAK; ! 606: #endif ! 607: } ! 608: } ! 609: ! 610: doshift(ap, c) ! 611: char **ap; ! 612: { ! 613: fprintf(stderr, "m4: shift not yet implemented\n"); ! 614: } ! 615: ! 616: dodump(ap, c) ! 617: char **ap; ! 618: { ! 619: int i; ! 620: register struct nlist *np; ! 621: ! 622: if (c > 0) ! 623: while (c--) { ! 624: if ((np = lookup(*++ap))->name != NULL) ! 625: fprintf(stderr, "`%s' `%s'\n", np->name, np->def); ! 626: } ! 627: else ! 628: for (i=0; i<HSHSIZ; i++) ! 629: for (np=hshtab[i]; np!=NULL; np=np->next) ! 630: fprintf(stderr, "`%s' `%s'\n", np->name, np->def); ! 631: } ! 632: ! 633: doerrp(ap, c) ! 634: char **ap; ! 635: { ! 636: if (c > 0) { ! 637: fprintf(stderr, ap[1], ap[2], ap[3], ap[4], ap[5], ap[6]); ! 638: fprintf(stderr, "\n"); ! 639: } ! 640: } ! 641: ! 642: ! 643: long evalval; /* return value from yacc stuff */ ! 644: char *pe; /* used by grammar */ ! 645: ! 646: doeval(ap, c) ! 647: char **ap; ! 648: { ! 649: ! 650: if (c > 0) { ! 651: pe = ap[1]; ! 652: if (yyparse() == 0) ! 653: putnum(evalval); ! 654: else ! 655: fprintf(stderr, "m4: invalid expression in eval: %s\n", ap[1]); ! 656: } ! 657: } ! 658: ! 659: doincl(ap, c, noisy) ! 660: char **ap; ! 661: { ! 662: if (c > 0 && strlen(ap[1]) > 0) { ! 663: infptr++; ! 664: ip_stk[infptr] = cur_ip = ip; ! 665: if ((infile[infptr] = fopen(ap[1], READ))==ERROR) { ! 666: if (noisy) { ! 667: fprintf(stderr, "m4: file not found: %s\n", ap[1]); ! 668: delexit(); ! 669: } ! 670: else ! 671: infptr--; ! 672: } ! 673: } ! 674: } ! 675: ! 676: dosyscmd(ap, c) ! 677: char **ap; ! 678: { ! 679: if (c > 0) ! 680: system(ap[1]); ! 681: } ! 682: ! 683: domake(ap, c) ! 684: char **ap; ! 685: { ! 686: if (c > 0) ! 687: pbstr(mktemp(ap[1])); ! 688: } ! 689: ! 690: doincr(ap, c) ! 691: char **ap; ! 692: { ! 693: if (c >= 1) ! 694: putnum(ctol(ap[1])+1); ! 695: } ! 696: ! 697: putnum(num) ! 698: long num; ! 699: { ! 700: register sign; ! 701: ! 702: sign = (num < 0) ? '-' : '\0'; ! 703: if (num < 0) ! 704: num = -num; ! 705: do { ! 706: putbak(num%10+'0'); ! 707: num = num/10; ! 708: } while (num!=0); ! 709: if (sign == '-') ! 710: putbak('-'); ! 711: } ! 712: ! 713: dosubstr(ap, c) ! 714: char **ap; ! 715: { ! 716: int nc; ! 717: register char *sp, *fc; ! 718: ! 719: if (c<2) ! 720: return; ! 721: if (c<3) ! 722: nc = TOKS; ! 723: else ! 724: nc = ctoi(ap[3]); ! 725: fc = ap[1] + max(0, min(ctoi(ap[2]), strlen(ap[1]))); ! 726: sp = fc + min(nc, strlen(fc)); ! 727: while (sp > fc) ! 728: putbak(*--sp); ! 729: } ! 730: ! 731: doindex(ap, c) ! 732: char **ap; ! 733: { ! 734: if (c >= 2) ! 735: putnum((long) strindex(ap[1], ap[2])); ! 736: } ! 737: ! 738: strindex(p1, p2) ! 739: char *p1, *p2; ! 740: { ! 741: register m; ! 742: register char *s, *t, *p; ! 743: ! 744: for (p=p1; *p; p++) { ! 745: s = p; ! 746: m = 1; ! 747: for (t=p2; *t; ) ! 748: if (*t++ != *s++) ! 749: m = 0; ! 750: if (m == 1) ! 751: return(p-p1); ! 752: } ! 753: return(-1); ! 754: } ! 755: ! 756: dotransl(ap, c) ! 757: char **ap; ! 758: { ! 759: register char *s, *fr, *to; ! 760: ! 761: if (c <= 1) return; ! 762: ! 763: if (c == 2) { ! 764: register int i; ! 765: to = ap[1]; ! 766: for (s = ap[1]; *s; s++) { ! 767: i = 0; ! 768: for (fr = ap[2]; *fr; fr++) ! 769: if (*s == *fr) { ! 770: i++; ! 771: break; ! 772: } ! 773: if (i == 0) ! 774: *to++ = *s; ! 775: } ! 776: *to = '\0'; ! 777: } ! 778: ! 779: if (c >= 3) { ! 780: for (s = ap[1]; *s; s++) ! 781: for (fr = ap[2], to = ap[3]; *fr && *to; fr++, to++) ! 782: if (*s == *fr) ! 783: *s = *to; ! 784: } ! 785: ! 786: pbstr(ap[1]); ! 787: } ! 788: ! 789: doif(ap, c) ! 790: register char **ap; ! 791: { ! 792: if (c < 3) ! 793: return; ! 794: while (c >= 3) { ! 795: if (strcmp(ap[1], ap[2]) == 0) { ! 796: pbstr(ap[3]); ! 797: return; ! 798: } ! 799: c -= 3; ! 800: ap += 3; ! 801: } ! 802: if (c > 0) ! 803: pbstr(ap[1]); ! 804: } ! 805: ! 806: dodiv(ap, c) ! 807: register char **ap; ! 808: { ! 809: register int f; ! 810: ! 811: if (c<1) ! 812: f = 0; ! 813: else ! 814: f = ctoi(ap[1]); ! 815: if (f>=10 || f<0) { ! 816: curfile = NULL; ! 817: return; ! 818: } ! 819: tempname[7] = 'a' + f; ! 820: if (olist[f] || (olist[f]=fopen(tempname, WRITE))) { ! 821: curout = f; ! 822: curfile = olist[f]; ! 823: } ! 824: } ! 825: ! 826: doundiv(ap, c) ! 827: char **ap; ! 828: { ! 829: register FILE *fp; ! 830: register int i, ch; ! 831: int j; ! 832: ! 833: if (c == 0) { ! 834: for (i=1; i<10; i++) { ! 835: if (i==curout || olist[i]==NULL) ! 836: continue; ! 837: fclose(olist[i]); ! 838: tempname[7] = 'a'+i; ! 839: fp = fopen(tempname, READ); ! 840: if (curfile != NULL) ! 841: while ((ch = getc(fp)) > 0) ! 842: putc(ch, curfile); ! 843: fclose(fp); ! 844: unlink(tempname); ! 845: olist[i] = NULL; ! 846: } ! 847: ! 848: } ! 849: else { ! 850: for (j = 1; j <= c; j++) { ! 851: i = ctoi(*++ap); ! 852: if (i<1 || i>9 || i==curout || olist[i]==NULL) ! 853: continue; ! 854: fclose(olist[i]); ! 855: tempname[7] = 'a'+i; ! 856: fp = fopen(tempname, READ); ! 857: if (curfile != NULL) ! 858: while ((ch = getc(fp)) > 0) ! 859: putc(ch, curfile); ! 860: fclose(fp); ! 861: unlink(tempname); ! 862: olist[i] = NULL; ! 863: } ! 864: } ! 865: } ! 866: ! 867: dodivnum(ap, c) ! 868: char **ap; ! 869: { ! 870: putnum((long) curout); ! 871: } ! 872: ! 873: dodnl(ap, c) ! 874: char **ap; ! 875: { ! 876: register t; ! 877: ! 878: while ((t=getchr())!='\n' && t>=0) ! 879: ; ! 880: } ! 881: ! 882: long ctol(str) ! 883: register char *str; ! 884: { ! 885: register sign; ! 886: long num; ! 887: ! 888: while (*str==' ' || *str=='\t' || *str=='\n') ! 889: str++; ! 890: num = 0; ! 891: if (*str == '-') { ! 892: sign = -1; ! 893: str++; ! 894: } ! 895: else ! 896: sign = 1; ! 897: while (*str>='0' && *str<='9') ! 898: num = num*10 + *str++ - '0'; ! 899: return(sign * num); ! 900: } ! 901: ! 902: ctoi(s) ! 903: char *s; ! 904: { ! 905: return(ctol(s)); ! 906: } ! 907: ! 908: min(a, b) ! 909: { ! 910: if (a>b) ! 911: return(b); ! 912: return(a); ! 913: } ! 914: ! 915: max(a, b) ! 916: { ! 917: if (a>b) ! 918: return(a); ! 919: return(b); ! 920: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.