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 char xx[2] = { 0, 0}; 67 68 for (kp=kwtab; kp->kw; kp++) { 69 t.t = (uchar*)kp->kw; 70 t.len = strlen(kp->kw); 71 np = lookup(&t, 1); 72 np->flag = kp->flag; 73 np->val = kp->val; 74 if (np->val == KDEFINED) { 75 kwdefined = np; 76 np->val = NAME; 77 np->vp = &deftr; 78 np->ap = 0; 79 } 80 } 81 /* 82 * For Plan 9, search /objtype/include, then /sys/include 83 * (Note that includelist is searched from high end to low) 84 */ 85 if ((objtype = getenv("objtype"))){ 86 snprintf(nbuf, sizeof nbuf, "/%s/include", objtype); 87 includelist[1].file = nbuf; 88 includelist[1].always = 1; 89 } else { 90 includelist[1].file = NULL; 91 error(WARNING, "Unknown $objtype"); 92 } 93 if (getwd(wd, sizeof(wd))==0) 94 wd[0] = '\0'; 95 includelist[0].file = "/sys/include"; 96 includelist[0].always = 1; 97 firstinclude = NINCLUDE-2; 98 if ((includeenv=getenv("include")) != NULL) { 99 char *cp; 100 includeenv = strdup(includeenv); 101 for (;firstinclude>0; firstinclude--) { 102 cp = strtok(includeenv, " "); 103 if (cp==NULL) 104 break; 105 includelist[firstinclude].file = cp; 106 includelist[firstinclude].always = 1; 107 includeenv = NULL; 108 } 109 } 110 setsource("", -1, 0); 111 ARGBEGIN { 112 case 'N': 113 for (i=0; i<NINCLUDE; i++) 114 if (includelist[i].always==1) 115 includelist[i].deleted = 1; 116 break; 117 case 'I': 118 for (i=firstinclude; i>=0; i--) { 119 if (includelist[i].file==NULL) { 120 includelist[i].always = 1; 121 includelist[i].file = ARGF(); 122 break; 123 } 124 } 125 if (i<0) 126 error(WARNING, "Too many -I directives"); 127 break; 128 case 'D': 129 case 'U': 130 setsource("<cmdarg>", -1, ARGF()); 131 maketokenrow(3, &tr); 132 gettokens(&tr, 1); 133 doadefine(&tr, ARGC()); 134 unsetsource(); 135 break; 136 case 'M': 137 Mflag++; 138 break; 139 case 'V': 140 verbose++; 141 break; 142 case '+': 143 Cplusplus++; 144 break; 145 case 'i': 146 debuginclude++; 147 break; 148 case 'P': 149 nolineinfo++; 150 break; 151 default: 152 xx[0] = ARGC(); 153 error(FATAL, "Unknown argument '%s'", xx); 154 break; 155 } ARGEND 156 dp = "."; 157 fp = "<stdin>"; 158 fd = 0; 159 if (argc > 0) { 160 if ((fp = strrchr(argv[0], '/')) != NULL) { 161 int len = fp - argv[0]; 162 dp = (char*)newstring((uchar*)argv[0], len+1, 0); 163 dp[len] = '\0'; 164 } 165 fp = (char*)newstring((uchar*)argv[0], strlen(argv[0]), 0); 166 if ((fd = open(fp, 0)) <= 0) 167 error(FATAL, "Can't open input file %s", fp); 168 } 169 if (argc > 1) { 170 int fdo = create(argv[1], 1, 0666); 171 if (fdo<0) 172 error(FATAL, "Can't open output file %s", argv[1]); 173 dup(fdo, 1); 174 } 175 if (Mflag) 176 setobjname(fp); 177 includelist[NINCLUDE-1].always = 0; 178 includelist[NINCLUDE-1].file = dp; 179 setsource(fp, fd, NULL); 180 if (debuginclude) { 181 for (i=0; i<NINCLUDE; i++) 182 if (includelist[i].file && includelist[i].deleted==0) 183 error(WARNING, "Include: %s", includelist[i].file); 184 } 185 } 186 187 Nlist * 188 lookup(Token *tp, int install) 189 { 190 unsigned int h; 191 Nlist *np; 192 uchar *cp, *cpe; 193 194 h = 0; 195 for (cp=tp->t, cpe=cp+tp->len; cp<cpe; ) 196 h += *cp++; 197 h %= NLSIZE; 198 np = nlist[h]; 199 while (np) { 200 if (*tp->t==*np->name && tp->len==np->len 201 && strncmp((char*)tp->t, (char*)np->name, tp->len)==0) 202 return np; 203 np = np->next; 204 } 205 if (install) { 206 np = new(Nlist); 207 np->val = 0; 208 np->vp = NULL; 209 np->ap = NULL; 210 np->flag = 0; 211 np->len = tp->len; 212 np->name = newstring(tp->t, tp->len, 0); 213 np->next = nlist[h]; 214 nlist[h] = np; 215 quickset(tp->t[0], tp->len>1? tp->t[1]:0); 216 return np; 217 } 218 return NULL; 219 } 220