]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/cpp/nlist.c
cwfs: fix listen filedescriptor leaks
[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     nolineinfo;
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         "warning",      KWARNING,       ISKW,           // extension to ANSI
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                         /* Ignored for compatibility */
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 }