annotate directive.c @ 37:70902cac4170

Sort the option lists to match the comparison used to search them. duh. Also don't assert on the incpaths during shutdown.
author David A. Holland
date Sat, 30 Mar 2013 20:52:59 -0400
parents a489cc223483
children b156910b59b2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
30
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
1 /*-
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
2 * Copyright (c) 2010 The NetBSD Foundation, Inc.
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
3 * All rights reserved.
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
4 *
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
5 * This code is derived from software contributed to The NetBSD Foundation
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
6 * by David A. Holland.
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
7 *
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
8 * Redistribution and use in source and binary forms, with or without
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
9 * modification, are permitted provided that the following conditions
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
10 * are met:
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
11 * 1. Redistributions of source code must retain the above copyright
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
12 * notice, this list of conditions and the following disclaimer.
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
13 * 2. Redistributions in binary form must reproduce the above copyright
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
14 * notice, this list of conditions and the following disclaimer in the
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
15 * documentation and/or other materials provided with the distribution.
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
16 *
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
27 * POSSIBILITY OF SUCH DAMAGE.
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
28 */
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
29
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
30 #include <assert.h>
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
31 #include <stdbool.h>
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
32 #include <stdlib.h>
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
33 #include <string.h>
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
34
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
35 #include "utils.h"
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
36 #include "mode.h"
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
37 #include "place.h"
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
38 #include "files.h"
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
39 #include "directive.h"
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
40 #include "macro.h"
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
41 #include "eval.h"
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
42
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
43 struct ifstate {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
44 struct ifstate *prev;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
45 struct place startplace;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
46 bool curtrue;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
47 bool evertrue;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
48 bool seenelse;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
49 };
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
50
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
51 static struct ifstate *ifstate;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
52
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
53 ////////////////////////////////////////////////////////////
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
54 // common parsing bits
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
55
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
56 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
57 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
58 oneword(const char *what, struct place *p2, char *line)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
59 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
60 size_t pos;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
61
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
62 pos = strcspn(line, ws);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
63 if (line[pos] != '\0') {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
64 p2->column += pos;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
65 complain(p2, "Garbage after %s argument", what);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
66 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
67 line[pos] = '\0';
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
68 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
69 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
70
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
71 ////////////////////////////////////////////////////////////
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
72 // if handling
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
73
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
74 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
75 struct ifstate *
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
76 ifstate_create(struct ifstate *prev, struct place *p, bool startstate)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
77 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
78 struct ifstate *is;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
79
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
80 is = domalloc(sizeof(*is));
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
81 is->prev = prev;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
82 if (p != NULL) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
83 is->startplace = *p;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
84 } else {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
85 place_setbuiltin(&is->startplace, 1);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
86 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
87 is->curtrue = startstate;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
88 is->evertrue = is->curtrue;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
89 is->seenelse = false;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
90 return is;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
91 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
92
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
93 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
94 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
95 ifstate_destroy(struct ifstate *is)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
96 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
97 free(is);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
98 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
99
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
100 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
101 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
102 ifstate_push(struct place *p, bool startstate)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
103 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
104 ifstate = ifstate_create(ifstate, p, startstate);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
105 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
106
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
107 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
108 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
109 ifstate_pop(void)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
110 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
111 struct ifstate *is;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
112
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
113 is = ifstate;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
114 ifstate = ifstate->prev;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
115 ifstate_destroy(is);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
116 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
117
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
118 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
119 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
120 d_if(struct place *p, struct place *p2, char *line, size_t len)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
121 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
122 char *expr;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
123 bool val;
16
9dda765ee85c expression evaluator
David A. Holland
parents: 15
diff changeset
124 struct place p3 = *p2;
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
125
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
126 expr = macroexpand(p2, line, len, true);
16
9dda765ee85c expression evaluator
David A. Holland
parents: 15
diff changeset
127 val = eval(&p3, expr);
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
128 ifstate_push(p, val);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
129 free(expr);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
130 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
131
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
132 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
133 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
134 d_ifdef(struct place *p, struct place *p2, char *line, size_t len)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
135 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
136 oneword("#ifdef", p2, line);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
137 ifstate_push(p, macro_isdefined(line));
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
138 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
139
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
140 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
141 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
142 d_ifndef(struct place *p, struct place *p2, char *line, size_t len)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
143 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
144 oneword("#ifndef", p2, line);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
145 ifstate_push(p, !macro_isdefined(line));
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
146 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
147
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
148 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
149 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
150 d_elif(struct place *p, struct place *p2, char *line, size_t len)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
151 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
152 char *expr;
16
9dda765ee85c expression evaluator
David A. Holland
parents: 15
diff changeset
153 struct place p3 = *p2;
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
154
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
155 if (ifstate->seenelse) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
156 complain(p, "#elif after #else");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
157 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
158 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
159
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
160 if (ifstate->evertrue) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
161 ifstate->curtrue = false;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
162 } else {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
163 expr = macroexpand(p2, line, len, true);
16
9dda765ee85c expression evaluator
David A. Holland
parents: 15
diff changeset
164 ifstate->curtrue = eval(&p3, expr);
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
165 ifstate->evertrue = ifstate->curtrue;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
166 free(expr);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
167 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
168 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
169
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
170 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
171 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
172 d_else(struct place *p, struct place *p2, char *line, size_t len)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
173 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
174 if (ifstate->seenelse) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
175 complain(p, "Multiple #else directives in one conditional");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
176 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
177 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
178
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
179 ifstate->curtrue = !ifstate->evertrue;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
180 ifstate->evertrue = true;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
181 ifstate->seenelse = true;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
182 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
183
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
184 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
185 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
186 d_endif(struct place *p, struct place *p2, char *line, size_t len)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
187 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
188 if (ifstate->prev == NULL) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
189 complain(p, "Unmatched #endif");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
190 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
191 } else {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
192 ifstate_pop();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
193 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
194 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
195
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
196 ////////////////////////////////////////////////////////////
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
197 // macros
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
198
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
199 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
200 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
201 d_define(struct place *p, struct place *p2, char *line, size_t len)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
202 {
18
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
203 size_t pos, argpos;
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
204 struct place p3, p4;
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
205
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
206 /*
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
207 * line may be:
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
208 * macro expansion
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
209 * macro(arg, arg, ...) expansion
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
210 */
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
211
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
212 pos = strcspn(line, " \t\f\v(");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
213 if (line[pos] == '(') {
18
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
214 line[pos++] = '\0';
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
215 argpos = pos;
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
216 pos = pos + strcspn(line+pos, "()");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
217 if (line[pos] == '(') {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
218 p2->column += pos;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
219 complain(p2, "Left parenthesis in macro parameters");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
220 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
221 return;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
222 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
223 if (line[pos] != ')') {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
224 p2->column += pos;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
225 complain(p2, "Unclosed macro parameter list");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
226 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
227 return;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
228 }
18
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
229 line[pos++] = '\0';
36
a489cc223483 Don't demand space after the macro argument parenthesis.
David A. Holland
parents: 30
diff changeset
230 #if 0
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
231 if (!strchr(ws, line[pos])) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
232 p2->column += pos;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
233 complain(p2, "Trash after macro parameter list");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
234 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
235 return;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
236 }
36
a489cc223483 Don't demand space after the macro argument parenthesis.
David A. Holland
parents: 30
diff changeset
237 #endif
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
238 } else if (line[pos] == '\0') {
18
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
239 argpos = 0;
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
240 } else {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
241 line[pos++] = '\0';
18
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
242 argpos = 0;
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
243 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
244
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
245 pos += strspn(line+pos, ws);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
246
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
247 p3 = *p2;
18
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
248 p3.column += argpos;
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
249
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
250 p4 = *p2;
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
251 p4.column += pos;
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
252
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
253 if (argpos) {
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
254 macro_define_params(p2, line, &p3,
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
255 line + argpos, &p4,
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
256 line + pos);
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
257 } else {
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
258 macro_define_plain(p2, line, &p4, line + pos);
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
259 }
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
260 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
261
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
262 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
263 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
264 d_undef(struct place *p, struct place *p2, char *line, size_t len)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
265 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
266 oneword("#undef", p2, line);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
267 macro_undef(line);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
268 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
269
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
270 ////////////////////////////////////////////////////////////
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
271 // includes
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
272
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
273 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
274 bool
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
275 tryinclude(struct place *p, char *line, size_t len)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
276 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
277 if (len > 2 && line[0] == '"' && line[len-1] == '"') {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
278 line[len-1] = '\0';
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
279 file_readquote(p, line+1);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
280 return true;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
281 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
282 if (len > 2 && line[0] == '<' && line[len-1] == '>') {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
283 line[len-1] = '\0';
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
284 file_readbracket(p, line+1);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
285 return true;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
286 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
287 return false;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
288 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
289
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
290 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
291 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
292 d_include(struct place *p, struct place *p2, char *line, size_t len)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
293 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
294 char *text;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
295
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
296 if (tryinclude(p, line, len)) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
297 return;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
298 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
299 text = macroexpand(p2, line, len, false);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
300 if (tryinclude(p, text, strlen(text))) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
301 free(text);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
302 return;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
303 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
304 free(text);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
305 complain(p, "Illegal #include directive");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
306 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
307 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
308
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
309 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
310 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
311 d_line(struct place *p, struct place *p2, char *line, size_t len)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
312 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
313 /* XXX */
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
314 complain(p, "Sorry, no #line yet");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
315 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
316
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
317 ////////////////////////////////////////////////////////////
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
318 // messages
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
319
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
320 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
321 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
322 d_warning(struct place *p, struct place *p2, char *line, size_t len)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
323 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
324 char *msg;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
325
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
326 msg = macroexpand(p2, line, len, false);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
327 complain(p, "#warning: %s", msg);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
328 if (mode.werror) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
329 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
330 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
331 free(msg);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
332 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
333
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
334 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
335 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
336 d_error(struct place *p, struct place *p2, char *line, size_t len)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
337 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
338 char *msg;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
339
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
340 msg = macroexpand(p2, line, len, false);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
341 complain(p, "#error: %s", msg);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
342 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
343 free(msg);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
344 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
345
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
346 ////////////////////////////////////////////////////////////
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
347 // other
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
348
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
349 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
350 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
351 d_pragma(struct place *p, struct place *p2, char *line, size_t len)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
352 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
353 complain(p, "#pragma %s", line);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
354 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
355 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
356
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
357 ////////////////////////////////////////////////////////////
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
358 // directive table
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
359
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
360 static const struct {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
361 const char *name;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
362 bool ifskip;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
363 void (*func)(struct place *, struct place *, char *line, size_t len);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
364 } directives[] = {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
365 { "define", true, d_define },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
366 { "elif", false, d_elif },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
367 { "else", false, d_else },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
368 { "endif", false, d_endif },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
369 { "error", true, d_error },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
370 { "if", false, d_if },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
371 { "ifdef", false, d_ifdef },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
372 { "ifndef", false, d_ifndef },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
373 { "include", true, d_include },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
374 { "line", true, d_line },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
375 { "pragma", true, d_pragma },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
376 { "undef", true, d_undef },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
377 { "warning", true, d_warning },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
378 };
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
379 static const unsigned numdirectives = HOWMANY(directives);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
380
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
381 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
382 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
383 directive_gotdirective(struct place *p, char *line, size_t linelen)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
384 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
385 struct place p2;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
386 size_t len, skip;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
387 unsigned i;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
388
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
389 p2 = *p;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
390 for (i=0; i<numdirectives; i++) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
391 len = strlen(directives[i].name);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
392 if (!strncmp(line, directives[i].name, len) &&
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
393 strchr(ws, line[len])) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
394 if (directives[i].ifskip && !ifstate->curtrue) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
395 return;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
396 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
397 skip = len + strspn(line+len, ws);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
398 p2.column += skip;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
399 line += skip;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
400 linelen -= skip;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
401 linelen = notrailingws(line, linelen);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
402 directives[i].func(p, &p2, line, linelen);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
403 return;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
404 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
405 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
406 skip = strcspn(line, ws);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
407 complain(p, "Unknown directive #%.*s", (int)skip, line);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
408 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
409 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
410
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
411 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
412 directive_gotline(struct place *p, char *line, size_t len)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
413 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
414 size_t skip;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
415
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
416 /* check if we have a directive line */
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
417 skip = strspn(line, ws);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
418 if (line[skip] == '#') {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
419 skip = skip + 1 + strspn(line + skip + 1, ws);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
420 p->column += skip;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
421 directive_gotdirective(p, line+skip, len-skip);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
422 } else if (ifstate->curtrue) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
423 macro_sendline(p, line, len);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
424 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
425 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
426
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
427
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
428 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
429 directive_goteof(struct place *p)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
430 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
431 while (ifstate->prev != NULL) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
432 complain(p, "Missing #endif");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
433 complain(&ifstate->startplace, "...opened at this point");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
434 complain_failed();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
435 ifstate_pop();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
436 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
437 macro_sendeof(p);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
438 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
439
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
440 ////////////////////////////////////////////////////////////
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
441 // module initialization
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
442
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
443 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
444 directive_init(void)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
445 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
446 ifstate = ifstate_create(NULL, NULL, true);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
447 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
448
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
449 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
450 directive_cleanup(void)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
451 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
452 assert(ifstate->prev == NULL);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
453 ifstate_destroy(ifstate);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
454 ifstate = NULL;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
455 }