1 #include <u.h> 2 #include <libc.h> 3 #include <stdio.h> 4 #include "cpp.h" 5 6 extern int getopt(int, char **, char *); 7 extern char *optarg; 8 extern int optind; 9 int verbose; 10 int Cplusplus; 11 12 #define NLSIZE 128 13 14 Nlist *nlist[NLSIZE]; 15 16 struct kwtab { 17 char *kw; 18 int val; 19 int flag; 20 } kwtab[] = { 21 "if", KIF, ISKW, 22 "ifdef", KIFDEF, ISKW, 23 "ifndef", KIFNDEF, ISKW, 24 "elif", KELIF, ISKW, 25 "else", KELSE, ISKW, 26 "endif", KENDIF, ISKW, 27 "include", KINCLUDE, ISKW, 28 "define", KDEFINE, ISKW, 29 "undef", KUNDEF, ISKW, 30 "line", KLINE, ISKW, 31 "error", KERROR, ISKW, 32 "pragma", KPRAGMA, ISKW, 33 "eval", KEVAL, ISKW, 34 "defined", KDEFINED, ISKW+ISUNCHANGE, 35 "__LINE__", KLINENO, ISMAC+ISUNCHANGE, 36 "__FILE__", KFILE, ISMAC+ISUNCHANGE, 37 "__DATE__", KDATE, ISMAC+ISUNCHANGE, 38 "__TIME__", KTIME, ISMAC+ISUNCHANGE, 39 "__STDC__", KSTDC, ISUNCHANGE, 40 NULL 41 }; 42 43 unsigned long namebit[077+1]; 44 45 void 46 setup(int argc, char **argv) 47 { 48 struct kwtab *kp; 49 Nlist *np; 50 Token t; 51 int fd, i; 52 char *fp, *dp; 53 Tokenrow tr; 54 char *objtype; 55 static char nbuf[40]; 56 57 for (kp=kwtab; kp->kw; kp++) { 58 t.t = (uchar*)kp->kw; 59 t.len = strlen(kp->kw); 60 np = lookup(&t, 1); 61 np->flag = kp->flag; 62 np->val = kp->val; 63 } 64 /* 65 * For Plan 9, search /objtype/include, then /sys/include 66 * (Note that includelist is searched from high end to low 67 */ 68 if ((objtype = getenv("objtype"))){ 69 sprintf(nbuf, "/%s/include", objtype); 70 includelist[1].file = nbuf; 71 includelist[1].always = 1; 72 } else { 73 includelist[1].file = NULL; 74 error(WARNING, "Unknown $objtype"); 75 } 76 includelist[0].file = "/sys/include"; 77 includelist[0].always = 1; 78 setsource("", -1, 0); 79 ARGBEGIN { 80 case 'N': 81 for (i=0; i<NINCLUDE; i++) 82 if (includelist[i].always==1) 83 includelist[i].deleted = 1; 84 break; 85 case 'I': 86 for (i=NINCLUDE-2; i>=0; i--) { 87 if (includelist[i].file==NULL) { 88 includelist[i].always = 1; 89 includelist[i].file = ARGF(); 90 break; 91 } 92 } 93 if (i<0) 94 error(FATAL, "Too many -I directives"); 95 break; 96 case 'D': 97 case 'U': 98 setsource("<cmdarg>", -1, ARGF()); 99 maketokenrow(3, &tr); 100 gettokens(&tr, 1); 101 doadefine(&tr, ARGC()); 102 unsetsource(); 103 break; 104 case 'V': 105 verbose++; 106 break; 107 case '+': 108 Cplusplus++; 109 break; 110 default: 111 error(FATAL, "Unknown argument"); 112 break; 113 } ARGEND 114 dp = "."; 115 fp = "<stdin>"; 116 fd = 0; 117 if (argc > 0) { 118 if ((fp = strrchr(argv[0], '/')) != NULL) { 119 int len = fp - argv[0]; 120 dp = (char*)newstring((uchar*)argv[0], len+1, 0); 121 dp[len] = '\0'; 122 } 123 fp = (char*)newstring((uchar*)argv[0], strlen(argv[0]), 0); 124 if ((fd = open(fp, 0)) <= 0) 125 error(FATAL, "Can't open input file %s", fp); 126 } 127 if (argc > 1) { 128 int fdo = create(argv[1], 1, 0666); 129 if (fdo<0) 130 error(FATAL, "Can't open output file %s", argv[1]); 131 dup(fdo, 1); 132 } 133 includelist[NINCLUDE-1].always = 0; 134 includelist[NINCLUDE-1].file = dp; 135 setsource(fp, fd, NULL); 136 } 137 138 Nlist * 139 lookup(Token *tp, int install) 140 { 141 unsigned int h; 142 Nlist *np; 143 uchar *cp, *cpe; 144 145 h = 0; 146 for (cp=tp->t, cpe=cp+tp->len; cp<cpe; ) 147 h += *cp++; 148 h %= NLSIZE; 149 np = nlist[h]; 150 while (np) { 151 if (*tp->t==*np->name && tp->len==np->len 152 && strncmp((char*)tp->t, (char*)np->name, tp->len)==0) 153 return np; 154 np = np->next; 155 } 156 if (install) { 157 np = new(Nlist); 158 np->vp = NULL; 159 np->ap = NULL; 160 np->flag = 0; 161 np->len = tp->len; 162 np->name = newstring(tp->t, tp->len, 0); 163 np->next = nlist[h]; 164 nlist[h] = np; 165 quickset(tp->t[0], tp->len>1? tp->t[1]:0); 166 return np; 167 } 168 return NULL; 169 } 170