Mercurial > ~dholland > hg > tradcpp > index.cgi
annotate place.c @ 184:d359d9b86327
Don't rely on anonymous unions.
They break on... dun dun dun... Solaris. Such a shock.
author | David A. Holland |
---|---|
date | Fri, 12 Jun 2015 03:35:01 -0400 |
parents | a2f047301c15 |
children | 16b4451e34b8 |
rev | line source |
---|---|
30 | 1 /*- |
2 * Copyright (c) 2010 The NetBSD Foundation, Inc. | |
3 * All rights reserved. | |
4 * | |
5 * This code is derived from software contributed to The NetBSD Foundation | |
6 * by David A. Holland. | |
7 * | |
8 * Redistribution and use in source and binary forms, with or without | |
9 * modification, are permitted provided that the following conditions | |
10 * are met: | |
11 * 1. Redistributions of source code must retain the above copyright | |
12 * notice, this list of conditions and the following disclaimer. | |
13 * 2. Redistributions in binary form must reproduce the above copyright | |
14 * notice, this list of conditions and the following disclaimer in the | |
15 * documentation and/or other materials provided with the distribution. | |
16 * | |
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
27 * POSSIBILITY OF SUCH DAMAGE. | |
28 */ | |
29 | |
8 | 30 #include <assert.h> |
31 #include <stdarg.h> | |
32 #include <stdio.h> | |
33 #include <stdlib.h> | |
112 | 34 #include <string.h> |
8 | 35 |
36 #include "utils.h" | |
10 | 37 #include "array.h" |
8 | 38 #include "place.h" |
39 | |
13 | 40 struct placefile { |
10 | 41 struct place includedfrom; |
112 | 42 char *dir; |
10 | 43 char *name; |
28 | 44 int depth; |
10 | 45 bool fromsystemdir; |
46 }; | |
107 | 47 DECLARRAY(placefile, static UNUSED); |
47
2e25e55dba6b
Fix inline usage as per the version in dholland-make2.
David A. Holland
parents:
39
diff
changeset
|
48 DEFARRAY(placefile, static); |
10 | 49 |
13 | 50 static struct placefilearray placefiles; |
10 | 51 static bool overall_failure; |
52 | |
142 | 53 static const char *myprogname; |
54 | |
10 | 55 //////////////////////////////////////////////////////////// |
176
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
56 // placefiles |
10 | 57 |
58 static | |
13 | 59 struct placefile * |
60 placefile_create(const struct place *from, const char *name, | |
61 bool fromsystemdir) | |
10 | 62 { |
13 | 63 struct placefile *pf; |
112 | 64 const char *s; |
65 size_t len; | |
10 | 66 |
13 | 67 pf = domalloc(sizeof(*pf)); |
68 pf->includedfrom = *from; | |
112 | 69 |
70 s = strrchr(name, '/'); | |
71 len = (s == NULL) ? 0 : s - name; | |
72 pf->dir = dostrndup(name, len); | |
73 | |
13 | 74 pf->name = dostrdup(name); |
75 pf->fromsystemdir = fromsystemdir; | |
112 | 76 |
28 | 77 if (from->file != NULL) { |
78 pf->depth = from->file->depth + 1; | |
79 } else { | |
80 pf->depth = 1; | |
81 } | |
13 | 82 return pf; |
10 | 83 } |
84 | |
85 static | |
86 void | |
13 | 87 placefile_destroy(struct placefile *pf) |
10 | 88 { |
39
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
89 dostrfree(pf->name); |
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
90 dofree(pf, sizeof(*pf)); |
10 | 91 } |
92 | |
13 | 93 DESTROYALL_ARRAY(placefile, ); |
10 | 94 |
112 | 95 const char * |
96 place_getparsedir(const struct place *place) | |
97 { | |
98 if (place->file == NULL) { | |
99 return "."; | |
100 } | |
101 return place->file->dir; | |
102 } | |
103 | |
176
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
104 static |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
105 bool |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
106 place_eq(const struct place *a, const struct place *b) |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
107 { |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
108 if (a->type != b->type) { |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
109 return false; |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
110 } |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
111 if (a->file != b->file) { |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
112 return false; |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
113 } |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
114 if (a->line != b->line || a->column != b->column) { |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
115 return false; |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
116 } |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
117 return true; |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
118 } |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
119 |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
120 static |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
121 struct placefile * |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
122 placefile_find(const struct place *incfrom, const char *name) |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
123 { |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
124 unsigned i, num; |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
125 struct placefile *pf; |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
126 |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
127 num = placefilearray_num(&placefiles); |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
128 for (i=0; i<num; i++) { |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
129 pf = placefilearray_get(&placefiles, i); |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
130 if (place_eq(incfrom, &pf->includedfrom) && |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
131 !strcmp(name, pf->name)) { |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
132 return pf; |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
133 } |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
134 } |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
135 return NULL; |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
136 } |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
137 |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
138 void |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
139 place_changefile(struct place *p, const char *name) |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
140 { |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
141 struct placefile *pf; |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
142 |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
143 assert(p->type == P_FILE); |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
144 if (!strcmp(name, p->file->name)) { |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
145 return; |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
146 } |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
147 pf = placefile_find(&p->file->includedfrom, name); |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
148 if (pf == NULL) { |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
149 pf = placefile_create(&p->file->includedfrom, name, |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
150 p->file->fromsystemdir); |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
151 placefilearray_add(&placefiles, pf, NULL); |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
152 } |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
153 p->file = pf; |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
154 } |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
155 |
13 | 156 const struct placefile * |
157 place_addfile(const struct place *place, const char *file, bool issystem) | |
10 | 158 { |
13 | 159 struct placefile *pf; |
10 | 160 |
13 | 161 pf = placefile_create(place, file, issystem); |
162 placefilearray_add(&placefiles, pf, NULL); | |
114
05d67dd74e1f
Reduce the maximum include depth from 128 to 120.
David A. Holland
parents:
112
diff
changeset
|
163 if (pf->depth > 120) { |
28 | 164 complain(place, "Maximum include nesting depth exceeded"); |
165 die(); | |
166 } | |
13 | 167 return pf; |
10 | 168 } |
169 | |
170 //////////////////////////////////////////////////////////// | |
171 // places | |
172 | |
8 | 173 void |
174 place_setnowhere(struct place *p) | |
175 { | |
12 | 176 p->type = P_NOWHERE; |
8 | 177 p->file = NULL; |
12 | 178 p->line = 0; |
8 | 179 p->column = 0; |
180 } | |
181 | |
182 void | |
183 place_setbuiltin(struct place *p, unsigned num) | |
184 { | |
12 | 185 p->type = P_BUILTIN; |
8 | 186 p->file = NULL; |
12 | 187 p->line = num; |
188 p->column = 1; | |
8 | 189 } |
190 | |
191 void | |
14 | 192 place_setcommandline(struct place *p, unsigned line, unsigned column) |
8 | 193 { |
14 | 194 p->type = P_COMMANDLINE; |
8 | 195 p->file = NULL; |
14 | 196 p->line = line; |
8 | 197 p->column = column; |
198 } | |
199 | |
14 | 200 void |
201 place_setfilestart(struct place *p, const struct placefile *pf) | |
202 { | |
28 | 203 p->type = P_FILE; |
14 | 204 p->file = pf; |
205 p->line = 1; | |
206 p->column = 1; | |
207 } | |
208 | |
12 | 209 const char * |
210 place_getname(const struct place *p) | |
8 | 211 { |
12 | 212 switch (p->type) { |
213 case P_NOWHERE: return "<nowhere>"; | |
214 case P_BUILTIN: return "<built-in>"; | |
215 case P_COMMANDLINE: return "<command-line>"; | |
216 case P_FILE: return p->file->name; | |
8 | 217 } |
12 | 218 assert(0); |
219 return NULL; | |
8 | 220 } |
221 | |
222 static | |
223 void | |
224 place_printfrom(const struct place *p) | |
225 { | |
226 const struct place *from; | |
227 | |
95
1c0575f7dd46
Don't crash printing the commandline place.
David A. Holland
parents:
47
diff
changeset
|
228 if (p->file == NULL) { |
1c0575f7dd46
Don't crash printing the commandline place.
David A. Holland
parents:
47
diff
changeset
|
229 return; |
1c0575f7dd46
Don't crash printing the commandline place.
David A. Holland
parents:
47
diff
changeset
|
230 } |
10 | 231 from = &p->file->includedfrom; |
12 | 232 if (from->type != P_NOWHERE) { |
8 | 233 place_printfrom(from); |
12 | 234 fprintf(stderr, "In file included from %s:%u:%u:\n", |
235 place_getname(from), from->line, from->column); | |
8 | 236 } |
237 } | |
238 | |
10 | 239 //////////////////////////////////////////////////////////// |
240 // complaints | |
241 | |
8 | 242 void |
142 | 243 complain_init(const char *pn) |
244 { | |
245 myprogname = pn; | |
246 } | |
247 | |
248 void | |
8 | 249 complain(const struct place *p, const char *fmt, ...) |
250 { | |
251 va_list ap; | |
252 | |
142 | 253 if (p != NULL) { |
254 place_printfrom(p); | |
255 fprintf(stderr, "%s:%u:%u: ", place_getname(p), | |
256 p->line, p->column); | |
257 } else { | |
258 fprintf(stderr, "%s: ", myprogname); | |
259 } | |
8 | 260 va_start(ap, fmt); |
261 vfprintf(stderr, fmt, ap); | |
262 va_end(ap); | |
263 fprintf(stderr, "\n"); | |
264 } | |
265 | |
266 void | |
267 complain_fail(void) | |
268 { | |
269 overall_failure = true; | |
270 } | |
271 | |
272 bool | |
273 complain_failed(void) | |
274 { | |
275 return overall_failure; | |
276 } | |
277 | |
10 | 278 //////////////////////////////////////////////////////////// |
279 // module init and cleanup | |
280 | |
281 void | |
282 place_init(void) | |
283 { | |
13 | 284 placefilearray_init(&placefiles); |
10 | 285 } |
286 | |
287 void | |
288 place_cleanup(void) | |
289 { | |
13 | 290 placefilearray_destroyall(&placefiles); |
291 placefilearray_cleanup(&placefiles); | |
10 | 292 } |