Print this page
new smatch
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/tools/smatch/src/c2xml.c
+++ new/usr/src/tools/smatch/src/c2xml.c
1 1 /*
2 2 * Sparse c2xml
3 3 *
4 4 * Dumps the parse tree as an xml document
5 5 *
6 6 * Copyright (C) 2007 Rob Taylor
7 7 *
8 8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 9 * of this software and associated documentation files (the "Software"), to deal
10 10 * in the Software without restriction, including without limitation the rights
11 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 12 * copies of the Software, and to permit persons to whom the Software is
13 13 * furnished to do so, subject to the following conditions:
14 14 *
15 15 * The above copyright notice and this permission notice shall be included in
16 16 * all copies or substantial portions of the Software.
17 17 *
18 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 24 * THE SOFTWARE.
25 25 */
26 26 #include <stdlib.h>
27 27 #include <stdio.h>
28 28 #include <string.h>
29 29 #include <unistd.h>
30 30 #include <fcntl.h>
31 31 #include <assert.h>
32 32 #include <libxml/parser.h>
33 33 #include <libxml/tree.h>
34 34
35 35 #include "expression.h"
36 36 #include "parse.h"
37 37 #include "scope.h"
38 38 #include "symbol.h"
39 39
40 40 static xmlDocPtr doc = NULL; /* document pointer */
41 41 static xmlNodePtr root_node = NULL;/* root node pointer */
42 42 static int idcount = 0;
43 43
44 44 static void examine_symbol(struct symbol *sym, xmlNodePtr node);
45 45
46 46 static xmlAttrPtr newProp(xmlNodePtr node, const char *name, const char *value)
47 47 {
48 48 return xmlNewProp(node, BAD_CAST name, BAD_CAST value);
49 49 }
50 50
51 51 static xmlAttrPtr newNumProp(xmlNodePtr node, const char *name, int value)
52 52 {
53 53 char buf[256];
54 54 snprintf(buf, 256, "%d", value);
55 55 return newProp(node, name, buf);
56 56 }
57 57
58 58 static xmlAttrPtr newIdProp(xmlNodePtr node, const char *name, unsigned int id)
59 59 {
60 60 char buf[256];
61 61 snprintf(buf, 256, "_%d", id);
62 62 return newProp(node, name, buf);
63 63 }
64 64
65 65 static xmlNodePtr new_sym_node(struct symbol *sym, const char *name, xmlNodePtr parent)
66 66 {
67 67 xmlNodePtr node;
68 68 const char *ident = show_ident(sym->ident);
69 69
70 70 assert(name != NULL);
71 71 assert(sym != NULL);
72 72 assert(parent != NULL);
73 73
74 74 node = xmlNewChild(parent, NULL, BAD_CAST "symbol", NULL);
75 75
76 76 newProp(node, "type", name);
77 77
78 78 newIdProp(node, "id", idcount);
79 79
80 80 if (sym->ident && ident)
81 81 newProp(node, "ident", ident);
82 82 newProp(node, "file", stream_name(sym->pos.stream));
83 83
84 84 newNumProp(node, "start-line", sym->pos.line);
85 85 newNumProp(node, "start-col", sym->pos.pos);
86 86
87 87 if (sym->endpos.type) {
88 88 newNumProp(node, "end-line", sym->endpos.line);
89 89 newNumProp(node, "end-col", sym->endpos.pos);
90 90 if (sym->pos.stream != sym->endpos.stream)
91 91 newProp(node, "end-file", stream_name(sym->endpos.stream));
92 92 }
93 93 sym->aux = node;
94 94
95 95 idcount++;
96 96
97 97 return node;
98 98 }
99 99
100 100 static inline void examine_members(struct symbol_list *list, xmlNodePtr node)
101 101 {
102 102 struct symbol *sym;
103 103
104 104 FOR_EACH_PTR(list, sym) {
105 105 examine_symbol(sym, node);
106 106 } END_FOR_EACH_PTR(sym);
107 107 }
108 108
109 109 static void examine_modifiers(struct symbol *sym, xmlNodePtr node)
110 110 {
111 111 const char *modifiers[] = {
112 112 "auto",
113 113 "register",
114 114 "static",
115 115 "extern",
116 116 "const",
117 117 "volatile",
118 118 "signed",
119 119 "unsigned",
120 120 "char",
121 121 "short",
122 122 "long",
123 123 "long-long",
124 124 "typedef",
125 125 NULL,
126 126 NULL,
127 127 NULL,
128 128 NULL,
129 129 NULL,
130 130 "inline",
131 131 "addressable",
132 132 "nocast",
133 133 "noderef",
134 134 "accessed",
135 135 "toplevel",
136 136 "label",
137 137 "assigned",
138 138 "type-type",
139 139 "safe",
140 140 "user-type",
141 141 "force",
142 142 "explicitly-signed",
143 143 "bitwise"};
144 144
145 145 int i;
146 146
147 147 if (sym->namespace != NS_SYMBOL)
148 148 return;
149 149
150 150 /*iterate over the 32 bit bitfield*/
151 151 for (i=0; i < 32; i++) {
152 152 if ((sym->ctype.modifiers & 1<<i) && modifiers[i])
153 153 newProp(node, modifiers[i], "1");
154 154 }
155 155 }
156 156
157 157 static void
158 158 examine_layout(struct symbol *sym, xmlNodePtr node)
159 159 {
160 160 examine_symbol_type(sym);
161 161
162 162 newNumProp(node, "bit-size", sym->bit_size);
163 163 newNumProp(node, "alignment", sym->ctype.alignment);
164 164 newNumProp(node, "offset", sym->offset);
165 165 if (is_bitfield_type(sym)) {
166 166 newNumProp(node, "bit-offset", sym->bit_offset);
167 167 }
168 168 }
169 169
170 170 static void examine_symbol(struct symbol *sym, xmlNodePtr node)
171 171 {
172 172 xmlNodePtr child = NULL;
173 173 const char *base;
174 174 int array_size;
175 175
176 176 if (!sym)
177 177 return;
178 178 if (sym->aux) /*already visited */
179 179 return;
180 180
181 181 if (sym->ident && sym->ident->reserved)
182 182 return;
183 183
184 184 child = new_sym_node(sym, get_type_name(sym->type), node);
185 185 examine_modifiers(sym, child);
186 186 examine_layout(sym, child);
187 187
188 188 if (sym->ctype.base_type) {
189 189 if ((base = builtin_typename(sym->ctype.base_type)) == NULL) {
190 190 if (!sym->ctype.base_type->aux) {
191 191 examine_symbol(sym->ctype.base_type, root_node);
192 192 }
193 193 xmlNewProp(child, BAD_CAST "base-type",
194 194 xmlGetProp((xmlNodePtr)sym->ctype.base_type->aux, BAD_CAST "id"));
195 195 } else {
196 196 newProp(child, "base-type-builtin", base);
197 197 }
198 198 }
199 199 if (sym->array_size) {
200 200 /* TODO: modify get_expression_value to give error return */
201 201 array_size = get_expression_value(sym->array_size);
202 202 newNumProp(child, "array-size", array_size);
203 203 }
204 204
205 205
206 206 switch (sym->type) {
207 207 case SYM_STRUCT:
208 208 case SYM_UNION:
209 209 examine_members(sym->symbol_list, child);
210 210 break;
211 211 case SYM_FN:
212 212 examine_members(sym->arguments, child);
213 213 break;
214 214 case SYM_UNINITIALIZED:
215 215 newProp(child, "base-type-builtin", builtin_typename(sym));
216 216 break;
217 217 default:
218 218 break;
219 219 }
220 220 return;
221 221 }
222 222
223 223 static struct position *get_expansion_end (struct token *token)
224 224 {
225 225 struct token *p1, *p2;
226 226
227 227 for (p1=NULL, p2=NULL;
228 228 !eof_token(token);
229 229 p2 = p1, p1 = token, token = token->next);
230 230
231 231 if (p2)
232 232 return &(p2->pos);
233 233 else
234 234 return NULL;
235 235 }
236 236
237 237 static void examine_macro(struct symbol *sym, xmlNodePtr node)
238 238 {
239 239 struct position *pos;
240 240
241 241 /* this should probably go in the main codebase*/
242 242 pos = get_expansion_end(sym->expansion);
243 243 if (pos)
244 244 sym->endpos = *pos;
245 245 else
246 246 sym->endpos = sym->pos;
247 247
248 248 new_sym_node(sym, "macro", node);
249 249 }
250 250
251 251 static void examine_namespace(struct symbol *sym)
252 252 {
253 253 if (sym->ident && sym->ident->reserved)
254 254 return;
255 255
256 256 switch(sym->namespace) {
257 257 case NS_MACRO:
258 258 examine_macro(sym, root_node);
259 259 break;
260 260 case NS_TYPEDEF:
261 261 case NS_STRUCT:
262 262 case NS_SYMBOL:
263 263 examine_symbol(sym, root_node);
264 264 break;
265 265 case NS_NONE:
266 266 case NS_LABEL:
267 267 case NS_ITERATOR:
268 268 case NS_UNDEF:
269 269 case NS_PREPROCESSOR:
270 270 case NS_KEYWORD:
271 271 break;
272 272 default:
273 273 die("Unrecognised namespace type %d",sym->namespace);
274 274 }
275 275
276 276 }
277 277
278 278 static int get_stream_id (const char *name)
279 279 {
280 280 int i;
281 281 for (i=0; i<input_stream_nr; i++) {
282 282 if (strcmp(name, stream_name(i))==0)
283 283 return i;
284 284 }
285 285 return -1;
286 286 }
287 287
288 288 static inline void examine_symbol_list(const char *file, struct symbol_list *list)
289 289 {
290 290 struct symbol *sym;
291 291 int stream_id = get_stream_id (file);
292 292
293 293 if (!list)
294 294 return;
295 295 FOR_EACH_PTR(list, sym) {
296 296 if (sym->pos.stream == stream_id)
297 297 examine_namespace(sym);
298 298 } END_FOR_EACH_PTR(sym);
299 299 }
300 300
301 301 int main(int argc, char **argv)
302 302 {
303 303 struct string_list *filelist = NULL;
304 304 struct symbol_list *symlist = NULL;
305 305 char *file;
306 306
307 307 doc = xmlNewDoc(BAD_CAST "1.0");
308 308 root_node = xmlNewNode(NULL, BAD_CAST "parse");
309 309 xmlDocSetRootElement(doc, root_node);
310 310
↓ open down ↓ |
310 lines elided |
↑ open up ↑ |
311 311 /* - A DTD is probably unnecessary for something like this
312 312
313 313 dtd = xmlCreateIntSubset(doc, "parse", "http://www.kernel.org/pub/software/devel/sparse/parse.dtd" NULL, "parse.dtd");
314 314
315 315 ns = xmlNewNs (root_node, "http://www.kernel.org/pub/software/devel/sparse/parse.dtd", NULL);
316 316
317 317 xmlSetNs(root_node, ns);
318 318 */
319 319 symlist = sparse_initialize(argc, argv, &filelist);
320 320
321 - FOR_EACH_PTR_NOTAG(filelist, file) {
321 + FOR_EACH_PTR(filelist, file) {
322 322 examine_symbol_list(file, symlist);
323 323 sparse_keep_tokens(file);
324 324 examine_symbol_list(file, file_scope->symbols);
325 325 examine_symbol_list(file, global_scope->symbols);
326 - } END_FOR_EACH_PTR_NOTAG(file);
326 + } END_FOR_EACH_PTR(file);
327 327
328 328
329 329 xmlSaveFormatFileEnc("-", doc, "UTF-8", 1);
330 330 xmlFreeDoc(doc);
331 331 xmlCleanupParser();
332 332
333 333 return 0;
334 334 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX