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