19b50d902SRodney W. Grimes /*- 29b50d902SRodney W. Grimes * Copyright (c) 1989, 1993 39b50d902SRodney W. Grimes * The Regents of the University of California. All rights reserved. 49b50d902SRodney W. Grimes * 59b50d902SRodney W. Grimes * This code is derived from software contributed to Berkeley by 69b50d902SRodney W. Grimes * Ozan Yigit at York University. 79b50d902SRodney W. Grimes * 89b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 99b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions 109b50d902SRodney W. Grimes * are met: 119b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 129b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 139b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 149b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 159b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution. 169b50d902SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 179b50d902SRodney W. Grimes * must display the following acknowledgement: 189b50d902SRodney W. Grimes * This product includes software developed by the University of 199b50d902SRodney W. Grimes * California, Berkeley and its contributors. 209b50d902SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 219b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software 229b50d902SRodney W. Grimes * without specific prior written permission. 239b50d902SRodney W. Grimes * 249b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 259b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 269b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 279b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 289b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 299b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 309b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 319b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 329b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 339b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 349b50d902SRodney W. Grimes * SUCH DAMAGE. 359b50d902SRodney W. Grimes */ 369b50d902SRodney W. Grimes 379b50d902SRodney W. Grimes #ifndef lint 3895105358SPhilippe Charnier static const char copyright[] = 399b50d902SRodney W. Grimes "@(#) Copyright (c) 1989, 1993\n\ 409b50d902SRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 419b50d902SRodney W. Grimes #endif /* not lint */ 429b50d902SRodney W. Grimes 439b50d902SRodney W. Grimes #ifndef lint 4495105358SPhilippe Charnier #if 0 459b50d902SRodney W. Grimes static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93"; 4695105358SPhilippe Charnier #endif 4795105358SPhilippe Charnier static const char rcsid[] = 4895105358SPhilippe Charnier "$Id$"; 499b50d902SRodney W. Grimes #endif /* not lint */ 509b50d902SRodney W. Grimes 519b50d902SRodney W. Grimes /* 529b50d902SRodney W. Grimes * main.c 539b50d902SRodney W. Grimes * Facility: m4 macro processor 549b50d902SRodney W. Grimes * by: oz 559b50d902SRodney W. Grimes */ 569b50d902SRodney W. Grimes 579b50d902SRodney W. Grimes #include <sys/types.h> 589b50d902SRodney W. Grimes #include <ctype.h> 5995105358SPhilippe Charnier #include <err.h> 6095105358SPhilippe Charnier #include <signal.h> 6195105358SPhilippe Charnier #include <stdio.h> 629b50d902SRodney W. Grimes #include <string.h> 6395105358SPhilippe Charnier #include <unistd.h> 649b50d902SRodney W. Grimes #include "mdef.h" 659b50d902SRodney W. Grimes #include "stdd.h" 669b50d902SRodney W. Grimes #include "extern.h" 679b50d902SRodney W. Grimes #include "pathnames.h" 689b50d902SRodney W. Grimes 699b50d902SRodney W. Grimes ndptr hashtab[HASHSIZE]; /* hash table for macros etc. */ 707c5eeb39SAndrey A. Chernov unsigned char buf[BUFSIZE]; /* push-back buffer */ 717c5eeb39SAndrey A. Chernov unsigned char *bufbase = buf; /* the base for current ilevel */ 727c5eeb39SAndrey A. Chernov unsigned char *bbase[MAXINP]; /* the base for each ilevel */ 737c5eeb39SAndrey A. Chernov unsigned char *bp = buf; /* first available character */ 747c5eeb39SAndrey A. Chernov unsigned char *endpbb = buf+BUFSIZE; /* end of push-back buffer */ 759b50d902SRodney W. Grimes stae mstack[STACKMAX+1]; /* stack of m4 machine */ 769b50d902SRodney W. Grimes char strspace[STRSPMAX+1]; /* string space for evaluation */ 779b50d902SRodney W. Grimes char *ep = strspace; /* first free char in strspace */ 789b50d902SRodney W. Grimes char *endest= strspace+STRSPMAX;/* end of string space */ 799b50d902SRodney W. Grimes int sp; /* current m4 stack pointer */ 809b50d902SRodney W. Grimes int fp; /* m4 call frame pointer */ 819b50d902SRodney W. Grimes FILE *infile[MAXINP]; /* input file stack (0=stdin) */ 829b50d902SRodney W. Grimes FILE *outfile[MAXOUT]; /* diversion array(0=bitbucket)*/ 839b50d902SRodney W. Grimes FILE *active; /* active output file pointer */ 849b50d902SRodney W. Grimes char *m4temp; /* filename for diversions */ 859b50d902SRodney W. Grimes int ilevel = 0; /* input file stack pointer */ 869b50d902SRodney W. Grimes int oindex = 0; /* diversion index.. */ 879b50d902SRodney W. Grimes char *null = ""; /* as it says.. just a null.. */ 889b50d902SRodney W. Grimes char *m4wraps = ""; /* m4wrap string default.. */ 899b50d902SRodney W. Grimes char lquote = LQUOTE; /* left quote character (`) */ 909b50d902SRodney W. Grimes char rquote = RQUOTE; /* right quote character (') */ 919b50d902SRodney W. Grimes char scommt = SCOMMT; /* start character for comment */ 929b50d902SRodney W. Grimes char ecommt = ECOMMT; /* end character for comment */ 939b50d902SRodney W. Grimes 949b50d902SRodney W. Grimes struct keyblk keywrds[] = { /* m4 keywords to be installed */ 959b50d902SRodney W. Grimes "include", INCLTYPE, 969b50d902SRodney W. Grimes "sinclude", SINCTYPE, 979b50d902SRodney W. Grimes "define", DEFITYPE, 989b50d902SRodney W. Grimes "defn", DEFNTYPE, 999b50d902SRodney W. Grimes "divert", DIVRTYPE, 1009b50d902SRodney W. Grimes "expr", EXPRTYPE, 1019b50d902SRodney W. Grimes "eval", EXPRTYPE, 1029b50d902SRodney W. Grimes "substr", SUBSTYPE, 1039b50d902SRodney W. Grimes "ifelse", IFELTYPE, 1049b50d902SRodney W. Grimes "ifdef", IFDFTYPE, 1059b50d902SRodney W. Grimes "len", LENGTYPE, 1069b50d902SRodney W. Grimes "incr", INCRTYPE, 1079b50d902SRodney W. Grimes "decr", DECRTYPE, 1089b50d902SRodney W. Grimes "dnl", DNLNTYPE, 1099b50d902SRodney W. Grimes "changequote", CHNQTYPE, 1109b50d902SRodney W. Grimes "changecom", CHNCTYPE, 1119b50d902SRodney W. Grimes "index", INDXTYPE, 1129b50d902SRodney W. Grimes #ifdef EXTENDED 1139b50d902SRodney W. Grimes "paste", PASTTYPE, 1149b50d902SRodney W. Grimes "spaste", SPASTYPE, 1159b50d902SRodney W. Grimes #endif 1169b50d902SRodney W. Grimes "popdef", POPDTYPE, 1179b50d902SRodney W. Grimes "pushdef", PUSDTYPE, 1189b50d902SRodney W. Grimes "dumpdef", DUMPTYPE, 1199b50d902SRodney W. Grimes "shift", SHIFTYPE, 1209b50d902SRodney W. Grimes "translit", TRNLTYPE, 1219b50d902SRodney W. Grimes "undefine", UNDFTYPE, 1229b50d902SRodney W. Grimes "undivert", UNDVTYPE, 1239b50d902SRodney W. Grimes "divnum", DIVNTYPE, 1249b50d902SRodney W. Grimes "maketemp", MKTMTYPE, 1259b50d902SRodney W. Grimes "errprint", ERRPTYPE, 1269b50d902SRodney W. Grimes "m4wrap", M4WRTYPE, 1279b50d902SRodney W. Grimes "m4exit", EXITTYPE, 1289b50d902SRodney W. Grimes "syscmd", SYSCTYPE, 1299b50d902SRodney W. Grimes "sysval", SYSVTYPE, 1309b50d902SRodney W. Grimes 1319b50d902SRodney W. Grimes #ifdef unix 1329b50d902SRodney W. Grimes "unix", MACRTYPE, 1339b50d902SRodney W. Grimes #else 1349b50d902SRodney W. Grimes #ifdef vms 1359b50d902SRodney W. Grimes "vms", MACRTYPE, 1369b50d902SRodney W. Grimes #endif 1379b50d902SRodney W. Grimes #endif 1389b50d902SRodney W. Grimes }; 1399b50d902SRodney W. Grimes 1409b50d902SRodney W. Grimes #define MAXKEYS (sizeof(keywrds)/sizeof(struct keyblk)) 1419b50d902SRodney W. Grimes 1429b50d902SRodney W. Grimes extern int optind; 1439b50d902SRodney W. Grimes extern char *optarg; 1449b50d902SRodney W. Grimes 1459b50d902SRodney W. Grimes void macro(); 1469b50d902SRodney W. Grimes void initkwds(); 1479b50d902SRodney W. Grimes extern int getopt(); 1489b50d902SRodney W. Grimes 1499b50d902SRodney W. Grimes int 1509b50d902SRodney W. Grimes main(argc,argv) 1519b50d902SRodney W. Grimes int argc; 1529b50d902SRodney W. Grimes char *argv[]; 1539b50d902SRodney W. Grimes { 1549b50d902SRodney W. Grimes register int c; 1559b50d902SRodney W. Grimes register int n; 1569b50d902SRodney W. Grimes char *p; 1579b50d902SRodney W. Grimes register FILE *ifp; 1589b50d902SRodney W. Grimes 1599b50d902SRodney W. Grimes if (signal(SIGINT, SIG_IGN) != SIG_IGN) 1609b50d902SRodney W. Grimes signal(SIGINT, onintr); 1619b50d902SRodney W. Grimes 1629b50d902SRodney W. Grimes initkwds(); 1639b50d902SRodney W. Grimes 1641c8af878SWarner Losh while ((c = getopt(argc, argv, "tD:U:o:")) != -1) 1659b50d902SRodney W. Grimes switch(c) { 1669b50d902SRodney W. Grimes 1679b50d902SRodney W. Grimes case 'D': /* define something..*/ 1689b50d902SRodney W. Grimes for (p = optarg; *p; p++) 1699b50d902SRodney W. Grimes if (*p == '=') 1709b50d902SRodney W. Grimes break; 1719b50d902SRodney W. Grimes if (*p) 1729b50d902SRodney W. Grimes *p++ = EOS; 1739b50d902SRodney W. Grimes dodefine(optarg, p); 1749b50d902SRodney W. Grimes break; 1759b50d902SRodney W. Grimes case 'U': /* undefine... */ 1769b50d902SRodney W. Grimes remhash(optarg, TOP); 1779b50d902SRodney W. Grimes break; 1789b50d902SRodney W. Grimes case 'o': /* specific output */ 1799b50d902SRodney W. Grimes case '?': 1809b50d902SRodney W. Grimes usage(); 1819b50d902SRodney W. Grimes } 1829b50d902SRodney W. Grimes 1839b50d902SRodney W. Grimes argc -= optind; 1849b50d902SRodney W. Grimes argv += optind; 1859b50d902SRodney W. Grimes 1869b50d902SRodney W. Grimes active = stdout; /* default active output */ 1879b50d902SRodney W. Grimes /* filename for diversions */ 1889b50d902SRodney W. Grimes m4temp = mktemp(xstrdup(_PATH_DIVNAME)); 1899b50d902SRodney W. Grimes 1909b50d902SRodney W. Grimes bbase[0] = bufbase; 1919b50d902SRodney W. Grimes if (!argc) { 1929b50d902SRodney W. Grimes sp = -1; /* stack pointer initialized */ 1939b50d902SRodney W. Grimes fp = 0; /* frame pointer initialized */ 1949b50d902SRodney W. Grimes infile[0] = stdin; /* default input (naturally) */ 1959b50d902SRodney W. Grimes macro(); 1969b50d902SRodney W. Grimes } else 1979b50d902SRodney W. Grimes for (; argc--; ++argv) { 1989b50d902SRodney W. Grimes p = *argv; 1999b50d902SRodney W. Grimes if (p[0] == '-' && p[1] == '\0') 2009b50d902SRodney W. Grimes ifp = stdin; 2019b50d902SRodney W. Grimes else if ((ifp = fopen(p, "r")) == NULL) 20295105358SPhilippe Charnier err(1, "%s", p); 2039b50d902SRodney W. Grimes sp = -1; 2049b50d902SRodney W. Grimes fp = 0; 2059b50d902SRodney W. Grimes infile[0] = ifp; 2069b50d902SRodney W. Grimes macro(); 2079b50d902SRodney W. Grimes if (ifp != stdin) 2089b50d902SRodney W. Grimes (void)fclose(ifp); 2099b50d902SRodney W. Grimes } 2109b50d902SRodney W. Grimes 2119b50d902SRodney W. Grimes if (*m4wraps) { /* anything for rundown ?? */ 2129b50d902SRodney W. Grimes ilevel = 0; /* in case m4wrap includes.. */ 2139b50d902SRodney W. Grimes bufbase = bp = buf; /* use the entire buffer */ 2149b50d902SRodney W. Grimes putback(EOF); /* eof is a must !! */ 2159b50d902SRodney W. Grimes pbstr(m4wraps); /* user-defined wrapup act */ 2169b50d902SRodney W. Grimes macro(); /* last will and testament */ 2179b50d902SRodney W. Grimes } 2189b50d902SRodney W. Grimes 2199b50d902SRodney W. Grimes if (active != stdout) 2209b50d902SRodney W. Grimes active = stdout; /* reset output just in case */ 2219b50d902SRodney W. Grimes for (n = 1; n < MAXOUT; n++) /* default wrap-up: undivert */ 2229b50d902SRodney W. Grimes if (outfile[n] != NULL) 2239b50d902SRodney W. Grimes getdiv(n); 2249b50d902SRodney W. Grimes /* remove bitbucket if used */ 2259b50d902SRodney W. Grimes if (outfile[0] != NULL) { 2269b50d902SRodney W. Grimes (void) fclose(outfile[0]); 2279b50d902SRodney W. Grimes m4temp[UNIQUE] = '0'; 2289b50d902SRodney W. Grimes #ifdef vms 2299b50d902SRodney W. Grimes (void) remove(m4temp); 2309b50d902SRodney W. Grimes #else 2319b50d902SRodney W. Grimes (void) unlink(m4temp); 2329b50d902SRodney W. Grimes #endif 2339b50d902SRodney W. Grimes } 2349b50d902SRodney W. Grimes 2359b50d902SRodney W. Grimes return 0; 2369b50d902SRodney W. Grimes } 2379b50d902SRodney W. Grimes 2389b50d902SRodney W. Grimes ndptr inspect(); 2399b50d902SRodney W. Grimes 2409b50d902SRodney W. Grimes /* 2419b50d902SRodney W. Grimes * macro - the work horse.. 2429b50d902SRodney W. Grimes */ 2439b50d902SRodney W. Grimes void 2449b50d902SRodney W. Grimes macro() { 2459b50d902SRodney W. Grimes char token[MAXTOK]; 2469b50d902SRodney W. Grimes register char *s; 2479b50d902SRodney W. Grimes register int t, l; 2489b50d902SRodney W. Grimes register ndptr p; 2499b50d902SRodney W. Grimes register int nlpar; 2509b50d902SRodney W. Grimes 2519b50d902SRodney W. Grimes cycle { 2527c5eeb39SAndrey A. Chernov if ((t = gpbc()) == '_' || (t != EOF && isalpha(t))) { 2539b50d902SRodney W. Grimes putback(t); 2549b50d902SRodney W. Grimes if ((p = inspect(s = token)) == nil) { 2559b50d902SRodney W. Grimes if (sp < 0) 2569b50d902SRodney W. Grimes while (*s) 2579b50d902SRodney W. Grimes putc(*s++, active); 2589b50d902SRodney W. Grimes else 2599b50d902SRodney W. Grimes while (*s) 2609b50d902SRodney W. Grimes chrsave(*s++); 2619b50d902SRodney W. Grimes } 2629b50d902SRodney W. Grimes else { 2639b50d902SRodney W. Grimes /* 2649b50d902SRodney W. Grimes * real thing.. First build a call frame: 2659b50d902SRodney W. Grimes */ 2669b50d902SRodney W. Grimes pushf(fp); /* previous call frm */ 2679b50d902SRodney W. Grimes pushf(p->type); /* type of the call */ 2689b50d902SRodney W. Grimes pushf(0); /* parenthesis level */ 2699b50d902SRodney W. Grimes fp = sp; /* new frame pointer */ 2709b50d902SRodney W. Grimes /* 2719b50d902SRodney W. Grimes * now push the string arguments: 2729b50d902SRodney W. Grimes */ 2739b50d902SRodney W. Grimes pushs(p->defn); /* defn string */ 2749b50d902SRodney W. Grimes pushs(p->name); /* macro name */ 2759b50d902SRodney W. Grimes pushs(ep); /* start next..*/ 2769b50d902SRodney W. Grimes 2779b50d902SRodney W. Grimes putback(l = gpbc()); 2789b50d902SRodney W. Grimes if (l != LPAREN) { /* add bracks */ 2799b50d902SRodney W. Grimes putback(RPAREN); 2809b50d902SRodney W. Grimes putback(LPAREN); 2819b50d902SRodney W. Grimes } 2829b50d902SRodney W. Grimes } 2839b50d902SRodney W. Grimes } 2849b50d902SRodney W. Grimes else if (t == EOF) { 2859b50d902SRodney W. Grimes if (sp > -1) 28695105358SPhilippe Charnier errx(1, "unexpected end of input"); 2879b50d902SRodney W. Grimes if (ilevel <= 0) 2889b50d902SRodney W. Grimes break; /* all done thanks.. */ 2899b50d902SRodney W. Grimes --ilevel; 2909b50d902SRodney W. Grimes (void) fclose(infile[ilevel+1]); 2919b50d902SRodney W. Grimes bufbase = bbase[ilevel]; 2929b50d902SRodney W. Grimes continue; 2939b50d902SRodney W. Grimes } 2949b50d902SRodney W. Grimes /* 2959b50d902SRodney W. Grimes * non-alpha single-char token seen.. 2969b50d902SRodney W. Grimes * [the order of else if .. stmts is important.] 2979b50d902SRodney W. Grimes */ 2989b50d902SRodney W. Grimes else if (t == lquote) { /* strip quotes */ 2999b50d902SRodney W. Grimes nlpar = 1; 3009b50d902SRodney W. Grimes do { 3019b50d902SRodney W. Grimes if ((l = gpbc()) == rquote) 3029b50d902SRodney W. Grimes nlpar--; 3039b50d902SRodney W. Grimes else if (l == lquote) 3049b50d902SRodney W. Grimes nlpar++; 3059b50d902SRodney W. Grimes else if (l == EOF) 30695105358SPhilippe Charnier errx(1, "missing right quote"); 3079b50d902SRodney W. Grimes if (nlpar > 0) { 3089b50d902SRodney W. Grimes if (sp < 0) 3099b50d902SRodney W. Grimes putc(l, active); 3109b50d902SRodney W. Grimes else 3119b50d902SRodney W. Grimes chrsave(l); 3129b50d902SRodney W. Grimes } 3139b50d902SRodney W. Grimes } 3149b50d902SRodney W. Grimes while (nlpar != 0); 3159b50d902SRodney W. Grimes } 3169b50d902SRodney W. Grimes 3179b50d902SRodney W. Grimes else if (sp < 0) { /* not in a macro at all */ 3189b50d902SRodney W. Grimes if (t == scommt) { /* comment handling here */ 3199b50d902SRodney W. Grimes putc(t, active); 3209b50d902SRodney W. Grimes while ((t = gpbc()) != ecommt) 3219b50d902SRodney W. Grimes putc(t, active); 3229b50d902SRodney W. Grimes } 3239b50d902SRodney W. Grimes putc(t, active); /* output directly.. */ 3249b50d902SRodney W. Grimes } 3259b50d902SRodney W. Grimes 3269b50d902SRodney W. Grimes else switch(t) { 3279b50d902SRodney W. Grimes 3289b50d902SRodney W. Grimes case LPAREN: 3299b50d902SRodney W. Grimes if (PARLEV > 0) 3309b50d902SRodney W. Grimes chrsave(t); 3317c5eeb39SAndrey A. Chernov while ((l = gpbc()) != EOF && isspace(l)) 3329b50d902SRodney W. Grimes ; /* skip blank, tab, nl.. */ 3339b50d902SRodney W. Grimes putback(l); 3349b50d902SRodney W. Grimes PARLEV++; 3359b50d902SRodney W. Grimes break; 3369b50d902SRodney W. Grimes 3379b50d902SRodney W. Grimes case RPAREN: 3389b50d902SRodney W. Grimes if (--PARLEV > 0) 3399b50d902SRodney W. Grimes chrsave(t); 3409b50d902SRodney W. Grimes else { /* end of argument list */ 3419b50d902SRodney W. Grimes chrsave(EOS); 3429b50d902SRodney W. Grimes 3439b50d902SRodney W. Grimes if (sp == STACKMAX) 34495105358SPhilippe Charnier errx(1, "internal stack overflow"); 3459b50d902SRodney W. Grimes 3469b50d902SRodney W. Grimes if (CALTYP == MACRTYPE) 3479b50d902SRodney W. Grimes expand((char **) mstack+fp+1, sp-fp); 3489b50d902SRodney W. Grimes else 3499b50d902SRodney W. Grimes eval((char **) mstack+fp+1, sp-fp, CALTYP); 3509b50d902SRodney W. Grimes 3519b50d902SRodney W. Grimes ep = PREVEP; /* flush strspace */ 3529b50d902SRodney W. Grimes sp = PREVSP; /* previous sp.. */ 3539b50d902SRodney W. Grimes fp = PREVFP; /* rewind stack...*/ 3549b50d902SRodney W. Grimes } 3559b50d902SRodney W. Grimes break; 3569b50d902SRodney W. Grimes 3579b50d902SRodney W. Grimes case COMMA: 3589b50d902SRodney W. Grimes if (PARLEV == 1) { 3599b50d902SRodney W. Grimes chrsave(EOS); /* new argument */ 3607c5eeb39SAndrey A. Chernov while ((l = gpbc()) != EOF && isspace(l)) 3619b50d902SRodney W. Grimes ; 3629b50d902SRodney W. Grimes putback(l); 3639b50d902SRodney W. Grimes pushs(ep); 3649b50d902SRodney W. Grimes } else 3659b50d902SRodney W. Grimes chrsave(t); 3669b50d902SRodney W. Grimes break; 3679b50d902SRodney W. Grimes 3689b50d902SRodney W. Grimes default: 3699b50d902SRodney W. Grimes chrsave(t); /* stack the char */ 3709b50d902SRodney W. Grimes break; 3719b50d902SRodney W. Grimes } 3729b50d902SRodney W. Grimes } 3739b50d902SRodney W. Grimes } 3749b50d902SRodney W. Grimes 3759b50d902SRodney W. Grimes /* 3769b50d902SRodney W. Grimes * build an input token.. 3779b50d902SRodney W. Grimes * consider only those starting with _ or A-Za-z. This is a 3789b50d902SRodney W. Grimes * combo with lookup to speed things up. 3799b50d902SRodney W. Grimes */ 3809b50d902SRodney W. Grimes ndptr 3819b50d902SRodney W. Grimes inspect(tp) 3829b50d902SRodney W. Grimes register char *tp; 3839b50d902SRodney W. Grimes { 3847c5eeb39SAndrey A. Chernov register int c; 3859b50d902SRodney W. Grimes register char *name = tp; 3869b50d902SRodney W. Grimes register char *etp = tp+MAXTOK; 3879b50d902SRodney W. Grimes register ndptr p; 3889b50d902SRodney W. Grimes register unsigned long h = 0; 3899b50d902SRodney W. Grimes 3907c5eeb39SAndrey A. Chernov while ((c = gpbc()) != EOF && (isalnum(c) || c == '_') && tp < etp) 3919b50d902SRodney W. Grimes h = (h << 5) + h + (*tp++ = c); 3929b50d902SRodney W. Grimes putback(c); 3939b50d902SRodney W. Grimes if (tp == etp) 39495105358SPhilippe Charnier errx(1, "token too long"); 3959b50d902SRodney W. Grimes 3969b50d902SRodney W. Grimes *tp = EOS; 3979b50d902SRodney W. Grimes 3989b50d902SRodney W. Grimes for (p = hashtab[h%HASHSIZE]; p != nil; p = p->nxtptr) 3999b50d902SRodney W. Grimes if (STREQ(name, p->name)) 4009b50d902SRodney W. Grimes break; 4019b50d902SRodney W. Grimes return p; 4029b50d902SRodney W. Grimes } 4039b50d902SRodney W. Grimes 4049b50d902SRodney W. Grimes /* 4059b50d902SRodney W. Grimes * initkwds - initialise m4 keywords as fast as possible. 4069b50d902SRodney W. Grimes * This very similar to install, but without certain overheads, 4079b50d902SRodney W. Grimes * such as calling lookup. Malloc is not used for storing the 4089b50d902SRodney W. Grimes * keyword strings, since we simply use the static pointers 4099b50d902SRodney W. Grimes * within keywrds block. 4109b50d902SRodney W. Grimes */ 4119b50d902SRodney W. Grimes void 4129b50d902SRodney W. Grimes initkwds() { 4139b50d902SRodney W. Grimes register int i; 4149b50d902SRodney W. Grimes register int h; 4159b50d902SRodney W. Grimes register ndptr p; 4169b50d902SRodney W. Grimes 4179b50d902SRodney W. Grimes for (i = 0; i < MAXKEYS; i++) { 4189b50d902SRodney W. Grimes h = hash(keywrds[i].knam); 4199b50d902SRodney W. Grimes p = (ndptr) xalloc(sizeof(struct ndblock)); 4209b50d902SRodney W. Grimes p->nxtptr = hashtab[h]; 4219b50d902SRodney W. Grimes hashtab[h] = p; 4229b50d902SRodney W. Grimes p->name = keywrds[i].knam; 4239b50d902SRodney W. Grimes p->defn = null; 4249b50d902SRodney W. Grimes p->type = keywrds[i].ktyp | STATIC; 4259b50d902SRodney W. Grimes } 4269b50d902SRodney W. Grimes } 427