xref: /plan9/sys/src/cmd/cpp/nlist.c (revision 3e12c5d1bb89fc02707907988834ef147769ddaf)
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	Cplusplus;
11 
12 #define	NLSIZE	128
13 
14 Nlist	*nlist[NLSIZE];
15 
16 struct	kwtab {
17 	char	*kw;
18 	int	val;
19 	int	flag;
20 } kwtab[] = {
21 	"if",		KIF,		ISKW,
22 	"ifdef",	KIFDEF,		ISKW,
23 	"ifndef",	KIFNDEF,	ISKW,
24 	"elif",		KELIF,		ISKW,
25 	"else",		KELSE,		ISKW,
26 	"endif",	KENDIF,		ISKW,
27 	"include",	KINCLUDE,	ISKW,
28 	"define",	KDEFINE,	ISKW,
29 	"undef",	KUNDEF,		ISKW,
30 	"line",		KLINE,		ISKW,
31 	"error",	KERROR,		ISKW,
32 	"pragma",	KPRAGMA,	ISKW,
33 	"eval",		KEVAL,		ISKW,
34 	"defined",	KDEFINED,	ISKW+ISUNCHANGE,
35 	"__LINE__",	KLINENO,	ISMAC+ISUNCHANGE,
36 	"__FILE__",	KFILE,		ISMAC+ISUNCHANGE,
37 	"__DATE__",	KDATE,		ISMAC+ISUNCHANGE,
38 	"__TIME__",	KTIME,		ISMAC+ISUNCHANGE,
39 	"__STDC__",	KSTDC,		ISUNCHANGE,
40 	NULL
41 };
42 
43 unsigned long	namebit[077+1];
44 
45 void
46 setup(int argc, char **argv)
47 {
48 	struct kwtab *kp;
49 	Nlist *np;
50 	Token t;
51 	int fd, i;
52 	char *fp, *dp;
53 	Tokenrow tr;
54 	char *objtype;
55 	static char nbuf[40];
56 
57 	for (kp=kwtab; kp->kw; kp++) {
58 		t.t = (uchar*)kp->kw;
59 		t.len = strlen(kp->kw);
60 		np = lookup(&t, 1);
61 		np->flag = kp->flag;
62 		np->val = kp->val;
63 	}
64 	/*
65 	 * For Plan 9, search /objtype/include, then /sys/include
66 	 * (Note that includelist is searched from high end to low
67 	 */
68 	if ((objtype = getenv("objtype"))){
69 		sprintf(nbuf, "/%s/include", objtype);
70 		includelist[1].file = nbuf;
71 		includelist[1].always = 1;
72 	} else {
73 		includelist[1].file = NULL;
74 		error(WARNING, "Unknown $objtype");
75 	}
76 	includelist[0].file = "/sys/include";
77 	includelist[0].always = 1;
78 	setsource("", -1, 0);
79 	ARGBEGIN {
80 		case 'N':
81 			for (i=0; i<NINCLUDE; i++)
82 				if (includelist[i].always==1)
83 					includelist[i].deleted = 1;
84 			break;
85 		case 'I':
86 			for (i=NINCLUDE-2; i>=0; i--) {
87 				if (includelist[i].file==NULL) {
88 					includelist[i].always = 1;
89 					includelist[i].file = ARGF();
90 					break;
91 				}
92 			}
93 			if (i<0)
94 				error(FATAL, "Too many -I directives");
95 			break;
96 		case 'D':
97 		case 'U':
98 			setsource("<cmdarg>", -1, ARGF());
99 			maketokenrow(3, &tr);
100 			gettokens(&tr, 1);
101 			doadefine(&tr, ARGC());
102 			unsetsource();
103 			break;
104 		case 'V':
105 			verbose++;
106 			break;
107 		case '+':
108 			Cplusplus++;
109 			break;
110 		default:
111 			error(FATAL, "Unknown argument");
112 			break;
113 	} ARGEND
114 	dp = ".";
115 	fp = "<stdin>";
116 	fd = 0;
117 	if (argc > 0) {
118 		if ((fp = strrchr(argv[0], '/')) != NULL) {
119 			int len = fp - argv[0];
120 			dp = (char*)newstring((uchar*)argv[0], len+1, 0);
121 			dp[len] = '\0';
122 		}
123 		fp = (char*)newstring((uchar*)argv[0], strlen(argv[0]), 0);
124 		if ((fd = open(fp, 0)) <= 0)
125 			error(FATAL, "Can't open input file %s", fp);
126 	}
127 	if (argc > 1) {
128 		int fdo = create(argv[1], 1, 0666);
129 		if (fdo<0)
130 			error(FATAL, "Can't open output file %s", argv[1]);
131 		dup(fdo, 1);
132 	}
133 	includelist[NINCLUDE-1].always = 0;
134 	includelist[NINCLUDE-1].file = dp;
135 	setsource(fp, fd, NULL);
136 }
137 
138 Nlist *
139 lookup(Token *tp, int install)
140 {
141 	unsigned int h;
142 	Nlist *np;
143 	uchar *cp, *cpe;
144 
145 	h = 0;
146 	for (cp=tp->t, cpe=cp+tp->len; cp<cpe; )
147 		h += *cp++;
148 	h %= NLSIZE;
149 	np = nlist[h];
150 	while (np) {
151 		if (*tp->t==*np->name && tp->len==np->len
152 		 && strncmp((char*)tp->t, (char*)np->name, tp->len)==0)
153 			return np;
154 		np = np->next;
155 	}
156 	if (install) {
157 		np = new(Nlist);
158 		np->vp = NULL;
159 		np->ap = NULL;
160 		np->flag = 0;
161 		np->len = tp->len;
162 		np->name = newstring(tp->t, tp->len, 0);
163 		np->next = nlist[h];
164 		nlist[h] = np;
165 		quickset(tp->t[0], tp->len>1? tp->t[1]:0);
166 		return np;
167 	}
168 	return NULL;
169 }
170