xref: /plan9-contrib/sys/src/cmd/cpp/nlist.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
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