Mercurial > ~dholland > hg > tradcpp > index.cgi
annotate place.c @ 136:59680a727e9d
Improve previous.
Just in case we ever crash and reach cleanup() while processing an
-include foo option, take the array entry for it out of the array to
make sure it doesn't get freed twice. This case shouldn't be
reachable, but it's better to be safe.
author | David A. Holland |
---|---|
date | Tue, 09 Jul 2013 13:38:43 -0400 |
parents | 05d67dd74e1f |
children | 26ee741196d1 |
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 | |
53 //////////////////////////////////////////////////////////// | |
54 // seenfiles | |
55 | |
56 static | |
13 | 57 struct placefile * |
58 placefile_create(const struct place *from, const char *name, | |
59 bool fromsystemdir) | |
10 | 60 { |
13 | 61 struct placefile *pf; |
112 | 62 const char *s; |
63 size_t len; | |
10 | 64 |
13 | 65 pf = domalloc(sizeof(*pf)); |
66 pf->includedfrom = *from; | |
112 | 67 |
68 s = strrchr(name, '/'); | |
69 len = (s == NULL) ? 0 : s - name; | |
70 pf->dir = dostrndup(name, len); | |
71 | |
13 | 72 pf->name = dostrdup(name); |
73 pf->fromsystemdir = fromsystemdir; | |
112 | 74 |
28 | 75 if (from->file != NULL) { |
76 pf->depth = from->file->depth + 1; | |
77 } else { | |
78 pf->depth = 1; | |
79 } | |
13 | 80 return pf; |
10 | 81 } |
82 | |
83 static | |
84 void | |
13 | 85 placefile_destroy(struct placefile *pf) |
10 | 86 { |
39
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
87 dostrfree(pf->name); |
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
88 dofree(pf, sizeof(*pf)); |
10 | 89 } |
90 | |
13 | 91 DESTROYALL_ARRAY(placefile, ); |
10 | 92 |
112 | 93 const char * |
94 place_getparsedir(const struct place *place) | |
95 { | |
96 if (place->file == NULL) { | |
97 return "."; | |
98 } | |
99 return place->file->dir; | |
100 } | |
101 | |
13 | 102 const struct placefile * |
103 place_addfile(const struct place *place, const char *file, bool issystem) | |
10 | 104 { |
13 | 105 struct placefile *pf; |
10 | 106 |
13 | 107 pf = placefile_create(place, file, issystem); |
108 placefilearray_add(&placefiles, pf, NULL); | |
114
05d67dd74e1f
Reduce the maximum include depth from 128 to 120.
David A. Holland
parents:
112
diff
changeset
|
109 if (pf->depth > 120) { |
28 | 110 complain(place, "Maximum include nesting depth exceeded"); |
111 die(); | |
112 } | |
13 | 113 return pf; |
10 | 114 } |
115 | |
116 //////////////////////////////////////////////////////////// | |
117 // places | |
118 | |
8 | 119 void |
120 place_setnowhere(struct place *p) | |
121 { | |
12 | 122 p->type = P_NOWHERE; |
8 | 123 p->file = NULL; |
12 | 124 p->line = 0; |
8 | 125 p->column = 0; |
126 } | |
127 | |
128 void | |
129 place_setbuiltin(struct place *p, unsigned num) | |
130 { | |
12 | 131 p->type = P_BUILTIN; |
8 | 132 p->file = NULL; |
12 | 133 p->line = num; |
134 p->column = 1; | |
8 | 135 } |
136 | |
137 void | |
14 | 138 place_setcommandline(struct place *p, unsigned line, unsigned column) |
8 | 139 { |
14 | 140 p->type = P_COMMANDLINE; |
8 | 141 p->file = NULL; |
14 | 142 p->line = line; |
8 | 143 p->column = column; |
144 } | |
145 | |
14 | 146 void |
147 place_setfilestart(struct place *p, const struct placefile *pf) | |
148 { | |
28 | 149 p->type = P_FILE; |
14 | 150 p->file = pf; |
151 p->line = 1; | |
152 p->column = 1; | |
153 } | |
154 | |
8 | 155 static |
12 | 156 const char * |
157 place_getname(const struct place *p) | |
8 | 158 { |
12 | 159 switch (p->type) { |
160 case P_NOWHERE: return "<nowhere>"; | |
161 case P_BUILTIN: return "<built-in>"; | |
162 case P_COMMANDLINE: return "<command-line>"; | |
163 case P_FILE: return p->file->name; | |
8 | 164 } |
12 | 165 assert(0); |
166 return NULL; | |
8 | 167 } |
168 | |
169 static | |
170 void | |
171 place_printfrom(const struct place *p) | |
172 { | |
173 const struct place *from; | |
174 | |
95
1c0575f7dd46
Don't crash printing the commandline place.
David A. Holland
parents:
47
diff
changeset
|
175 if (p->file == NULL) { |
1c0575f7dd46
Don't crash printing the commandline place.
David A. Holland
parents:
47
diff
changeset
|
176 return; |
1c0575f7dd46
Don't crash printing the commandline place.
David A. Holland
parents:
47
diff
changeset
|
177 } |
10 | 178 from = &p->file->includedfrom; |
12 | 179 if (from->type != P_NOWHERE) { |
8 | 180 place_printfrom(from); |
12 | 181 fprintf(stderr, "In file included from %s:%u:%u:\n", |
182 place_getname(from), from->line, from->column); | |
8 | 183 } |
184 } | |
185 | |
10 | 186 //////////////////////////////////////////////////////////// |
187 // complaints | |
188 | |
8 | 189 void |
190 complain(const struct place *p, const char *fmt, ...) | |
191 { | |
192 va_list ap; | |
193 | |
12 | 194 place_printfrom(p); |
195 fprintf(stderr, "%s:%u:%u: ", place_getname(p), p->line, p->column); | |
8 | 196 va_start(ap, fmt); |
197 vfprintf(stderr, fmt, ap); | |
198 va_end(ap); | |
199 fprintf(stderr, "\n"); | |
200 } | |
201 | |
202 void | |
203 complain_fail(void) | |
204 { | |
205 overall_failure = true; | |
206 } | |
207 | |
208 bool | |
209 complain_failed(void) | |
210 { | |
211 return overall_failure; | |
212 } | |
213 | |
10 | 214 //////////////////////////////////////////////////////////// |
215 // module init and cleanup | |
216 | |
217 void | |
218 place_init(void) | |
219 { | |
13 | 220 placefilearray_init(&placefiles); |
10 | 221 } |
222 | |
223 void | |
224 place_cleanup(void) | |
225 { | |
13 | 226 placefilearray_destroyall(&placefiles); |
227 placefilearray_cleanup(&placefiles); | |
10 | 228 } |