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