4 * Dumps the parse tree as an xml document
6 * Copyright (C) 2007 Rob Taylor
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
32 #include <libxml/parser.h>
33 #include <libxml/tree.h>
35 #include "expression.h"
40 static xmlDocPtr doc
= NULL
; /* document pointer */
41 static xmlNodePtr root_node
= NULL
;/* root node pointer */
42 static int idcount
= 0;
44 static void examine_symbol(struct symbol
*sym
, xmlNodePtr node
);
46 static xmlAttrPtr
newProp(xmlNodePtr node
, const char *name
, const char *value
)
48 return xmlNewProp(node
, BAD_CAST name
, BAD_CAST value
);
51 static xmlAttrPtr
newNumProp(xmlNodePtr node
, const char *name
, int value
)
54 snprintf(buf
, 256, "%d", value
);
55 return newProp(node
, name
, buf
);
58 static xmlAttrPtr
newIdProp(xmlNodePtr node
, const char *name
, unsigned int id
)
61 snprintf(buf
, 256, "_%d", id
);
62 return newProp(node
, name
, buf
);
65 static xmlNodePtr
new_sym_node(struct symbol
*sym
, const char *name
, xmlNodePtr parent
)
68 const char *ident
= show_ident(sym
->ident
);
72 assert(parent
!= NULL
);
74 node
= xmlNewChild(parent
, NULL
, BAD_CAST
"symbol", NULL
);
76 newProp(node
, "type", name
);
78 newIdProp(node
, "id", idcount
);
80 if (sym
->ident
&& ident
)
81 newProp(node
, "ident", ident
);
82 newProp(node
, "file", stream_name(sym
->pos
.stream
));
84 newNumProp(node
, "start-line", sym
->pos
.line
);
85 newNumProp(node
, "start-col", sym
->pos
.pos
);
87 if (sym
->endpos
.type
) {
88 newNumProp(node
, "end-line", sym
->endpos
.line
);
89 newNumProp(node
, "end-col", sym
->endpos
.pos
);
90 if (sym
->pos
.stream
!= sym
->endpos
.stream
)
91 newProp(node
, "end-file", stream_name(sym
->endpos
.stream
));
100 static inline void examine_members(struct symbol_list
*list
, xmlNodePtr node
)
104 FOR_EACH_PTR(list
, sym
) {
105 examine_symbol(sym
, node
);
106 } END_FOR_EACH_PTR(sym
);
109 static void examine_modifiers(struct symbol
*sym
, xmlNodePtr node
)
111 const char *modifiers
[] = {
147 if (sym
->namespace != NS_SYMBOL
)
150 /*iterate over the 32 bit bitfield*/
151 for (i
=0; i
< 32; i
++) {
152 if ((sym
->ctype
.modifiers
& 1<<i
) && modifiers
[i
])
153 newProp(node
, modifiers
[i
], "1");
158 examine_layout(struct symbol
*sym
, xmlNodePtr node
)
160 examine_symbol_type(sym
);
162 newNumProp(node
, "bit-size", sym
->bit_size
);
163 newNumProp(node
, "alignment", sym
->ctype
.alignment
);
164 newNumProp(node
, "offset", sym
->offset
);
165 if (is_bitfield_type(sym
)) {
166 newNumProp(node
, "bit-offset", sym
->bit_offset
);
170 static void examine_symbol(struct symbol
*sym
, xmlNodePtr node
)
172 xmlNodePtr child
= NULL
;
178 if (sym
->aux
) /*already visited */
181 if (sym
->ident
&& sym
->ident
->reserved
)
184 child
= new_sym_node(sym
, get_type_name(sym
->type
), node
);
185 examine_modifiers(sym
, child
);
186 examine_layout(sym
, child
);
188 if (sym
->ctype
.base_type
) {
189 if ((base
= builtin_typename(sym
->ctype
.base_type
)) == NULL
) {
190 if (!sym
->ctype
.base_type
->aux
) {
191 examine_symbol(sym
->ctype
.base_type
, root_node
);
193 xmlNewProp(child
, BAD_CAST
"base-type",
194 xmlGetProp((xmlNodePtr
)sym
->ctype
.base_type
->aux
, BAD_CAST
"id"));
196 newProp(child
, "base-type-builtin", base
);
199 if (sym
->array_size
) {
200 /* TODO: modify get_expression_value to give error return */
201 array_size
= get_expression_value(sym
->array_size
);
202 newNumProp(child
, "array-size", array_size
);
209 examine_members(sym
->symbol_list
, child
);
212 examine_members(sym
->arguments
, child
);
214 case SYM_UNINITIALIZED
:
215 newProp(child
, "base-type-builtin", builtin_typename(sym
));
223 static struct position
*get_expansion_end (struct token
*token
)
225 struct token
*p1
, *p2
;
227 for (p1
=NULL
, p2
=NULL
;
229 p2
= p1
, p1
= token
, token
= token
->next
);
237 static void examine_macro(struct symbol
*sym
, xmlNodePtr node
)
239 struct position
*pos
;
241 /* this should probably go in the main codebase*/
242 pos
= get_expansion_end(sym
->expansion
);
246 sym
->endpos
= sym
->pos
;
248 new_sym_node(sym
, "macro", node
);
251 static void examine_namespace(struct symbol
*sym
)
253 if (sym
->ident
&& sym
->ident
->reserved
)
256 switch(sym
->namespace) {
258 examine_macro(sym
, root_node
);
263 examine_symbol(sym
, root_node
);
269 case NS_PREPROCESSOR
:
273 die("Unrecognised namespace type %d",sym
->namespace);
278 static int get_stream_id (const char *name
)
281 for (i
=0; i
<input_stream_nr
; i
++) {
282 if (strcmp(name
, stream_name(i
))==0)
288 static inline void examine_symbol_list(const char *file
, struct symbol_list
*list
)
291 int stream_id
= get_stream_id (file
);
295 FOR_EACH_PTR(list
, sym
) {
296 if (sym
->pos
.stream
== stream_id
)
297 examine_namespace(sym
);
298 } END_FOR_EACH_PTR(sym
);
301 int main(int argc
, char **argv
)
303 struct string_list
*filelist
= NULL
;
304 struct symbol_list
*symlist
= NULL
;
307 doc
= xmlNewDoc(BAD_CAST
"1.0");
308 root_node
= xmlNewNode(NULL
, BAD_CAST
"parse");
309 xmlDocSetRootElement(doc
, root_node
);
311 /* - A DTD is probably unnecessary for something like this
313 dtd = xmlCreateIntSubset(doc, "parse", "http://www.kernel.org/pub/software/devel/sparse/parse.dtd" NULL, "parse.dtd");
315 ns = xmlNewNs (root_node, "http://www.kernel.org/pub/software/devel/sparse/parse.dtd", NULL);
317 xmlSetNs(root_node, ns);
319 symlist
= sparse_initialize(argc
, argv
, &filelist
);
321 FOR_EACH_PTR(filelist
, file
) {
322 examine_symbol_list(file
, symlist
);
323 sparse_keep_tokens(file
);
324 examine_symbol_list(file
, file_scope
->symbols
);
325 examine_symbol_list(file
, global_scope
->symbols
);
326 } END_FOR_EACH_PTR(file
);
329 xmlSaveFormatFileEnc("-", doc
, "UTF-8", 1);