annotate directive.c @ 114:05d67dd74e1f

Reduce the maximum include depth from 128 to 120. This way with the default limits on netbsd we hit it before we run out of file handles.
author David A. Holland
date Tue, 11 Jun 2013 13:55:38 -0400
parents 4483a14ee101
children a0a86380456e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
30
76c114899f63 copyrights
David A. Holland
parents: 18
diff changeset
1 /*-
99
60184aa42604 add 2013 to copyrights where it seems warranted
David A. Holland
parents: 90
diff changeset
2 * Copyright (c) 2010, 2013 The NetBSD Foundation, Inc.
30
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"
49
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
42 #include "output.h"
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
43
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
44 struct ifstate {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
45 struct ifstate *prev;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
46 struct place startplace;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
47 bool curtrue;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
48 bool evertrue;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
49 bool seenelse;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
50 };
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
51
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
52 static struct ifstate *ifstate;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
53
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
54 ////////////////////////////////////////////////////////////
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
55 // common parsing bits
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
56
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
57 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
58 void
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
59 uncomment(char *buf)
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
60 {
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
61 char *s, *t, *u = NULL;
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
62 bool incomment = false;
81
27c9aafcaca1 Don't recognize comments within double-quote strings.
David A. Holland
parents: 77
diff changeset
63 bool inesc = false;
27c9aafcaca1 Don't recognize comments within double-quote strings.
David A. Holland
parents: 77
diff changeset
64 bool inquote = false;
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
65
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
66 for (s = t = buf; *s; s++) {
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
67 if (incomment) {
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
68 if (s[0] == '*' && s[1] == '/') {
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
69 s++;
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
70 incomment = false;
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
71 }
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
72 } else {
81
27c9aafcaca1 Don't recognize comments within double-quote strings.
David A. Holland
parents: 77
diff changeset
73 if (!inquote && s[0] == '/' && s[1] == '*') {
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
74 incomment = true;
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
75 } else {
81
27c9aafcaca1 Don't recognize comments within double-quote strings.
David A. Holland
parents: 77
diff changeset
76 if (inesc) {
27c9aafcaca1 Don't recognize comments within double-quote strings.
David A. Holland
parents: 77
diff changeset
77 inesc = false;
27c9aafcaca1 Don't recognize comments within double-quote strings.
David A. Holland
parents: 77
diff changeset
78 } else if (s[0] == '\\') {
27c9aafcaca1 Don't recognize comments within double-quote strings.
David A. Holland
parents: 77
diff changeset
79 inesc = true;
27c9aafcaca1 Don't recognize comments within double-quote strings.
David A. Holland
parents: 77
diff changeset
80 } else if (s[0] == '"') {
27c9aafcaca1 Don't recognize comments within double-quote strings.
David A. Holland
parents: 77
diff changeset
81 inquote = !inquote;
27c9aafcaca1 Don't recognize comments within double-quote strings.
David A. Holland
parents: 77
diff changeset
82 }
27c9aafcaca1 Don't recognize comments within double-quote strings.
David A. Holland
parents: 77
diff changeset
83
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
84 if (t != s) {
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
85 *t = *s;
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
86 }
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
87 if (!strchr(ws, *t)) {
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
88 u = t;
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
89 }
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
90 t++;
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
91 }
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
92 }
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
93 }
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
94 if (u) {
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
95 /* end string after last non-whitespace char */
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
96 u[1] = '\0';
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
97 } else {
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
98 *t = '\0';
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
99 }
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
100 }
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
101
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
102 static
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
103 void
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
104 oneword(const char *what, struct place *p2, char *line)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
105 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
106 size_t pos;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
107
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
108 pos = strcspn(line, ws);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
109 if (line[pos] != '\0') {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
110 p2->column += pos;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
111 complain(p2, "Garbage after %s argument", what);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
112 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
113 line[pos] = '\0';
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
114 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
115 }
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 // if handling
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
119
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
120 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
121 struct ifstate *
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
122 ifstate_create(struct ifstate *prev, struct place *p, bool startstate)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
123 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
124 struct ifstate *is;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
125
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
126 is = domalloc(sizeof(*is));
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
127 is->prev = prev;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
128 if (p != NULL) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
129 is->startplace = *p;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
130 } else {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
131 place_setbuiltin(&is->startplace, 1);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
132 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
133 is->curtrue = startstate;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
134 is->evertrue = is->curtrue;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
135 is->seenelse = false;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
136 return is;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
137 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
138
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
139 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
140 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
141 ifstate_destroy(struct ifstate *is)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
142 {
39
337110e7240a Pass the size to free; it makes debug checking easier.
David A. Holland
parents: 38
diff changeset
143 dofree(is, sizeof(*is));
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
144 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
145
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
146 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
147 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
148 ifstate_push(struct place *p, bool startstate)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
149 {
72
b1d0f10e8d36 handle nested ifs correctly
David A. Holland
parents: 66
diff changeset
150 struct ifstate *newstate;
b1d0f10e8d36 handle nested ifs correctly
David A. Holland
parents: 66
diff changeset
151
b1d0f10e8d36 handle nested ifs correctly
David A. Holland
parents: 66
diff changeset
152 newstate = ifstate_create(ifstate, p, startstate);
b1d0f10e8d36 handle nested ifs correctly
David A. Holland
parents: 66
diff changeset
153 if (!ifstate->curtrue) {
b1d0f10e8d36 handle nested ifs correctly
David A. Holland
parents: 66
diff changeset
154 newstate->curtrue = false;
b1d0f10e8d36 handle nested ifs correctly
David A. Holland
parents: 66
diff changeset
155 newstate->evertrue = true;
b1d0f10e8d36 handle nested ifs correctly
David A. Holland
parents: 66
diff changeset
156 }
b1d0f10e8d36 handle nested ifs correctly
David A. Holland
parents: 66
diff changeset
157 ifstate = newstate;
15
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 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
161 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
162 ifstate_pop(void)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
163 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
164 struct ifstate *is;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
165
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
166 is = ifstate;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
167 ifstate = ifstate->prev;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
168 ifstate_destroy(is);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
169 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
170
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
171 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
172 void
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
173 d_if(struct place *p, struct place *p2, char *line)
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
174 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
175 char *expr;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
176 bool val;
16
9dda765ee85c expression evaluator
David A. Holland
parents: 15
diff changeset
177 struct place p3 = *p2;
82
05a94332f08b In #if/#elif, prune comments *after* macro expansion.
David A. Holland
parents: 81
diff changeset
178 size_t oldlen;
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
179
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
180 expr = macroexpand(p2, line, strlen(line), true);
82
05a94332f08b In #if/#elif, prune comments *after* macro expansion.
David A. Holland
parents: 81
diff changeset
181
05a94332f08b In #if/#elif, prune comments *after* macro expansion.
David A. Holland
parents: 81
diff changeset
182 oldlen = strlen(expr);
05a94332f08b In #if/#elif, prune comments *after* macro expansion.
David A. Holland
parents: 81
diff changeset
183 uncomment(expr);
05a94332f08b In #if/#elif, prune comments *after* macro expansion.
David A. Holland
parents: 81
diff changeset
184 /* trim to fit, so the malloc debugging won't complain */
05a94332f08b In #if/#elif, prune comments *after* macro expansion.
David A. Holland
parents: 81
diff changeset
185 expr = dorealloc(expr, oldlen + 1, strlen(expr) + 1);
05a94332f08b In #if/#elif, prune comments *after* macro expansion.
David A. Holland
parents: 81
diff changeset
186
16
9dda765ee85c expression evaluator
David A. Holland
parents: 15
diff changeset
187 val = eval(&p3, expr);
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
188 ifstate_push(p, val);
39
337110e7240a Pass the size to free; it makes debug checking easier.
David A. Holland
parents: 38
diff changeset
189 dostrfree(expr);
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
190 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
191
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
192 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
193 void
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
194 d_ifdef(struct place *p, struct place *p2, char *line)
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
195 {
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
196 uncomment(line);
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
197 oneword("#ifdef", p2, line);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
198 ifstate_push(p, macro_isdefined(line));
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
199 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
200
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
201 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
202 void
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
203 d_ifndef(struct place *p, struct place *p2, char *line)
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
204 {
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
205 uncomment(line);
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
206 oneword("#ifndef", p2, line);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
207 ifstate_push(p, !macro_isdefined(line));
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
208 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
209
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
210 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
211 void
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
212 d_elif(struct place *p, struct place *p2, char *line)
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
213 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
214 char *expr;
16
9dda765ee85c expression evaluator
David A. Holland
parents: 15
diff changeset
215 struct place p3 = *p2;
82
05a94332f08b In #if/#elif, prune comments *after* macro expansion.
David A. Holland
parents: 81
diff changeset
216 size_t oldlen;
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
217
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
218 if (ifstate->seenelse) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
219 complain(p, "#elif after #else");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
220 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
221 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
222
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
223 if (ifstate->evertrue) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
224 ifstate->curtrue = false;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
225 } else {
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
226 expr = macroexpand(p2, line, strlen(line), true);
82
05a94332f08b In #if/#elif, prune comments *after* macro expansion.
David A. Holland
parents: 81
diff changeset
227
05a94332f08b In #if/#elif, prune comments *after* macro expansion.
David A. Holland
parents: 81
diff changeset
228 oldlen = strlen(expr);
05a94332f08b In #if/#elif, prune comments *after* macro expansion.
David A. Holland
parents: 81
diff changeset
229 uncomment(expr);
05a94332f08b In #if/#elif, prune comments *after* macro expansion.
David A. Holland
parents: 81
diff changeset
230 /* trim to fit, so the malloc debugging won't complain */
05a94332f08b In #if/#elif, prune comments *after* macro expansion.
David A. Holland
parents: 81
diff changeset
231 expr = dorealloc(expr, oldlen + 1, strlen(expr) + 1);
05a94332f08b In #if/#elif, prune comments *after* macro expansion.
David A. Holland
parents: 81
diff changeset
232
16
9dda765ee85c expression evaluator
David A. Holland
parents: 15
diff changeset
233 ifstate->curtrue = eval(&p3, expr);
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
234 ifstate->evertrue = ifstate->curtrue;
39
337110e7240a Pass the size to free; it makes debug checking easier.
David A. Holland
parents: 38
diff changeset
235 dostrfree(expr);
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
236 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
237 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
238
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
239 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
240 void
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
241 d_else(struct place *p, struct place *p2, char *line)
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
242 {
103
343af355df1b Pass -Wunused.
David A. Holland
parents: 99
diff changeset
243 (void)p2;
343af355df1b Pass -Wunused.
David A. Holland
parents: 99
diff changeset
244 (void)line;
343af355df1b Pass -Wunused.
David A. Holland
parents: 99
diff changeset
245
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
246 if (ifstate->seenelse) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
247 complain(p, "Multiple #else directives in one conditional");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
248 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
249 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
250
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
251 ifstate->curtrue = !ifstate->evertrue;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
252 ifstate->evertrue = true;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
253 ifstate->seenelse = true;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
254 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
255
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
256 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
257 void
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
258 d_endif(struct place *p, struct place *p2, char *line)
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
259 {
103
343af355df1b Pass -Wunused.
David A. Holland
parents: 99
diff changeset
260 (void)p2;
343af355df1b Pass -Wunused.
David A. Holland
parents: 99
diff changeset
261 (void)line;
343af355df1b Pass -Wunused.
David A. Holland
parents: 99
diff changeset
262
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
263 if (ifstate->prev == NULL) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
264 complain(p, "Unmatched #endif");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
265 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
266 } else {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
267 ifstate_pop();
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 ////////////////////////////////////////////////////////////
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
272 // macros
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
273
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
274 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
275 void
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
276 d_define(struct place *p, struct place *p2, char *line)
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
277 {
18
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
278 size_t pos, argpos;
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
279 struct place p3, p4;
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
280
103
343af355df1b Pass -Wunused.
David A. Holland
parents: 99
diff changeset
281 (void)p;
343af355df1b Pass -Wunused.
David A. Holland
parents: 99
diff changeset
282
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
283 /*
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
284 * line may be:
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
285 * macro expansion
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
286 * macro(arg, arg, ...) expansion
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
287 */
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
288
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
289 pos = strcspn(line, " \t\f\v(");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
290 if (line[pos] == '(') {
18
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
291 line[pos++] = '\0';
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
292 argpos = pos;
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
293 pos = pos + strcspn(line+pos, "()");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
294 if (line[pos] == '(') {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
295 p2->column += pos;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
296 complain(p2, "Left parenthesis in macro parameters");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
297 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
298 return;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
299 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
300 if (line[pos] != ')') {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
301 p2->column += pos;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
302 complain(p2, "Unclosed macro parameter list");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
303 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
304 return;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
305 }
18
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
306 line[pos++] = '\0';
36
a489cc223483 Don't demand space after the macro argument parenthesis.
David A. Holland
parents: 30
diff changeset
307 #if 0
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
308 if (!strchr(ws, line[pos])) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
309 p2->column += pos;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
310 complain(p2, "Trash after macro parameter list");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
311 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
312 return;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
313 }
36
a489cc223483 Don't demand space after the macro argument parenthesis.
David A. Holland
parents: 30
diff changeset
314 #endif
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
315 } else if (line[pos] == '\0') {
18
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
316 argpos = 0;
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
317 } else {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
318 line[pos++] = '\0';
18
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
319 argpos = 0;
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
320 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
321
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
322 pos += strspn(line+pos, ws);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
323
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
324 p3 = *p2;
18
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
325 p3.column += argpos;
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
326
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
327 p4 = *p2;
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
328 p4.column += pos;
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
329
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
330 if (argpos) {
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
331 macro_define_params(p2, line, &p3,
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
332 line + argpos, &p4,
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
333 line + pos);
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
334 } else {
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
335 macro_define_plain(p2, line, &p4, line + pos);
c08a947d8f30 deal with macro parameters
David A. Holland
parents: 16
diff changeset
336 }
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
337 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
338
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
339 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
340 void
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
341 d_undef(struct place *p, struct place *p2, char *line)
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
342 {
103
343af355df1b Pass -Wunused.
David A. Holland
parents: 99
diff changeset
343 (void)p;
343af355df1b Pass -Wunused.
David A. Holland
parents: 99
diff changeset
344
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
345 uncomment(line);
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
346 oneword("#undef", p2, line);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
347 macro_undef(line);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
348 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
349
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
350 ////////////////////////////////////////////////////////////
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
351 // includes
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
352
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
353 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
354 bool
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
355 tryinclude(struct place *p, char *line)
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
356 {
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
357 size_t len;
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
358
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
359 len = strlen(line);
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
360 if (len > 2 && line[0] == '"' && line[len-1] == '"') {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
361 line[len-1] = '\0';
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
362 file_readquote(p, line+1);
62
90c6052410ce Don't truncate the candidate include path strings.
David A. Holland
parents: 49
diff changeset
363 line[len-1] = '"';
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
364 return true;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
365 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
366 if (len > 2 && line[0] == '<' && line[len-1] == '>') {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
367 line[len-1] = '\0';
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
368 file_readbracket(p, line+1);
62
90c6052410ce Don't truncate the candidate include path strings.
David A. Holland
parents: 49
diff changeset
369 line[len-1] = '>';
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
370 return true;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
371 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
372 return false;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
373 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
374
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
375 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
376 void
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
377 d_include(struct place *p, struct place *p2, char *line)
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
378 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
379 char *text;
82
05a94332f08b In #if/#elif, prune comments *after* macro expansion.
David A. Holland
parents: 81
diff changeset
380 size_t oldlen;
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
381
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
382 uncomment(line);
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
383 if (tryinclude(p, line)) {
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
384 return;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
385 }
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
386 text = macroexpand(p2, line, strlen(line), false);
82
05a94332f08b In #if/#elif, prune comments *after* macro expansion.
David A. Holland
parents: 81
diff changeset
387
05a94332f08b In #if/#elif, prune comments *after* macro expansion.
David A. Holland
parents: 81
diff changeset
388 oldlen = strlen(text);
05a94332f08b In #if/#elif, prune comments *after* macro expansion.
David A. Holland
parents: 81
diff changeset
389 uncomment(text);
05a94332f08b In #if/#elif, prune comments *after* macro expansion.
David A. Holland
parents: 81
diff changeset
390 /* trim to fit, so the malloc debugging won't complain */
05a94332f08b In #if/#elif, prune comments *after* macro expansion.
David A. Holland
parents: 81
diff changeset
391 text = dorealloc(text, oldlen + 1, strlen(text) + 1);
05a94332f08b In #if/#elif, prune comments *after* macro expansion.
David A. Holland
parents: 81
diff changeset
392
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
393 if (tryinclude(p, text)) {
39
337110e7240a Pass the size to free; it makes debug checking easier.
David A. Holland
parents: 38
diff changeset
394 dostrfree(text);
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
395 return;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
396 }
90
594495750d84 If we get a malformed #include, print it.
David A. Holland
parents: 83
diff changeset
397 complain(p, "Illegal #include directive");
594495750d84 If we get a malformed #include, print it.
David A. Holland
parents: 83
diff changeset
398 complain(p, "Before macro expansion: #include %s", line);
594495750d84 If we get a malformed #include, print it.
David A. Holland
parents: 83
diff changeset
399 complain(p, "After macro expansion: #include %s", text);
39
337110e7240a Pass the size to free; it makes debug checking easier.
David A. Holland
parents: 38
diff changeset
400 dostrfree(text);
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
401 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
402 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
403
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
404 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
405 void
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
406 d_line(struct place *p, struct place *p2, char *line)
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
407 {
103
343af355df1b Pass -Wunused.
David A. Holland
parents: 99
diff changeset
408 (void)p2;
343af355df1b Pass -Wunused.
David A. Holland
parents: 99
diff changeset
409 (void)line;
343af355df1b Pass -Wunused.
David A. Holland
parents: 99
diff changeset
410
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
411 /* XXX */
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
412 complain(p, "Sorry, no #line yet");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
413 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
414
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
415 ////////////////////////////////////////////////////////////
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
416 // messages
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
417
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
418 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
419 void
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
420 d_warning(struct place *p, struct place *p2, char *line)
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
421 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
422 char *msg;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
423
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
424 msg = macroexpand(p2, line, strlen(line), false);
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
425 complain(p, "#warning: %s", msg);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
426 if (mode.werror) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
427 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
428 }
39
337110e7240a Pass the size to free; it makes debug checking easier.
David A. Holland
parents: 38
diff changeset
429 dostrfree(msg);
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
430 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
431
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
432 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
433 void
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
434 d_error(struct place *p, struct place *p2, char *line)
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
435 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
436 char *msg;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
437
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
438 msg = macroexpand(p2, line, strlen(line), false);
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
439 complain(p, "#error: %s", msg);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
440 complain_fail();
39
337110e7240a Pass the size to free; it makes debug checking easier.
David A. Holland
parents: 38
diff changeset
441 dostrfree(msg);
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
442 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
443
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
444 ////////////////////////////////////////////////////////////
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
445 // other
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
446
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
447 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
448 void
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
449 d_pragma(struct place *p, struct place *p2, char *line)
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
450 {
103
343af355df1b Pass -Wunused.
David A. Holland
parents: 99
diff changeset
451 (void)p2;
343af355df1b Pass -Wunused.
David A. Holland
parents: 99
diff changeset
452
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
453 complain(p, "#pragma %s", line);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
454 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
455 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
456
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
457 ////////////////////////////////////////////////////////////
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
458 // directive table
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
459
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
460 static const struct {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
461 const char *name;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
462 bool ifskip;
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
463 void (*func)(struct place *, struct place *, char *line);
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
464 } directives[] = {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
465 { "define", true, d_define },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
466 { "elif", false, d_elif },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
467 { "else", false, d_else },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
468 { "endif", false, d_endif },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
469 { "error", true, d_error },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
470 { "if", false, d_if },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
471 { "ifdef", false, d_ifdef },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
472 { "ifndef", false, d_ifndef },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
473 { "include", true, d_include },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
474 { "line", true, d_line },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
475 { "pragma", true, d_pragma },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
476 { "undef", true, d_undef },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
477 { "warning", true, d_warning },
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
478 };
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
479 static const unsigned numdirectives = HOWMANY(directives);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
480
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
481 static
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
482 void
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
483 directive_gotdirective(struct place *p, char *line)
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
484 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
485 struct place p2;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
486 size_t len, skip;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
487 unsigned i;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
488
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
489 p2 = *p;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
490 for (i=0; i<numdirectives; i++) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
491 len = strlen(directives[i].name);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
492 if (!strncmp(line, directives[i].name, len) &&
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
493 strchr(ws, line[len])) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
494 if (directives[i].ifskip && !ifstate->curtrue) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
495 return;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
496 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
497 skip = len + strspn(line+len, ws);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
498 p2.column += skip;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
499 line += skip;
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
500
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
501 len = strlen(line);
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
502 len = notrailingws(line, len);
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
503 if (len < strlen(line)) {
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
504 line[len] = '\0';
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
505 }
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
506 directives[i].func(p, &p2, line);
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
507 return;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
508 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
509 }
83
3e505c16b0b0 Accept # by itself, including with a comment after it.
David A. Holland
parents: 82
diff changeset
510 /* ugh. allow # by itself, including with a comment after it */
3e505c16b0b0 Accept # by itself, including with a comment after it.
David A. Holland
parents: 82
diff changeset
511 uncomment(line);
3e505c16b0b0 Accept # by itself, including with a comment after it.
David A. Holland
parents: 82
diff changeset
512 if (line[0] == '\0') {
3e505c16b0b0 Accept # by itself, including with a comment after it.
David A. Holland
parents: 82
diff changeset
513 return;
3e505c16b0b0 Accept # by itself, including with a comment after it.
David A. Holland
parents: 82
diff changeset
514 }
3e505c16b0b0 Accept # by itself, including with a comment after it.
David A. Holland
parents: 82
diff changeset
515
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
516 skip = strcspn(line, ws);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
517 complain(p, "Unknown directive #%.*s", (int)skip, line);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
518 complain_fail();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
519 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
520
49
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
521 /*
77
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
522 * Check for nested comment delimiters in LINE.
49
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
523 */
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
524 static
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
525 size_t
77
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
526 directive_scancomments(const struct place *p, char *line, size_t len)
49
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
527 {
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
528 size_t pos;
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
529 bool incomment;
77
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
530 struct place p2;
49
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
531
77
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
532 p2 = *p;
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
533 incomment = 0;
49
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
534 for (pos = 0; pos+1 < len; pos++) {
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
535 if (line[pos] == '/' && line[pos+1] == '*') {
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
536 if (incomment) {
77
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
537 complain(&p2, "Warning: %c%c within comment",
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
538 '/', '*');
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
539 if (mode.werror) {
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
540 complain_failed();
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
541 }
49
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
542 } else {
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
543 incomment = true;
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
544 }
109
4483a14ee101 Make -Wcomment work again
David A. Holland
parents: 103
diff changeset
545 pos++;
49
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
546 } else if (line[pos] == '*' && line[pos+1] == '/') {
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
547 if (incomment) {
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
548 incomment = false;
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
549 } else {
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
550 /* stray end-comment; should we care? */
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
551 }
109
4483a14ee101 Make -Wcomment work again
David A. Holland
parents: 103
diff changeset
552 pos++;
49
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
553 }
77
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
554 if (line[pos] == '\n') {
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
555 p2.line++;
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
556 p2.column = 0;
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
557 } else {
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
558 p2.column++;
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
559 }
49
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
560 }
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
561
77
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
562 /* multiline comments are supposed to arrive in a single buffer */
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
563 assert(!incomment);
49
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
564 return len;
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
565 }
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
566
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
567 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
568 directive_gotline(struct place *p, char *line, size_t len)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
569 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
570 size_t skip;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
571
77
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
572 if (warns.nestcomment) {
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
573 directive_scancomments(p, line, len);
49
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
574 }
8a204d153398 Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents: 39
diff changeset
575
66
f8507e5ed84c Recognize directive lines only when the # is exactly in column 0.
David A. Holland
parents: 64
diff changeset
576 /* check if we have a directive line (# exactly in column 0) */
77
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
577 if (line[0] == '#') {
66
f8507e5ed84c Recognize directive lines only when the # is exactly in column 0.
David A. Holland
parents: 64
diff changeset
578 skip = 1 + strspn(line + 1, ws);
77
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
579 assert(skip <= len);
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
580 p->column += skip;
64
f50b4ea6cbfe Prune single-line comments from (most) directive lines.
David A. Holland
parents: 62
diff changeset
581 assert(line[len] == '\0');
77
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
582 directive_gotdirective(p, line+skip /*, length = len-skip */);
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
583 p->column += len-skip;
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
584 } else if (ifstate->curtrue) {
77
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
585 macro_sendline(p, line, len);
123168887da8 Clean out old not-really-working nested comment handling.
David A. Holland
parents: 72
diff changeset
586 p->column += len;
15
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
587 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
588 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
589
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
590 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
591 directive_goteof(struct place *p)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
592 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
593 while (ifstate->prev != NULL) {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
594 complain(p, "Missing #endif");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
595 complain(&ifstate->startplace, "...opened at this point");
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
596 complain_failed();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
597 ifstate_pop();
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
598 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
599 macro_sendeof(p);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
600 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
601
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
602 ////////////////////////////////////////////////////////////
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
603 // module initialization
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
604
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
605 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
606 directive_init(void)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
607 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
608 ifstate = ifstate_create(NULL, NULL, true);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
609 }
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
610
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
611 void
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
612 directive_cleanup(void)
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
613 {
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
614 assert(ifstate->prev == NULL);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
615 ifstate_destroy(ifstate);
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
616 ifstate = NULL;
f6177d3ed5c2 handle directives
David A. Holland
parents:
diff changeset
617 }