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