123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- #include <u.h>
- #include <libc.h>
- #include <stdio.h>
- #include "cpp.h"
- extern int getopt(int, char **, char *);
- extern char *optarg;
- extern int optind;
- int verbose;
- int Mflag;
- int Cplusplus;
- int nolineinfo;
- Nlist *kwdefined;
- char wd[128];
- #define NLSIZE 128
- Nlist *nlist[NLSIZE];
- struct kwtab {
- char *kw;
- int val;
- int flag;
- } kwtab[] = {
- "if", KIF, ISKW,
- "ifdef", KIFDEF, ISKW,
- "ifndef", KIFNDEF, ISKW,
- "elif", KELIF, ISKW,
- "else", KELSE, ISKW,
- "endif", KENDIF, ISKW,
- "include", KINCLUDE, ISKW,
- "define", KDEFINE, ISKW,
- "undef", KUNDEF, ISKW,
- "line", KLINE, ISKW,
- "error", KERROR, ISKW,
- "warning", KWARNING, ISKW, // extension to ANSI
- "pragma", KPRAGMA, ISKW,
- "eval", KEVAL, ISKW,
- "defined", KDEFINED, ISDEFINED+ISUNCHANGE,
- "__LINE__", KLINENO, ISMAC+ISUNCHANGE,
- "__FILE__", KFILE, ISMAC+ISUNCHANGE,
- "__DATE__", KDATE, ISMAC+ISUNCHANGE,
- "__TIME__", KTIME, ISMAC+ISUNCHANGE,
- "__STDC__", KSTDC, ISUNCHANGE,
- NULL
- };
- unsigned long namebit[077+1];
- Nlist *np;
- void
- setup(int argc, char **argv)
- {
- struct kwtab *kp;
- Nlist *np;
- Token t;
- int fd, i;
- char *fp, *dp;
- Tokenrow tr;
- char *objtype;
- char *includeenv;
- int firstinclude;
- static char nbuf[40];
- static Token deftoken[1] = {{ NAME, 0, 0, 0, 7, (uchar*)"defined" }};
- static Tokenrow deftr = { deftoken, deftoken, deftoken+1, 1 };
- int debuginclude = 0;
- int nodot = 0;
- char xx[2] = { 0, 0};
- for (kp=kwtab; kp->kw; kp++) {
- t.t = (uchar*)kp->kw;
- t.len = strlen(kp->kw);
- np = lookup(&t, 1);
- np->flag = kp->flag;
- np->val = kp->val;
- if (np->val == KDEFINED) {
- kwdefined = np;
- np->val = NAME;
- np->vp = &deftr;
- np->ap = 0;
- }
- }
- /*
- * For Plan 9, search /objtype/include, then /sys/include
- * (Note that includelist is searched from high end to low)
- */
- if ((objtype = getenv("objtype"))){
- snprintf(nbuf, sizeof nbuf, "/%s/include", objtype);
- includelist[1].file = nbuf;
- includelist[1].always = 1;
- } else {
- includelist[1].file = NULL;
- error(WARNING, "Unknown $objtype");
- }
- if (getwd(wd, sizeof(wd))==0)
- wd[0] = '\0';
- includelist[0].file = "/sys/include";
- includelist[0].always = 1;
- firstinclude = NINCLUDE-2;
- if ((includeenv=getenv("include")) != NULL) {
- char *cp;
- includeenv = strdup(includeenv);
- for (;firstinclude>0; firstinclude--) {
- cp = strtok(includeenv, " ");
- if (cp==NULL)
- break;
- includelist[firstinclude].file = cp;
- includelist[firstinclude].always = 1;
- includeenv = NULL;
- }
- }
- setsource("", -1, 0);
- ARGBEGIN {
- case 'N':
- for (i=0; i<NINCLUDE; i++)
- if (includelist[i].always==1)
- includelist[i].deleted = 1;
- break;
- case 'I':
- for (i=firstinclude; i>=0; i--) {
- if (includelist[i].file==NULL) {
- includelist[i].always = 1;
- includelist[i].file = ARGF();
- break;
- }
- }
- if (i<0)
- error(WARNING, "Too many -I directives");
- break;
- case 'D':
- case 'U':
- setsource("<cmdarg>", -1, ARGF());
- maketokenrow(3, &tr);
- gettokens(&tr, 1);
- doadefine(&tr, ARGC());
- unsetsource();
- break;
- case 'M':
- Mflag++;
- break;
- case 'V':
- verbose++;
- break;
- case '+':
- Cplusplus++;
- break;
- case 'i':
- debuginclude++;
- break;
- case 'P':
- nolineinfo++;
- break;
- case '.':
- nodot++;
- break;
- default:
- xx[0] = ARGC();
- error(FATAL, "Unknown argument '%s'", xx);
- break;
- } ARGEND
- dp = ".";
- fp = "<stdin>";
- fd = 0;
- if (argc > 2)
- error(FATAL, "Too many file arguments; see cpp(1)");
- if (argc > 0) {
- if ((fp = strrchr(argv[0], '/')) != NULL) {
- int len = fp - argv[0];
- dp = (char*)newstring((uchar*)argv[0], len+1, 0);
- dp[len] = '\0';
- }
- fp = (char*)newstring((uchar*)argv[0], strlen(argv[0]), 0);
- if ((fd = open(fp, 0)) < 0)
- error(FATAL, "Can't open input file %s", fp);
- }
- if (argc > 1) {
- int fdo = create(argv[1], 1, 0666);
- if (fdo<0)
- error(FATAL, "Can't open output file %s", argv[1]);
- dup(fdo, 1);
- }
- if (Mflag)
- setobjname(fp);
- includelist[NINCLUDE-1].always = 0;
- includelist[NINCLUDE-1].file = dp;
- if(nodot)
- includelist[NINCLUDE-1].deleted = 1;
- setsource(fp, fd, NULL);
- if (debuginclude) {
- for (i=0; i<NINCLUDE; i++)
- if (includelist[i].file && includelist[i].deleted==0)
- error(WARNING, "Include: %s", includelist[i].file);
- }
- }
- Nlist *
- lookup(Token *tp, int install)
- {
- unsigned int h;
- Nlist *np;
- uint8_t *cp, *cpe;
- h = 0;
- for (cp=tp->t, cpe=cp+tp->len; cp<cpe; )
- h += *cp++;
- h %= NLSIZE;
- np = nlist[h];
- while (np) {
- if (*tp->t==*np->name && tp->len==np->len
- && strncmp((char*)tp->t, (char*)np->name, tp->len)==0)
- return np;
- np = np->next;
- }
- if (install) {
- np = new(Nlist);
- np->val = 0;
- np->vp = NULL;
- np->ap = NULL;
- np->flag = 0;
- np->len = tp->len;
- np->name = newstring(tp->t, tp->len, 0);
- np->next = nlist[h];
- nlist[h] = np;
- quickset(tp->t[0], tp->len>1? tp->t[1]:0);
- return np;
- }
- return NULL;
- }
|