Mercurial > ~dholland > hg > tradcpp > index.cgi
annotate place.c @ 185:16b4451e34b8
Add the ability to output line numbers, sort of.
It is enabled with the intentionally undocumented -p option (similar
to -P but reversed sense) and it might be vaguely useful but only
prints the line number when the file changes and may not get the line
numbers right.
author | David A. Holland |
---|---|
date | Fri, 12 Jun 2015 03:59:36 -0400 |
parents | a2f047301c15 |
children | 1d2bad7151f9 |
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 struct placefile * |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
106 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
|
107 { |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
108 unsigned i, num; |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
109 struct placefile *pf; |
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 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
|
112 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
|
113 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
|
114 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
|
115 !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
|
116 return pf; |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
117 } |
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 return NULL; |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
120 } |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
121 |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
122 void |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
123 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
|
124 { |
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 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
|
128 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
|
129 return; |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
130 } |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
131 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
|
132 if (pf == NULL) { |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
133 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
|
134 p->file->fromsystemdir); |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
135 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
|
136 } |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
137 p->file = pf; |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
138 } |
a2f047301c15
Replace Joerg's place_setfile with something that at least sort of works.
David A. Holland
parents:
160
diff
changeset
|
139 |
13 | 140 const struct placefile * |
141 place_addfile(const struct place *place, const char *file, bool issystem) | |
10 | 142 { |
13 | 143 struct placefile *pf; |
10 | 144 |
13 | 145 pf = placefile_create(place, file, issystem); |
146 placefilearray_add(&placefiles, pf, NULL); | |
114
05d67dd74e1f
Reduce the maximum include depth from 128 to 120.
David A. Holland
parents:
112
diff
changeset
|
147 if (pf->depth > 120) { |
28 | 148 complain(place, "Maximum include nesting depth exceeded"); |
149 die(); | |
150 } | |
13 | 151 return pf; |
10 | 152 } |
153 | |
154 //////////////////////////////////////////////////////////// | |
155 // places | |
156 | |
8 | 157 void |
158 place_setnowhere(struct place *p) | |
159 { | |
12 | 160 p->type = P_NOWHERE; |
8 | 161 p->file = NULL; |
12 | 162 p->line = 0; |
8 | 163 p->column = 0; |
164 } | |
165 | |
166 void | |
167 place_setbuiltin(struct place *p, unsigned num) | |
168 { | |
12 | 169 p->type = P_BUILTIN; |
8 | 170 p->file = NULL; |
12 | 171 p->line = num; |
172 p->column = 1; | |
8 | 173 } |
174 | |
175 void | |
14 | 176 place_setcommandline(struct place *p, unsigned line, unsigned column) |
8 | 177 { |
14 | 178 p->type = P_COMMANDLINE; |
8 | 179 p->file = NULL; |
14 | 180 p->line = line; |
8 | 181 p->column = column; |
182 } | |
183 | |
14 | 184 void |
185 place_setfilestart(struct place *p, const struct placefile *pf) | |
186 { | |
28 | 187 p->type = P_FILE; |
14 | 188 p->file = pf; |
189 p->line = 1; | |
190 p->column = 1; | |
191 } | |
192 | |
12 | 193 const char * |
194 place_getname(const struct place *p) | |
8 | 195 { |
12 | 196 switch (p->type) { |
197 case P_NOWHERE: return "<nowhere>"; | |
198 case P_BUILTIN: return "<built-in>"; | |
199 case P_COMMANDLINE: return "<command-line>"; | |
200 case P_FILE: return p->file->name; | |
8 | 201 } |
12 | 202 assert(0); |
203 return NULL; | |
8 | 204 } |
205 | |
185
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
206 bool |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
207 place_samefile(const struct place *a, const struct place *b) |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
208 { |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
209 if (a->type != b->type) { |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
210 return false; |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
211 } |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
212 if (a->file != b->file) { |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
213 return false; |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
214 } |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
215 return true; |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
216 } |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
217 |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
218 bool |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
219 place_eq(const struct place *a, const struct place *b) |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
220 { |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
221 if (!place_samefile(a, b)) { |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
222 return false; |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
223 } |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
224 if (a->line != b->line || a->column != b->column) { |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
225 return false; |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
226 } |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
227 return true; |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
228 } |
16b4451e34b8
Add the ability to output line numbers, sort of.
David A. Holland
parents:
176
diff
changeset
|
229 |
8 | 230 static |
231 void | |
232 place_printfrom(const struct place *p) | |
233 { | |
234 const struct place *from; | |
235 | |
95
1c0575f7dd46
Don't crash printing the commandline place.
David A. Holland
parents:
47
diff
changeset
|
236 if (p->file == NULL) { |
1c0575f7dd46
Don't crash printing the commandline place.
David A. Holland
parents:
47
diff
changeset
|
237 return; |
1c0575f7dd46
Don't crash printing the commandline place.
David A. Holland
parents:
47
diff
changeset
|
238 } |
10 | 239 from = &p->file->includedfrom; |
12 | 240 if (from->type != P_NOWHERE) { |
8 | 241 place_printfrom(from); |
12 | 242 fprintf(stderr, "In file included from %s:%u:%u:\n", |
243 place_getname(from), from->line, from->column); | |
8 | 244 } |
245 } | |
246 | |
10 | 247 //////////////////////////////////////////////////////////// |
248 // complaints | |
249 | |
8 | 250 void |
142 | 251 complain_init(const char *pn) |
252 { | |
253 myprogname = pn; | |
254 } | |
255 | |
256 void | |
8 | 257 complain(const struct place *p, const char *fmt, ...) |
258 { | |
259 va_list ap; | |
260 | |
142 | 261 if (p != NULL) { |
262 place_printfrom(p); | |
263 fprintf(stderr, "%s:%u:%u: ", place_getname(p), | |
264 p->line, p->column); | |
265 } else { | |
266 fprintf(stderr, "%s: ", myprogname); | |
267 } | |
8 | 268 va_start(ap, fmt); |
269 vfprintf(stderr, fmt, ap); | |
270 va_end(ap); | |
271 fprintf(stderr, "\n"); | |
272 } | |
273 | |
274 void | |
275 complain_fail(void) | |
276 { | |
277 overall_failure = true; | |
278 } | |
279 | |
280 bool | |
281 complain_failed(void) | |
282 { | |
283 return overall_failure; | |
284 } | |
285 | |
10 | 286 //////////////////////////////////////////////////////////// |
287 // module init and cleanup | |
288 | |
289 void | |
290 place_init(void) | |
291 { | |
13 | 292 placefilearray_init(&placefiles); |
10 | 293 } |
294 | |
295 void | |
296 place_cleanup(void) | |
297 { | |
13 | 298 placefilearray_destroyall(&placefiles); |
299 placefilearray_cleanup(&placefiles); | |
10 | 300 } |