/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- emalloc
- print_usage
- process_args
- init
- final
- count_children
- search_sibling
- create_dir_table
- delete_dir_table
- create_file_table
- create_line_table
- create_comp_unit_table
- create_abbrev_table
- do_src2html
- href_info
- href_info2
- href_macinfo
- href_macinfo2
- href_src1
- href_src2
- a_name
- eval_xpath
- get_child
- get_tag
- get_attr
- get_attr_value
- get_attr_value_ref
- get_attr_desc
- get_type
- get_params
- get_subscript
- get_comp_unit
- get_filename_by_char
- get_filename_by_node
- get_filename_by_int
- get_pathname_by_char
- get_pathname_by_node
- get_pathname_by_int
- get_line
- get_name
- type_to_string
- base_type_to_string
- array_type_to_string
- ptr_type_to_string
- func_type_to_string
- volatile_to_string
- const_to_string
- struct_union_to_string
- struct_to_string
- union_to_string
- members_to_string
- enum_to_string
- enum_constants_to_string
- output_indent
- visit_all_children
- output_debug_info_top
- output_debug_info
- output_compile_unit
- output_subprogram
- output_lexical_block
- output_variable
- output_label
- output_typedef
- output_enum
- output_enum_constants
- output_struct_union
- output_struct
- output_union
- output_members
- output_all_structs
- output_all_unions
- output_all_typedefs
- output_all_enum_tags
- output_all_enum_consts
- output_all_labels
- output_all_functions
- output_all_variables
- output_all_files
- get_macinfo_id
- output_all_macros
- main
1 /*
2 dxref - a tiny cross referencer using DWARF2-XML
3 Copyright (C) 2003, 2004, by gondow@jaist.ac.jp, All rights reserved.
4 $Id: dxref.c,v 1.13 2004/01/20 14:22:10 gondow Exp gondow $
5 */
6 /* ======================================================================== */
7 #include <stdio.h> <stdio.h>
8 #include <stdlib.h> <stdlib.h>
9 #include <assert.h> <assert.h>
10 #include <string.h> <string.h>
11 #include <unistd.h> <unistd.h>
12
13 #include <libxml/parser.h> <parser.h>
14 #include <libxml/xpath.h> <xpath.h>
15 #include <libxml/tree.h>
16 #include <libxml/debugXML.h> <debugXML.h>
17
18 #define BUFLEN 8192 <BUFLEN>
19
20 #define TARGET_MAIN "target=\"main\"" <TARGET_MAIN>
21 #define TARGET_SRC "target=\"src\"" <TARGET_SRC>
22 #define COMM_BEGIN "<font color=\"red\">/* " <COMM_BEGIN>
23 #define COMM_END " */</font>" <COMM_END>
24
25 #define DEFAULT_DIR "./HTML/" <DEFAULT_DIR>
26 #define WORKING_DIR "./HTML/dxref.files/" <WORKING_DIR>
27 #if 0
28 #define XREF_MAIN "dxref_main.html"
29 #endif
30 #define XREF_INFO "dxref_info.html" <XREF_INFO>
31 #define XREF_MACINFO "dxref_macinfo.html" <XREF_MACINFO>
32 #define XREF_INDEX "dxref_index.html" <XREF_INDEX>
33 #define XREF_STRUCTS1 "dxref_structs1.html" <XREF_STRUCTS1>
34 #define XREF_STRUCTS2 "dxref_structs2.html" <XREF_STRUCTS2>
35 #define XREF_UNIONS1 "dxref_unions1.html" <XREF_UNIONS1>
36 #define XREF_UNIONS2 "dxref_unions2.html" <XREF_UNIONS2>
37 #define XREF_TYPEDEFS1 "dxref_typedefs1.html" <XREF_TYPEDEFS1>
38 #define XREF_TYPEDEFS2 "dxref_typedefs2.html" <XREF_TYPEDEFS2>
39 #define XREF_ENUM_TAGS1 "dxref_enum_tags1.html" <XREF_ENUM_TAGS1>
40 #define XREF_ENUM_TAGS2 "dxref_enum_tags2.html" <XREF_ENUM_TAGS2>
41 #define XREF_ENUM_CONSTS1 "dxref_enum_consts1.html" <XREF_ENUM_CONSTS1>
42 #define XREF_ENUM_CONSTS2 "dxref_enum_consts2.html" <XREF_ENUM_CONSTS2>
43 #define XREF_LABELS1 "dxref_labels1.html" <XREF_LABELS1>
44 #define XREF_LABELS2 "dxref_labels2.html" <XREF_LABELS2>
45 #define XREF_FUNCTIONS1 "dxref_functions1.html" <XREF_FUNCTIONS1>
46 #define XREF_FUNCTIONS2 "dxref_functions2.html" <XREF_FUNCTIONS2>
47 #define XREF_VARIABLES1 "dxref_variables1.html" <XREF_VARIABLES1>
48 #define XREF_VARIABLES2 "dxref_variables2.html" <XREF_VARIABLES2>
49 #define XREF_MACROS1 "dxref_macros1.html" <XREF_MACROS1>
50 #define XREF_MACROS2 "dxref_macros2.html" <XREF_MACROS2>
51 #define XREF_MACROS3 "dxref_macros3.html" <XREF_MACROS3>
52 #define XREF_FILES1 "dxref_files1.html" <XREF_FILES1>
53 #define XREF_FILES2 "dxref_files2.html" <XREF_FILES2>
54
55 /* ====================================================================== */
56 static struct {
57 int src2html;
58 int num_files;
59 char **files;
60 int verbose;
61 } args = { <??> <args>
62 0, /* src2html */
63 0, /* num_files */
64 NULL,/* files */
65 0 /* verbose */
66 };
67
68 struct comp_unit { <comp_unit>
69 char *info_offset;
70 unsigned long info_offset2;
71 char *macinfo_offset;
72 char *line_offset;
73 int n_file;
74 struct file *file; /* array */ <file>
75 int n_line;
76 struct line *line; /* array */ <line>
77 };
78
79 struct file {
80 char *filename;
81 char *pathname;
82 };
83
84 struct line {
85 unsigned long addr;
86 int line;
87 struct file *file;
88 };
89
90 struct abbrev_entry { <abbrev_entry>
91 int number;
92 char *upper_bound_form;
93 };
94 /* ====================================================================== */
95 static xmlDocPtr xml_doc = NULL; <xml_doc>
96 static xmlNodePtr xml_root = NULL; <xml_root>
97 static int indent_depth = 0; <indent_depth>
98 static int n_comp_unit; <n_comp_unit>
99 static struct comp_unit *comp_unit; <comp_unit>
100 static struct abbrev_entry *abbrev_table; <abbrev_table>
101 static int eval_xpath_debug = 0; <eval_xpath_debug>
102 /* ====================================================================== */
103 static void *emalloc (size_t size);
104 static void print_usage (void);
105 static void process_args (int argc, char *argv []);
106 static void init (void);
107 static void final (void);
108 static int count_children (xmlNodePtr node, char *tag);
109 static xmlNodePtr search_sibling (xmlNodePtr node, char *tag);
110 static char **create_dir_table (xmlNodePtr node);
111 static void delete_dir_table (char **dir_table);
112 static struct file *create_file_table (xmlNodePtr node, char **dir_table,
113 int *n_file);
114 static struct line *create_line_table (xmlNodePtr node,
115 struct file *file_table, int *n_line);
116 static void create_comp_unit_table (void);
117 static void create_abbrev_table (void);
118 static void do_src2html (void);
119
120 static char *href_info (char *id, char *title);
121 static char *href_info2 (char *id, char *title, char *title2);
122 static char *href_macinfo (char *id, char *title);
123 static char *href_macinfo2 (char *id, char *title, char *title2);
124 static char *href_src1 (char *pathname, char *line, char *title);
125 static char *href_src2 (char *pathname, char *line, char *title);
126 static char *a_name (char *id);
127
128 static xmlNodeSetPtr eval_xpath (char *xpath, xmlNodePtr from,
129 void **free_p, int *num);
130 static inline char *get_child (char *elem, char *name, char *attr,
131 xmlNodePtr from);
132 static inline char *get_tag (char *name, char *attr, xmlNodePtr from);
133 static inline char *get_attr (char *name, char *attr, xmlNodePtr from);
134 static inline char *get_attr_value (char *xpath, xmlNodePtr from);
135 static inline char *get_attr_value_ref (char *name, xmlNodePtr from);
136 static inline char *get_attr_desc (char *xpath, xmlNodePtr from);
137
138 static char *get_type (xmlNodePtr node);
139 static char *get_params (xmlNodePtr node);
140 static char *get_subscript (xmlNodePtr node);
141 static int get_comp_unit (xmlNodePtr node);
142 static char *get_filename_by_char (int n_comp, char *file_num);
143 static char *get_filename_by_node (xmlNodePtr node, char *file_num);
144 static char *get_filename_by_int (int n_comp, int file_num);
145 static char *get_pathname_by_char (int n_comp, char *file_num);
146 static char *get_pathname_by_node (xmlNodePtr node, char *file_num);
147 static char *get_pathname_by_int (int n_comp, int file_num);
148 static char *get_line (char *line);
149 static char *get_name (char *name);
150
151 static char *type_to_string (xmlNodePtr node);
152 static char *base_type_to_string (xmlNodePtr node);
153 static char *array_type_to_string (xmlNodePtr node);
154 static char *ptr_type_to_string (xmlNodePtr node);
155 static char *func_type_to_string (xmlNodePtr node);
156 static char *volatile_to_string (xmlNodePtr node);
157 static char *const_to_string (xmlNodePtr node);
158 static char *struct_union_to_string (xmlNodePtr node, char *which);
159 static char *struct_to_string (xmlNodePtr node);
160 static char *union_to_string (xmlNodePtr node);
161 static char *typedef_to_string (xmlNodePtr node);
162 static char *enum_to_string (xmlNodePtr node);
163 static char *enum_constants_to_string (xmlNodePtr node);
164 static char *members_to_string (xmlNodePtr node);
165
166 static void visit_all_children (xmlNodePtr node, FILE *fp);
167 static void output_indent (FILE *fp);
168 static void output_debug_info_top (void);
169 static void output_debug_info (xmlNodePtr node, FILE *fp);
170 static void output_compile_unit (xmlNodePtr node, FILE *fp);
171 static void output_subprogram (xmlNodePtr node, FILE *fp);
172 static void output_lexical_block (xmlNodePtr node, FILE *fp);
173 static void output_variable (xmlNodePtr node, FILE *fp);
174 static void output_label (xmlNodePtr node, FILE *fp);
175 static void output_typedef (xmlNodePtr node, FILE *fp);
176 static void output_enum (xmlNodePtr node, FILE *fp);
177 static void output_enum_constants (xmlNodePtr node, FILE *fp,
178 char *pathname, char *line);
179 static void output_struct_union (xmlNodePtr node, FILE *fp, char *which);
180 static void output_struct (xmlNodePtr node, FILE *fp);
181 static void output_union (xmlNodePtr node, FILE *fp);
182 static void output_members (xmlNodePtr node, FILE *fp);
183
184 static void output_all_structs (void);
185 static void output_all_unions (void);
186
187 static void output_all_typedefs (void);
188 static void output_all_enums (void);
189 static void output_all_labels (void);
190 static void output_all_functions (void);
191 static void output_all_variables (void);
192 static void output_all_files (void);
193
194 static char *get_macinfo_id (void);
195 static void output_all_macros (void);
196 /* ====================================================================== */
197 static void *
198 emalloc (size_t size)
199 { <emalloc>
200 void *p = malloc (size); <p>
201 if (p == NULL) perror ("malloc");
202 return p;
203 }
204
205 static void
206 print_usage (void)
207 { <print_usage>
208 fprintf (stderr,
209 "usage : dxref [options] file.xml\n"
210 "options:\n"
211 " --src2html translate sources to htmls\n"
212 " --verbose tells what is being doing\n"
213 " --help prints this usage\n"
214 );
215 }
216
217 static void
218 process_args (int argc, char *argv [])
219 { <process_args>
220 int i; <i>
221 char *s; <s>
222
223 for (i = 1; i < argc; i++) {
224 if (argv [i][0] != '-') { /* filenames */
225 args.files = &argv [i];
226 args.num_files = argc - i;
227 break;
228 } else if (!strcmp (argv [i], "--src2html")) {
229 args.src2html = 1;
230 } else if (!strcmp (argv [i], "--verbose")) {
231 args.verbose = 1;
232 } else if (!strcmp (argv [i], "--help")) {
233 print_usage ();
234 exit (1);
235 } else {
236 /* unknown option */
237 fprintf (stderr, "unknown option: %s\n", argv [i]);
238 print_usage ();
239 exit (1);
240 }
241 }
242
243 if (args.num_files <= 0) {
244 print_usage ();
245 exit (1);
246 }
247 }
248
249 static void
250 init (void)
251 { <init>
252 char *xml; <xml>
253
254 assert (args.num_files >= 1);
255 xml = args.files [0]; /* currently, only one file is processed */
256 xmlDoValidityCheckingDefaultValue = 1;
257 xmlSubstituteEntitiesDefault (1); /* to substitute entity refs. (<) */
258
259 if (!strcmp (".gz", xml + strlen (xml) -3)) { /* gzipped file */
260 FILE *fp; <fp>
261 char buf[BUFLEN], *gunzip_file; <buf> <gunzip_file>
262 int ret; <ret>
263
264 gunzip_file = tmpnam (NULL);
265 snprintf (buf, sizeof (buf), "gunzip -c %s > %s", xml, gunzip_file);
266 ret = system (buf);
267 if (ret == -1) {
268 perror ("system"); exit (1);
269 }
270 fp = fopen (gunzip_file, "r");
271 xml_doc = xmlParseFile(gunzip_file);
272 unlink (gunzip_file);
273 } else { /* not gzipped file */
274 xml_doc = xmlParseFile(xml);
275 }
276 xml_root = xmlDocGetRootElement (xml_doc);
277 xmlXPathInit();
278 mkdir (DEFAULT_DIR, 0755); <mkdir>
279 mkdir (WORKING_DIR, 0755);
280 create_comp_unit_table ();
281 create_abbrev_table ();
282
283 /* must be after create_comp_unit_table (); */
284 if (args.src2html) do_src2html ();
285 }
286
287 static void
288 final (void)
289 { <final>
290 system ("dxref.csh");
291 }
292
293 static int
294 count_children (xmlNodePtr node, char *tag)
295 { <count_children>
296 int n = 0; <n>
297 xmlNodePtr child; <child>
298
299 for (child = node->children; child != NULL; child = child->next) {
300 if (child->type == XML_ELEMENT_NODE && !strcmp (child->name, tag))
301 n++;
302 }
303 return n;
304 }
305
306 static xmlNodePtr
307 search_sibling (xmlNodePtr node, char *tag)
308 { <search_sibling>
309 while (node != NULL) {
310 if (node->type == XML_ELEMENT_NODE && !strcmp (node->name, tag))
311 return node;
312 node = node->next;
313 }
314 return NULL; /* not found */
315 }
316
317 static char **
318 create_dir_table (xmlNodePtr node)
319 { <create_dir_table>
320 int i, n_dir; <i> <n_dir>
321 xmlNodePtr child; <child>
322 char **dir_table; <dir_table>
323
324 assert (node != NULL);
325 assert (node->type == XML_ELEMENT_NODE);
326 assert (!strcmp (node->name, "include_directories"));
327
328 n_dir = count_children (node, "directory");
329 /* +1 for 1-origin, +1 for NULL-termination */
330 dir_table = emalloc (sizeof (char *) * (n_dir + 2));
331 dir_table [0] = "!!!not used entry";
332 i = 1;
333 for (child = node->children; child != NULL; child = child->next) {
334 if (child->type == XML_ELEMENT_NODE
335 && !strcmp (child->name, "directory"))
336 dir_table [i++] = xmlNodeGetContent (child);
337 }
338 dir_table [i] = NULL;
339
340 return dir_table;
341 }
342
343 static void
344 delete_dir_table (char **dir_table)
345 { <delete_dir_table>
346 int i; <i>
347
348 if (dir_table == NULL)
349 return;
350
351 for (i = 1; dir_table [i] != NULL; i++) {
352 xmlFree (dir_table [i]);
353 }
354 free (dir_table);
355 }
356
357 static struct file *
358 create_file_table (xmlNodePtr node, char **dir_table, int *n_file)
359 { <create_file_table>
360 int i; <i>
361 struct file *file_table; <file_table>
362 xmlNodePtr child; <child>
363 char buf [BUFLEN]; <buf>
364
365 *n_file = count_children (node, "file");
366 /* +1 for 1-origin */
367 file_table = emalloc (sizeof (struct file) * *n_file + 1);
368
369 file_table [0].filename = "!!!unused entry";
370 file_table [0].pathname = "!!!unused entry";
371 i = 1;
372 for (child = node->children; child != NULL; child = child->next) {
373 if (child->type == XML_ELEMENT_NODE && !strcmp (child->name, "file")) {
374 char *dir_index = xmlGetProp (child, "directory"); <dir_index>
375 int d = atoi (dir_index); <d>
376 xmlFree (dir_index);
377
378 file_table [i].filename = xmlNodeGetContent (child);
379
380 if (d == 0) {
381 file_table [i].pathname = file_table [i].filename;
382 } else {
383 snprintf (buf, sizeof (buf), "%s/%s",
384 dir_table [d], file_table [i].filename);
385 file_table [i].pathname = strdup (buf);
386 }
387 i++;
388 }
389 }
390 assert (i == *n_file + 1);
391 return file_table;
392 }
393
394 static struct line *
395 create_line_table (xmlNodePtr node, struct file *file_table, int *n_line)
396 { <create_line_table>
397 int i; <i>
398 struct line *line_table; <line_table>
399 xmlNodePtr child; <child>
400
401 *n_line = count_children (node, "line");
402 line_table = emalloc (sizeof (struct line) * *n_line);
403
404 i = 0;
405 for (child = node->children; child != NULL; child = child->next) {
406 if (child->type == XML_ELEMENT_NODE && !strcmp (child->name, "line")) {
407 char *addr = xmlGetProp (child, "address"); <addr>
408 char *line = xmlGetProp (child, "line"); <line>
409 char *file = xmlGetProp (child, "file"); <file>
410
411 line_table [i].addr = atoll (addr);
412 line_table [i].line = atoi (line);
413 line_table [i].file = &file_table [atoi (file)];
414
415 xmlFree (addr);
416 xmlFree (line);
417 xmlFree (file);
418 i++;
419 }
420 }
421 assert (i == *n_line);
422 return line_table;
423 }
424
425 static void
426 create_comp_unit_table (void)
427 { <create_comp_unit_table>
428 int i; <i>
429 char *xpath = "//section[@name='.debug_info']/tag[@name='DW_TAG_compile_unit']"; <xpath>
430 void *free_p; <free_p>
431
432 xmlNodeSetPtr result = eval_xpath (xpath, xml_root, &free_p, <result>
433 &n_comp_unit);
434 assert (n_comp_unit >= 1);
435 comp_unit = emalloc (sizeof (struct comp_unit) * n_comp_unit);
436
437 /* store debug line info. etc for each compilation_unit */
438 for (i = 0; i < n_comp_unit; i++) {
439 xmlNodePtr node = result->nodeTab [i]; <node>
440 char **dir_table; <dir_table>
441 xmlNodePtr line_node, line_node2; <line_node> <line_node2>
442 char buf [BUFLEN]; <buf>
443 xmlAttrPtr attr; <attr>
444 int ret; <ret>
445
446 char *info_offset = xmlGetProp (node, "offset"); <info_offset>
447 char *macro_info = get_attr_value ("DW_AT_macro_info", node); <macro_info>
448 char *stmt_list = get_attr_value ("DW_AT_stmt_list", node); <stmt_list>
449
450 assert (info_offset != NULL);
451 assert (macro_info != NULL);
452 assert (stmt_list != NULL);
453
454 comp_unit [i].info_offset = info_offset;
455 ret = sscanf (info_offset, "info:%ld", &comp_unit [i].info_offset2);
456 if (ret != 1)
457 fprintf (stderr, "info_offset = %s\n", info_offset);
458 assert (ret == 1);
459 snprintf (buf, sizeof (buf), "macinfo:%s", macro_info);
460 comp_unit [i].macinfo_offset = strdup (buf);
461 snprintf (buf, sizeof (buf), "line:%s", stmt_list);
462 comp_unit [i].line_offset = strdup (buf);
463
464 attr = xmlGetID (xml_doc, comp_unit [i].line_offset);
465 assert (attr != NULL);
466 line_node = attr->parent;
467
468 line_node2 = search_sibling (line_node, "include_directories");
469 if (line_node2 == NULL) { /* no directory info. */
470 dir_table = NULL;
471 } else {
472 line_node = line_node2;
473 dir_table = create_dir_table (line_node);
474 }
475 line_node = search_sibling (line_node, "file_names");
476 assert (node != NULL);
477 comp_unit [i].file = create_file_table (line_node, dir_table,
478 &comp_unit [i].n_file);
479 delete_dir_table (dir_table);
480 #if 1
481 comp_unit [i].line = NULL;
482 #else
483 /* currently, dxref does not use `comp_unit [i].line', so
484 I commented out the following. */
485 line_node = search_sibling (line_node, "lines");
486 assert (node != NULL);
487 comp_unit [i].line = create_line_table (line_node, comp_unit [i].file,
488 &comp_unit [i].n_line);
489 #endif
490 xmlFree (macro_info);
491 xmlFree (stmt_list);
492 }
493 }
494
495 static void
496 create_abbrev_table (void)
497 { <create_abbrev_table>
498 int i, n; <i> <n>
499 char *xpath = "//section[@name='.debug_abbrev']/tag_abbrev" <xpath>
500 "[@name='DW_TAG_subrange_type']/"
501 "attribute_abbrev[@name='DW_AT_upper_bound']";
502 void *free_p; <free_p>
503 xmlNodeSetPtr result = eval_xpath (xpath, xml_root, &free_p, &n); <result>
504
505 abbrev_table = emalloc (sizeof (struct abbrev_entry) * (n + 1));
506 for (i = 0; i < n; i++) {
507 xmlNodePtr node = result->nodeTab [i]; <node>
508 char *number = xmlGetProp (node->parent, "number"); <number>
509 abbrev_table [i].number = atoi (number);
510 xmlFree (number);
511 abbrev_table [i].upper_bound_form = xmlGetProp (node, "type");
512 }
513 abbrev_table [n].number = -1; /* sentinel */
514 abbrev_table [n].upper_bound_form = NULL;
515 free (free_p);
516 }
517
518 static void
519 do_src2html (void)
520 { <do_src2html>
521 int i, j, ret; <i> <j> <ret>
522 char buf [BUFLEN]; <buf>
523
524 if (args.verbose) printf ("translating sources to htmls\n");
525 for (i = 0; i < n_comp_unit; i++) {
526 for (j = 1; j <= comp_unit [i].n_file; j++) {
527 snprintf (buf, sizeof (buf), "PATH=.:$PATH; src2html %s",
528 comp_unit [i].file [j].pathname);
529 ret = system (buf);
530 if (ret == -1) { perror ("system"); exit (1); }
531 }
532 }
533 }
534
535 static char *
536 href_info (char *id, char *title)
537 { <href_info>
538 static char buf [BUFLEN]; <buf>
539 snprintf (buf, sizeof (buf), "<a href=\"" XREF_INFO "#%s\" "
540 TARGET_MAIN ">%s</a>", id, title);
541 return buf;
542 }
543
544 static char *
545 href_info2 (char *id, char *title, char *title2)
546 { <href_info2>
547 static char buf [BUFLEN]; <buf>
548 snprintf (buf, sizeof (buf), "<a href=\"" XREF_INFO "#%s\" "
549 TARGET_MAIN ">%s %s</a>", id, title, title2);
550 return buf;
551 }
552
553 static char *
554 href_macinfo (char *id, char *title)
555 { <href_macinfo>
556 static char buf [BUFLEN]; <buf>
557 snprintf (buf, sizeof (buf), "<a href=\"" XREF_MACINFO "#%s\" "
558 TARGET_MAIN ">%s</a>", id, title);
559 return buf;
560 }
561
562 static char *
563 href_macinfo2 (char *id, char *title, char *title2)
564 { <href_macinfo2>
565 static char buf [BUFLEN]; <buf>
566 snprintf (buf, sizeof (buf), "<a href=\"" XREF_MACINFO "#%s\" "
567 TARGET_MAIN ">%s %s</a>", id, title, title2);
568 return buf;
569 }
570
571 static char *
572 href_src1 (char *pathname, char *line, char *title)
573 { <href_src1>
574 static char buf [BUFLEN]; <buf>
575 snprintf (buf, sizeof (buf), "<a href=\"./%s.html#%s\" "
576 TARGET_SRC ">%s</a>", pathname, line, title);
577 return buf;
578 }
579
580 static char *
581 href_src2 (char *pathname, char *line, char *title)
582 { <href_src2>
583 static char buf [BUFLEN]; <buf>
584 snprintf (buf, sizeof (buf),
585 "<a href=\"./%s.html#%s\" " TARGET_SRC ">%s:%s</a>",
586 pathname, line, title, line);
587 return buf;
588 }
589
590 static char *
591 a_name (char *id)
592 { <a_name>
593 static char buf [BUFLEN]; <buf>
594 snprintf (buf, sizeof (buf), "<a name=\"%s\"/>", id);
595 return buf;
596 }
597
598 static xmlNodeSetPtr
599 eval_xpath (char *xpath, xmlNodePtr from, void **free_p, int *num)
600 { <eval_xpath>
601 xmlXPathObjectPtr result; <result>
602 xmlXPathContextPtr context; <context>
603
604 context = xmlXPathNewContext(xml_doc);
605 assert (context != NULL);
606 context->node = from;
607 result = xmlXPathEval (xpath, context);
608 xmlXPathFreeContext (context);
609 #if 0
610 if (args.verbose)
611 xmlXPathDebugDumpObject (stdout, result, 0);
612 #endif
613 if (num != NULL)
614 *num = xmlXPathNodeSetGetLength (result->nodesetval);
615 *free_p = result;
616 return result->nodesetval;
617 }
618
619 static inline char *
620 get_child (char *elem, char *name, char *attr, xmlNodePtr from)
621 { <get_child>
622 int i; <i>
623 xmlNodePtr node; <node>
624 char *attr_name; <attr_name>
625
626 assert (from->children != NULL);
627 for (node = from->children; node != NULL; node = node->next) {
628 if (node->type != XML_ELEMENT_NODE) continue;
629 if (strcmp (node->name, elem)) continue;
630 attr_name = xmlGetProp (node, "name");
631 if (strcmp (attr_name, name)) {
632 xmlFree (attr_name);
633 continue;
634 }
635 xmlFree (attr_name);
636 if (*attr == '@') {
637 attr++;
638 return xmlGetProp (node, attr);
639 } else {
640 xmlNodePtr child; <child>
641 for (child = node->children; child != NULL; child = child->next) {
642 if (child->type != XML_ELEMENT_NODE) continue;
643 if (strcmp (child->name, attr)) continue;
644 return xmlNodeGetContent (child);
645 }
646 return NULL;
647 }
648 }
649 return NULL;
650 }
651
652 static inline char *
653 get_tag (char *name, char *attr, xmlNodePtr from)
654 { <get_tag>
655 return get_child ("tag", name, attr, from);
656 }
657
658 static inline char *
659 get_attr (char *name, char *attr, xmlNodePtr from)
660 { <get_attr>
661 return get_child ("attribute", name, attr, from);
662 }
663
664 static inline char *
665 get_attr_value (char *name, xmlNodePtr from)
666 { <get_attr_value>
667 return get_attr (name, "@value", from);
668 }
669
670 static inline char *
671 get_attr_value_ref (char *name, xmlNodePtr from)
672 { <get_attr_value_ref>
673 return get_attr (name, "@value_ref", from);
674 }
675
676 static inline char *
677 get_attr_desc (char *name, xmlNodePtr from)
678 { <get_attr_desc>
679 return get_attr (name, "description", from);
680 }
681
682 static char *
683 get_type (xmlNodePtr node)
684 { <get_type>
685 char *type; <type>
686 char *type_id; <type_id>
687
688 type_id = get_attr_value_ref ("DW_AT_type", node);
689 if (type_id == NULL) {
690 type = strdup ("void %s");
691 } else {
692 xmlAttrPtr list = xmlGetID (xml_doc, type_id); <list>
693 assert (list != NULL);
694 type = type_to_string (list->parent);
695 }
696 xmlFree (type_id);
697 return type;
698 }
699
700 static char *
701 get_params (xmlNodePtr node)
702 { <get_params>
703 char *attr, *xpath; <attr> <xpath>
704 char buf [BUFLEN] = {'\0'}; <buf>
705 xmlNodeSetPtr result; <result>
706 int i, n; <i> <n>
707 void *free_p; <free_p>
708
709 assert (node->type == XML_ELEMENT_NODE);
710 assert (!strcmp (node->name, "tag"));
711 attr = xmlGetProp (node, "name");
712 assert (!strcmp (attr, "DW_TAG_subroutine_type")
713 || !strcmp (attr, "DW_TAG_subprogram"));
714 xmlFree (attr);
715
716 xpath = "tag[@name='DW_TAG_unspecified_parameters'"
717 " or @name='DW_TAG_formal_parameter']";
718 result = eval_xpath (xpath, node, &free_p, &n);
719
720 for (i = 0; i < n; i++) {
721 xmlNodePtr child = result->nodeTab [i]; <child>
722 char *attr = xmlGetProp (child, "name"); <attr>
723 if (!strcmp (attr, "DW_TAG_unspecified_parameters")) {
724 strncat (buf, (i == 0 ? "" : ", ..."), sizeof (buf));
725 } else if (!strcmp (attr, "DW_TAG_formal_parameter")) {
726 char buf2 [BUFLEN]; <buf2>
727 char *type = get_type (child); <type>
728 char *name = get_attr_value ("DW_AT_name", child); <name>
729 snprintf (buf2, sizeof (buf2), type, (name == NULL ? "" : name));
730 if (i != 0) strncat (buf, ", ", sizeof (buf));
731 strncat (buf, buf2, sizeof (buf));
732 free (type);
733 xmlFree (name);
734 } else {
735 assert (0); exit (1);
736 }
737 xmlFree (attr);
738 }
739
740 free (free_p);
741
742 if (n == 0)
743 snprintf (buf, sizeof (buf), "void");
744 return strdup (buf);
745 }
746
747 static char *
748 get_subscript (xmlNodePtr node)
749 { <get_subscript>
750 /* Note: A DW_AT_upper_bound's value means 2 possibilities:
751 (1) the maximum index value (e.g., 9 for 'int a[10]').
752 (2) the pointer to the (artificial) DW_TAG_variable that
753 holds an expression value for the array size.
754 Problem here is that artificial DW_TAG_variable does not
755 have a name, just a location. */
756 int i; <i>
757 char buf [BUFLEN]; <buf>
758 char *ret, *form = NULL; <ret> <form>
759 char *abbrev_num = get_tag ("DW_TAG_subrange_type", <abbrev_num>
760 "@abbrev_number", node);
761 if (abbrev_num == NULL) {
762 /* we cannot found the corresponding abbrev.
763 this might be a bug, but now just ignore it. */
764 return strdup ("");
765 }
766
767 for (i = 0; abbrev_table [i].number != -1; i++) {
768 if (abbrev_table [i].number == atoi (abbrev_num)) {
769 form = abbrev_table [i].upper_bound_form;
770 break;
771 }
772 }
773
774 xmlFree (abbrev_num);
775
776 if (form == NULL) {
777 ret = strdup (""); /* no subscript information */
778 } else if (!strncmp (form, "DW_FORM_ref", 11)) {
779 ret = "<em>exp</em>";
780 } else if (!strncmp (form, "DW_FORM_data", 12)) {
781 xmlNodePtr child, child2; <child> <child2>
782 char *upper_bound = NULL; <upper_bound>
783 char *attr; <attr>
784
785 for (child = node->children; child != NULL; child = child->next) {
786 if (child->type != XML_ELEMENT_NODE) continue;
787 if (strcmp (child->name, "tag")) continue;
788 attr = xmlGetProp (child, "name");
789 if (strcmp (attr, "DW_TAG_subrange_type")) {
790 xmlFree (attr);
791 continue;
792 }
793 xmlFree (attr);
794
795 for (child2 = child->children; child2 != NULL;
796 child2 = child2->next) {
797 if (child2->type != XML_ELEMENT_NODE) continue;
798 if (strcmp (child2->name, "attribute")) continue;
799 attr = xmlGetProp (child2, "name");
800 if (strcmp (attr, "DW_AT_upper_bound")) {
801 xmlFree (attr);
802 continue;
803 }
804 xmlFree (attr);
805 upper_bound = xmlGetProp (child2, "value");
806 break;
807 }
808 }
809 assert (upper_bound != NULL);
810 snprintf (buf, sizeof (buf), "%d", atoi (upper_bound) + 1);
811 xmlFree (upper_bound);
812 ret = buf;
813 } else {
814 assert (0); exit (1);
815 }
816 return strdup (ret);
817 }
818
819
820 static int
821 get_comp_unit (xmlNodePtr node)
822 { <get_comp_unit>
823 int i, ret; <i> <ret>
824 char *offset = xmlGetProp (node, "offset"); <offset>
825 unsigned long offset2; <offset2>
826
827 assert (offset != NULL);
828 ret = sscanf (offset, "info:%ld", &offset2);
829 assert (ret == 1);
830
831 for (i = 0; i < n_comp_unit; i++) {
832 if (offset2 < comp_unit [i].info_offset2)
833 break;
834 }
835 return i - 1;
836 }
837
838 static char *
839 get_filename_by_char (int n_comp, char *file_num)
840 { <get_filename_by_char>
841 if (file_num == NULL) {
842 return "??";
843 } else {
844 return get_filename_by_int (n_comp, atoi (file_num));
845 }
846 }
847
848 static char *
849 get_filename_by_node (xmlNodePtr node, char *file_num)
850 { <get_filename_by_node>
851 if (file_num == NULL) {
852 return "??";
853 } else {
854 int n_comp = get_comp_unit (node); <n_comp>
855 return get_filename_by_int (n_comp, atoi (file_num));
856 }
857 }
858
859 static char *
860 get_filename_by_int (int n_comp, int file_num)
861 { <get_filename_by_int>
862 assert (0 <= n_comp && n_comp < n_comp_unit);
863 assert (0 <= file_num && file_num <= comp_unit [n_comp].n_file);
864 if (file_num > 0) {
865 return comp_unit [n_comp].file [file_num].filename;
866 } else {
867 return "??";
868 }
869 }
870
871 static char *
872 get_pathname_by_char (int n_comp, char *file_num)
873 { <get_pathname_by_char>
874 if (file_num == NULL) {
875 return "??";
876 } else {
877 return get_pathname_by_int (n_comp, atoi (file_num));
878 }
879 }
880
881 static char *
882 get_pathname_by_node (xmlNodePtr node, char *file_num)
883 { <get_pathname_by_node>
884 if (file_num == NULL) {
885 return "??";
886 } else {
887 int n_comp = get_comp_unit (node); <n_comp>
888 return get_pathname_by_int (n_comp, atoi (file_num));
889 }
890 }
891
892 static char *
893 get_pathname_by_int (int n_comp, int file_num)
894 { <get_pathname_by_int>
895 assert (0 <= n_comp && n_comp < n_comp_unit);
896 assert (0 <= file_num && file_num <= comp_unit [n_comp].n_file);
897 if (file_num > 0) {
898 return comp_unit [n_comp].file [file_num].pathname;
899 } else {
900 return "??";
901 }
902 }
903
904 static char *
905 get_line (char *line)
906 { <get_line>
907 return (line == NULL ? "??" : line);
908 }
909
910 static char *
911 get_name (char *name)
912 { <get_name>
913 return (name == NULL ? "??" : name);
914 }
915
916 static char *
917 type_to_string (xmlNodePtr node)
918 { <type_to_string>
919 char *attr, *ret; <attr> <ret>
920 assert (node->type == XML_ELEMENT_NODE);
921 assert (!strcmp (node->name, "tag"));
922
923 attr = xmlGetProp (node, "name");
924
925 if (!strcmp (attr, "DW_TAG_array_type")) {
926 ret = array_type_to_string (node);
927 } else if (!strcmp (attr, "DW_TAG_base_type")) {
928 ret = base_type_to_string (node);
929 } else if (!strcmp (attr, "DW_TAG_pointer_type")) {
930 ret = ptr_type_to_string (node);
931 } else if (!strcmp (attr, "DW_TAG_subroutine_type")) {
932 ret = func_type_to_string (node);
933 } else if (!strcmp (attr, "DW_TAG_const_type")) {
934 ret = const_to_string (node);
935 } else if (!strcmp (attr, "DW_TAG_volatile_type")) {
936 ret = volatile_to_string (node);
937 } else if (!strcmp (attr, "DW_TAG_structure_type")) {
938 ret = struct_to_string (node);
939 } else if (!strcmp (attr, "DW_TAG_union_type")) {
940 ret = union_to_string (node);
941 } else if (!strcmp (attr, "DW_TAG_typedef")) {
942 ret = typedef_to_string (node);
943 } else if (!strcmp (attr, "DW_TAG_enumeration_type")) {
944 ret = enum_to_string (node);
945 #if 0
946 } else if (!strcmp (attr, "DW_TAG_member")) {
947 } else if (!strcmp (attr, "DW_TAG_subrange_type")) {
948 #endif
949 } else {
950 assert (0); exit (1);
951 }
952 xmlFree (attr);
953 return ret;
954 }
955 static char *
956 base_type_to_string (xmlNodePtr node)
957 { <base_type_to_string>
958 char buf [BUFLEN]; <buf>
959 char *type = get_attr_value ("DW_AT_name", node); <type>
960 if (type == NULL) {
961 snprintf (buf, sizeof (buf), "%s %%s", "void");
962 } else {
963 snprintf (buf, sizeof (buf), "%s %%s", type);
964 xmlFree (type);
965 }
966 return strdup (buf);
967 }
968
969 static char *
970 array_type_to_string (xmlNodePtr node)
971 { <array_type_to_string>
972 char buf [BUFLEN], buf2 [BUFLEN]; <buf> <buf2>
973 #if 0
974 char *id = xmlGetProp (node, "offset");
975 #endif
976 char *type = get_type (node); <type>
977 char *subscript = get_subscript (node); <subscript>
978 snprintf (buf2, sizeof (buf2), "%%s[%s]", subscript);
979 snprintf (buf, sizeof (buf), type, buf2);
980 free (subscript);
981 free (type);
982 return strdup (buf);
983 }
984
985 static char *
986 ptr_type_to_string (xmlNodePtr node)
987 { <ptr_type_to_string>
988 char buf [BUFLEN]; <buf>
989 char *type = get_type (node); <type>
990 snprintf (buf, sizeof (buf), type, "(*%s)");
991 free (type);
992 return strdup (buf);
993 }
994
995 static char *
996 func_type_to_string (xmlNodePtr node)
997 { <func_type_to_string>
998 char buf [BUFLEN], buf2 [BUFLEN]; <buf> <buf2>
999 char *ret_type = get_type (node); <ret_type>
1000 char *params = get_params (node); <params>
1001 snprintf (buf2, sizeof (buf2), "(%%s)(%s)", params);
1002 snprintf (buf, sizeof (buf), ret_type, buf2);
1003 free (ret_type);
1004 free (params);
1005 return strdup (buf);
1006 }
1007
1008 static char *
1009 volatile_to_string (xmlNodePtr node)
1010 { <volatile_to_string>
1011 char buf [BUFLEN]; <buf>
1012 char *type = get_type (node); <type>
1013 snprintf (buf, sizeof (buf), type, "volatile %s");
1014 free (type);
1015 return strdup (buf);
1016 }
1017
1018 static char *
1019 const_to_string (xmlNodePtr node)
1020 { <const_to_string>
1021 char buf [BUFLEN]; <buf>
1022 char *type = get_type (node); <type>
1023 snprintf (buf, sizeof (buf), type, "const %s");
1024 free (type);
1025 return strdup (buf);
1026 }
1027
1028 static char *
1029 struct_union_to_string (xmlNodePtr node, char *which)
1030 { <struct_union_to_string>
1031 char buf [BUFLEN]; <buf>
1032 char *id = xmlGetProp (node, "offset"); <id>
1033 char *name = get_attr_value ("DW_AT_name", node); <name>
1034 if (name == NULL) {
1035 char *members = members_to_string (node); <members>
1036 snprintf (buf, sizeof (buf), "%s %s %%s", which, members);
1037 } else {
1038 snprintf (buf, sizeof (buf), "%s %s %%s", which, href_info (id, name));
1039 xmlFree (name);
1040 }
1041 xmlFree (id);
1042 return strdup (buf);
1043 }
1044
1045 static char *
1046 struct_to_string (xmlNodePtr node)
1047 { <struct_to_string>
1048 return struct_union_to_string (node, "struct");
1049 }
1050
1051 static char *
1052 union_to_string (xmlNodePtr node)
1053 { <union_to_string>
1054 return struct_union_to_string (node, "union");
1055 }
1056
1057 static char *
1058 members_to_string (xmlNodePtr node)
1059 { <members_to_string>
1060 char buf [BUFLEN] = {'\0'}, buf2 [BUFLEN], buf3 [BUFLEN]; <buf> <buf2> <buf3>
1061 xmlNodeSetPtr result; <result>
1062 int i, n; <i> <n>
1063 char *xpath = "tag[@name='DW_TAG_member']"; <xpath>
1064 void *free_p; <free_p>
1065
1066 result = eval_xpath (xpath, node, &free_p, &n);
1067
1068 strncat (buf, "{ ", sizeof (buf));
1069
1070 for (i = 0; i < n; i++) {
1071 xmlNodePtr child = result->nodeTab [i]; <child>
1072 char *id = xmlGetProp (child, "offset"); <id>
1073 char *name = get_attr_value ("DW_AT_name", child); <name>
1074 char *file = get_attr_value ("DW_AT_decl_file", child); <file>
1075 char *filename = get_filename_by_node (child, file); <filename>
1076 char *pathname = get_pathname_by_node (child, file); <pathname>
1077 #if 0
1078 char *line = get_line (get_attr_value ("DW_AT_decl_line", child));
1079 #endif
1080 char *type = get_type (child); <type>
1081
1082 snprintf (buf2, sizeof (buf2), "%s", href_info (id, get_name (name)));
1083 snprintf (buf3, sizeof (buf3), type, buf2);
1084 strncat (buf, buf3, sizeof (buf));
1085 strncat (buf, "; ", sizeof (buf));
1086 xmlFree (id);
1087 xmlFree (name);
1088 xmlFree (file);
1089 free (type);
1090 }
1091 free (free_p);
1092
1093 strncat (buf, "}", sizeof (buf));
1094 return strdup (buf);
1095 }
1096
1097 static char *
1098 typedef_to_string (xmlNodePtr node)
1099 { <typedef_to_string>
1100 char buf [BUFLEN]; <buf>
1101 char *id = xmlGetProp (node, "offset"); <id>
1102 char *name = get_attr_value ("DW_AT_name", node); <name>
1103 snprintf (buf, sizeof (buf), "%s %%s", href_info (id, get_name (name)));
1104 xmlFree (id);
1105 xmlFree (name);
1106 return strdup (buf);
1107 }
1108
1109 static char *
1110 enum_to_string (xmlNodePtr node)
1111 { <enum_to_string>
1112 char buf [BUFLEN]; <buf>
1113 char *id = xmlGetProp (node, "offset"); <id>
1114 char *name = get_attr_value ("DW_AT_name", node); <name>
1115 if (name == NULL) {
1116 char * enum_constants = enum_constants_to_string (node); <enum_constants>
1117 snprintf (buf, sizeof (buf), "enum %s %%s", enum_constants);
1118 } else {
1119 snprintf (buf, sizeof (buf), "enum %s %%s", href_info (id, name));
1120 }
1121 xmlFree (id);
1122 xmlFree (name);
1123 return strdup (buf);
1124 }
1125
1126 static char *
1127 enum_constants_to_string (xmlNodePtr node)
1128 { <enum_constants_to_string>
1129 char buf [BUFLEN] = {'\0'}, buf2 [BUFLEN]; <buf> <buf2>
1130 xmlNodeSetPtr result; <result>
1131 int i, n; <i> <n>
1132 char *xpath = "tag[@name='DW_TAG_enumerator']"; <xpath>
1133 void *free_p; <free_p>
1134
1135 result = eval_xpath (xpath, node, &free_p, &n);
1136 strncat (buf, "{ ", sizeof (buf));
1137
1138 for (i = 0; i < n; i++) {
1139 xmlNodePtr child = result->nodeTab [i]; <child>
1140 char *id = xmlGetProp (child, "offset"); <id>
1141 char *name = get_attr_value ("DW_AT_name", child); <name>
1142 char *value = get_attr_value ("DW_AT_const_value", child); <value>
1143
1144 snprintf (buf2, sizeof (buf2),
1145 "%s = %s, ", href_info (id, get_name (name)), value);
1146 strncat (buf, buf2, sizeof (buf));
1147 xmlFree (id);
1148 xmlFree (name);
1149 xmlFree (value);
1150 }
1151
1152 free (free_p);
1153 strncat (buf, "}", sizeof (buf));
1154 return strdup (buf);
1155 }
1156
1157 static void
1158 output_indent (FILE *fp)
1159 { <output_indent>
1160 fprintf (fp, "%*s", indent_depth*4, "");
1161 }
1162
1163 static void
1164 visit_all_children (xmlNodePtr node, FILE *fp)
1165 { <visit_all_children>
1166 xmlNodePtr child; <child>
1167 for (child = node->children; child != NULL; child = child->next) {
1168 if (child->type != XML_ELEMENT_NODE || strcmp (child->name, "tag"))
1169 continue;
1170 output_debug_info (child, fp);
1171 }
1172 }
1173
1174 static void
1175 output_debug_info_top (void)
1176 { <output_debug_info_top>
1177 FILE *fp; <fp>
1178 xmlNodeSetPtr result; <result>
1179 xmlNodePtr node, child; <node> <child>
1180 void *free_p; <free_p>
1181
1182 if (args.verbose) printf ("processing .debug_info\n");
1183 result = eval_xpath ("//section[@name='.debug_info']",
1184 xml_root, &free_p, NULL);
1185 assert (xmlXPathNodeSetGetLength (result) == 1);
1186 node = result->nodeTab [0];
1187 assert (node->type == XML_ELEMENT_NODE);
1188 assert (!strcmp (node->name, "section"));
1189
1190 fp = fopen (WORKING_DIR XREF_INFO, "w");
1191 if (fp == NULL) {
1192 perror ("fopen (info)"); exit (1);
1193 }
1194 visit_all_children (node, fp);
1195 free (free_p);
1196 fclose (fp);
1197 }
1198
1199 static void
1200 output_debug_info (xmlNodePtr node, FILE *fp)
1201 { <output_debug_info>
1202 char *attr; <attr>
1203 assert (node->type == XML_ELEMENT_NODE);
1204 assert (!strcmp (node->name, "tag"));
1205 attr = xmlGetProp (node, "name");
1206 if (args.verbose) printf ("\tprocessing %s\n", attr);
1207
1208 if (!strcmp (attr, "DW_TAG_compile_unit")) {
1209 output_compile_unit (node, fp);
1210 } else if (!strcmp (attr, "DW_TAG_subprogram")) {
1211 output_subprogram (node, fp);
1212 } else if (!strcmp (attr, "DW_TAG_lexical_block")) {
1213 output_lexical_block (node, fp);
1214 } else if (!strcmp (attr, "DW_TAG_variable")) {
1215 output_variable (node, fp);
1216 } else if (!strcmp (attr, "DW_TAG_label")) {
1217 output_label (node, fp);
1218 } else if (!strcmp (attr, "DW_TAG_typedef")) {
1219 output_typedef (node, fp);
1220 } else if (!strcmp (attr, "DW_TAG_structure_type")) {
1221 output_struct (node, fp);
1222 } else if (!strcmp (attr, "DW_TAG_union_type")) {
1223 output_union (node, fp);
1224 } else if (!strcmp (attr, "DW_TAG_enumeration_type")) {
1225 output_enum (node, fp);
1226 #if 0
1227 } else if (!strcmp (attr, "DW_TAG_array_type")
1228 || !strcmp (attr, "DW_TAG_base_type")
1229 || !strcmp (attr, "DW_TAG_const_type")
1230 || !strcmp (attr, "DW_TAG_pointer_type")
1231 || !strcmp (attr, "DW_TAG_subroutine_type")
1232 || !strcmp (attr, "DW_TAG_volatile_type")
1233 || !strcmp (attr, "DW_TAG_member")
1234 || !strcmp (attr, "DW_TAG_subrange_type")
1235 || !strcmp (attr, "DW_TAG_constant")
1236 || !strcmp (attr, "DW_TAG_enumerator")
1237 || !strcmp (attr, "DW_TAG_formal_parameter")
1238 || !strcmp (attr, "DW_TAG_unspecified_parameters")) {
1239 visit_all_children (node, fp);
1240 #endif
1241 } else {
1242 /*
1243 just ignore for the following tags, not appearing in ANSI C:
1244 DW_TAG_access_declaration DW_TAG_catch_block
1245 DW_TAG_class_type DW_TAG_common_block
1246 DW_TAG_common_inclusion DW_TAG_entry_point
1247 DW_TAG_file_type DW_TAG_friend
1248 DW_TAG_imported_declaration DW_TAG_inheritance
1249 DW_TAG_inlined_subroutine DW_TAG_module
1250 DW_TAG_namelist DW_TAG_namelist_item
1251 DW_TAG_packed_type DW_TAG_ptr_to_member_type
1252 DW_TAG_reference_type DW_TAG_set_type
1253 DW_TAG_string_type
1254 DW_TAG_template_type_param DW_TAG_template_value_param
1255 DW_TAG_thrown_type DW_TAG_try_block
1256 DW_TAG_variant DW_TAG_variant_part DW_TAG_with_stmt
1257 and other vender-specific extentions.
1258 */
1259 }
1260 xmlFree (attr);
1261 }
1262
1263 static void
1264 output_compile_unit (xmlNodePtr node, FILE *fp)
1265 { <output_compile_unit>
1266 char *id = xmlGetProp (node, "offset"); <id>
1267 char *filename = get_attr_value ("DW_AT_name", node); <filename>
1268 char *comp_dir = get_attr_value ("DW_AT_comp_dir", node); <comp_dir>
1269 char *high_pc = get_attr_value ("DW_AT_high_pc", node); <high_pc>
1270 char *low_pc = get_attr_value ("DW_AT_low_pc", node); <low_pc>
1271 char *producer = get_attr_value ("DW_AT_producer", node); <producer>
1272
1273 fprintf (fp,
1274 "</pre><hr/>\n"
1275 "<h1>%s --- %s, 0x%x-0x%x, %s</h1><a name=\"%s\"/>\n"
1276 "<hr/><pre>\n",
1277 href_src1 (filename, "top", filename), comp_dir,
1278 atoi (low_pc), atoi (high_pc), producer, id);
1279 visit_all_children (node, fp);
1280
1281 xmlFree (id);
1282 xmlFree (filename);
1283 xmlFree (comp_dir);
1284 xmlFree (high_pc);
1285 xmlFree (low_pc);
1286 xmlFree (producer);
1287 }
1288
1289 static void
1290 output_subprogram (xmlNodePtr node, FILE *fp)
1291 { <output_subprogram>
1292 char buf [BUFLEN], buf2 [BUFLEN]; <buf> <buf2>
1293 char *id = xmlGetProp (node, "offset"); <id>
1294 char *funcname = get_attr_value ("DW_AT_name", node); <funcname>
1295 char *file = get_attr_value ("DW_AT_decl_file", node); <file>
1296 char *filename = get_filename_by_node (node, file); <filename>
1297 char *pathname = get_pathname_by_node (node, file); <pathname>
1298 char *line = get_attr_value ("DW_AT_decl_line", node); <line>
1299 char *line2 = get_line (line); <line2>
1300 char *high_pc = get_attr_value ("DW_AT_high_pc", node); <high_pc>
1301 char *low_pc = get_attr_value ("DW_AT_low_pc", node); <low_pc>
1302 char *external = get_attr_value ("DW_AT_external", node); <external>
1303 char *declaration = get_attr_value ("DW_AT_declaration", node); <declaration>
1304 char *abst_origin = get_attr_value ("DW_AT_abstract_origin", node); <abst_origin>
1305 char *inlined = get_attr_desc ("DW_AT_inline", node); <inlined>
1306 char *ret_type = get_type (node); <ret_type>
1307 char *params = get_params (node); <params>
1308
1309 int is_extern = (declaration != NULL) && strcmp (declaration, "0"); <is_extern>
1310
1311 /* skip this entry because this is a concrete code for inlined func */
1312 if (abst_origin != NULL)
1313 goto output_subprogram_exit;
1314
1315 snprintf (buf2, sizeof (buf2), "%%s (%s)", params);
1316 snprintf (buf, sizeof (buf), ret_type, buf2);
1317 free (ret_type);
1318 free (params);
1319
1320 snprintf (buf2, sizeof (buf2),
1321 "%s<a name=\"%s\"/>",
1322 href_src1 (pathname, line2, get_name (funcname)), id);
1323
1324 if (inlined == NULL)
1325 inlined = "";
1326
1327 output_indent (fp);
1328 if (low_pc != NULL && high_pc != NULL) {
1329 fprintf (fp, COMM_BEGIN "0x%x-0x%x, %s %s" COMM_END "\n",
1330 atoi (low_pc), atoi (high_pc),
1331 href_src2 (pathname, line2, filename), inlined);
1332 } else {
1333 fprintf (fp, COMM_BEGIN "%s %s" COMM_END "\n",
1334 href_src2 (pathname, line2, filename), inlined);
1335 }
1336
1337 output_indent (fp);
1338 if (external == NULL || strcmp (external, "1"))
1339 fprintf (fp, "static ");
1340 if (is_extern)
1341 fprintf (fp, "extern ");
1342 fprintf (fp, buf, buf2);
1343
1344 if (is_extern) {
1345 fprintf (fp, ";\n");
1346 } else {
1347 fprintf (fp, "\n{\n");
1348 indent_depth++;
1349 visit_all_children (node, fp);
1350 indent_depth--;
1351 fprintf (fp, "}\n", buf);
1352 }
1353
1354 output_subprogram_exit: <output_subprogram_exit>
1355 xmlFree (id);
1356 xmlFree (funcname);
1357 xmlFree (file);
1358 xmlFree (line);
1359 xmlFree (high_pc);
1360 xmlFree (low_pc);
1361 xmlFree (external);
1362 xmlFree (declaration);
1363 xmlFree (abst_origin);
1364 xmlFree (inlined);
1365 }
1366
1367 static void
1368 output_lexical_block (xmlNodePtr node, FILE *fp)
1369 { <output_lexical_block>
1370 char *id = xmlGetProp (node, "offset"); <id>
1371 char *high_pc = get_attr_value ("DW_AT_high_pc", node); <high_pc>
1372 char *low_pc = get_attr_value ("DW_AT_low_pc", node); <low_pc>
1373 output_indent (fp);
1374 fprintf (fp,
1375 "{ <a name=\"%s\"/><font color=\"red\">/* 0x%x-0x%x */</font>\n",
1376 id,
1377 (low_pc == NULL ? 0 : atoi (low_pc)),
1378 (low_pc == NULL ? 0 : atoi (high_pc)));
1379 indent_depth++;
1380 visit_all_children (node, fp);
1381 indent_depth--;
1382 output_indent (fp);
1383 fprintf (fp, "}\n");
1384
1385 xmlFree (id);
1386 xmlFree (high_pc);
1387 xmlFree (low_pc);
1388 }
1389
1390 static void
1391 output_variable (xmlNodePtr node, FILE *fp)
1392 { <output_variable>
1393 char buf [BUFLEN], loc [BUFLEN]; <buf> <loc>
1394 int offset, reg, is_auto = 0; <offset> <reg> <is_auto>
1395 unsigned long addr; <addr>
1396 char *id = xmlGetProp (node, "offset"); <id>
1397 char *varname = get_attr_value ("DW_AT_name", node); <varname>
1398 char *file = get_attr_value ("DW_AT_decl_file", node); <file>
1399 char *filename = get_filename_by_node (node, file); <filename>
1400 char *pathname = get_pathname_by_node (node, file); <pathname>
1401 char *line = get_attr_value ("DW_AT_decl_line", node); <line>
1402 char *line2 = get_line (line); <line2>
1403 char *external = get_attr_value ("DW_AT_external", node); <external>
1404 char *type = get_type (node); <type>
1405 char *location = get_attr_desc ("DW_AT_location", node); <location>
1406 char *declaration = get_attr_value ("DW_AT_declaration", node); <declaration>
1407
1408 snprintf (buf, sizeof (buf), "%s%s",
1409 href_src1 (pathname, line2, get_name (varname)), a_name (id));
1410
1411 if (location == NULL) {
1412 snprintf (loc, sizeof (loc), "??");
1413 } else if (sscanf (location, "DW_OP_fbreg: %d", &offset) == 1) {
1414 /* allocated on stack */
1415 is_auto = 1;
1416 snprintf (loc, sizeof (loc), "%%fp+(%d)", offset);
1417 } else if (sscanf (location, "DW_OP_addr: %u", &addr) == 1) {
1418 /* allocated on data */
1419 snprintf (loc, sizeof (loc), "0x%x", addr);
1420 } else if (sscanf (location, "DW_OP_reg%d", ®) == 1) {
1421 /* allocated on registers */
1422 is_auto = 1;
1423 snprintf (loc, sizeof (loc), "%%r%d", reg);
1424 } else {
1425 /* unknown description, so print it as it is. */
1426 snprintf (loc, sizeof (loc), "%s", location);
1427 #if 0
1428 fprintf (stderr, "unknown description (%s)\n", location);
1429 assert (0);
1430 #endif
1431 }
1432
1433 output_indent (fp);
1434 if (!is_auto && (external == NULL || strcmp (external, "1")))
1435 fprintf (fp, "static ");
1436 if (declaration != NULL && strcmp (declaration, "0"))
1437 fprintf (fp, "extern ");
1438 fprintf (fp, type, buf);
1439 free (type);
1440 fprintf (fp, "; " COMM_BEGIN "%s, %s" COMM_END,
1441 loc, href_src2 (pathname, line2, filename));
1442 fprintf (fp, "\n");
1443
1444 xmlFree (id);
1445 xmlFree (varname);
1446 xmlFree (file);
1447 xmlFree (line);
1448 xmlFree (external);
1449 xmlFree (location);
1450 xmlFree (declaration);
1451 }
1452
1453 static void
1454 output_label (xmlNodePtr node, FILE *fp)
1455 { <output_label>
1456 char *id = xmlGetProp (node, "offset"); <id>
1457 char *labelname = get_attr_value ("DW_AT_name", node); <labelname>
1458 char *file = get_attr_value ("DW_AT_decl_file", node); <file>
1459 char *filename = get_filename_by_node (node, file); <filename>
1460 char *pathname = get_pathname_by_node (node, file); <pathname>
1461 char *line = get_attr_value ("DW_AT_decl_line", node); <line>
1462 char *low_pc = get_attr_value ("DW_AT_low_pc", node); <low_pc>
1463
1464 output_indent (fp);
1465 fprintf (fp, "%s%s:",
1466 href_src1 (pathname, get_line (line), get_name (labelname)),
1467 a_name (id));
1468 fprintf (fp, " " COMM_BEGIN "0x%x, %s" COMM_END,
1469 atoi (low_pc),
1470 href_src2 (pathname, get_line (line), filename));
1471 fprintf (fp, "\n");
1472
1473 xmlFree (id);
1474 xmlFree (labelname);
1475 xmlFree (file);
1476 xmlFree (line);
1477 xmlFree (low_pc);
1478 }
1479
1480 static void
1481 output_typedef (xmlNodePtr node, FILE *fp)
1482 { <output_typedef>
1483 char buf [BUFLEN], loc [BUFLEN]; <buf> <loc>
1484 char *id = xmlGetProp (node, "offset"); <id>
1485 char *typename = get_attr_value ("DW_AT_name", node); <typename>
1486 char *file = get_attr_value ("DW_AT_decl_file", node); <file>
1487 char *filename = get_filename_by_node (node, file); <filename>
1488 char *pathname = get_pathname_by_node (node, file); <pathname>
1489 char *line = get_attr_value ("DW_AT_decl_line", node); <line>
1490 char *type = get_type (node); <type>
1491
1492 snprintf (buf, sizeof (buf), "%s%s",
1493 href_src1 (pathname, get_line (line), get_name (typename)),
1494 a_name (id));
1495 output_indent (fp);
1496 fprintf (fp, "typedef ");
1497 fprintf (fp, type, buf);
1498 free (type);
1499 fprintf (fp, "; ");
1500 fprintf (fp, " " COMM_BEGIN "%s" COMM_END,
1501 href_src2 (pathname, get_line (line), filename));
1502 fprintf (fp, "\n");
1503
1504 xmlFree (id);
1505 xmlFree (typename);
1506 xmlFree (file);
1507 xmlFree (line);
1508 }
1509
1510 static void
1511 output_enum (xmlNodePtr node, FILE *fp)
1512 { <output_enum>
1513 char *id = xmlGetProp (node, "offset"); <id>
1514 char *enumname = get_attr_value ("DW_AT_name", node); <enumname>
1515 char *file = get_attr_value ("DW_AT_decl_file", node); <file>
1516 char *filename = get_filename_by_node (node, file); <filename>
1517 char *pathname = get_pathname_by_node (node, file); <pathname>
1518 char *line = get_attr_value ("DW_AT_decl_line", node); <line>
1519 char *line2 = get_line (line); <line2>
1520
1521 output_indent (fp);
1522 fprintf (fp, "enum %s%s " COMM_BEGIN "%s" COMM_END " ",
1523 (enumname == NULL ? "" : href_src1 (pathname, line2, enumname)),
1524 a_name (id), href_src2 (pathname, line2, filename));
1525 output_enum_constants (node, fp, pathname, line2);
1526 fprintf (fp, ";\n");
1527
1528 xmlFree (id);
1529 xmlFree (enumname);
1530 xmlFree (file);
1531 xmlFree (line);
1532 }
1533
1534 static void
1535 output_enum_constants (xmlNodePtr node, FILE *fp, char *pathname, char *line)
1536 { <output_enum_constants>
1537 xmlNodeSetPtr result; <result>
1538 int i, n; <i> <n>
1539 char *xpath = "tag[@name='DW_TAG_enumerator']"; <xpath>
1540 void *free_p; <free_p>
1541
1542 result = eval_xpath (xpath, node, &free_p, &n);
1543
1544 if (n == 0) return;
1545
1546 output_indent (fp);
1547 fprintf (fp, "{\n");
1548 indent_depth++;
1549
1550 for (i = 0; i < n; i++) {
1551 xmlNodePtr child = result->nodeTab [i]; <child>
1552 char *id = xmlGetProp (child, "offset"); <id>
1553 char *name = get_attr_value ("DW_AT_name", child); <name>
1554 char *value = get_attr_value ("DW_AT_const_value", child); <value>
1555
1556 output_indent (fp);
1557 fprintf (fp, "%s = %s,%s\n",
1558 href_src1 (pathname, line, name), value, a_name (id));
1559 xmlFree (id);
1560 xmlFree (name);
1561 xmlFree (value);
1562 }
1563 free (free_p);
1564 indent_depth--;
1565 output_indent (fp);
1566 fprintf (fp, "}");
1567 }
1568
1569 static void
1570 output_struct_union (xmlNodePtr node, FILE *fp, char *which)
1571 { <output_struct_union>
1572 char *id = xmlGetProp (node, "offset"); <id>
1573 char *tagname = get_attr_value ("DW_AT_name", node); <tagname>
1574 char *file = get_attr_value ("DW_AT_decl_file", node); <file>
1575 char *filename = get_filename_by_node (node, file); <filename>
1576 char *pathname = get_pathname_by_node (node, file); <pathname>
1577 char *line = get_attr_value ("DW_AT_decl_line", node); <line>
1578 char *line2 = get_line (line); <line2>
1579 char *size = get_attr_value ("DW_AT_byte_size", node); <size>
1580
1581 output_indent (fp);
1582 fprintf (fp, "%s %s%s " COMM_BEGIN "%s" COMM_END " ", which,
1583 (tagname == NULL ? "" : href_src1 (pathname, line2, tagname)),
1584 a_name (id), href_src2 (pathname, line2, filename));
1585 output_members (node, fp);
1586 fprintf (fp, ";\n");
1587
1588 xmlFree (id);
1589 xmlFree (tagname);
1590 xmlFree (file);
1591 xmlFree (line);
1592 xmlFree (size);
1593 }
1594
1595 static void
1596 output_struct (xmlNodePtr node, FILE *fp)
1597 { <output_struct>
1598 output_struct_union (node, fp, "struct");
1599 }
1600
1601 static void
1602 output_union (xmlNodePtr node, FILE *fp)
1603 { <output_union>
1604 output_struct_union (node, fp, "union");
1605 }
1606
1607 static void
1608 output_members (xmlNodePtr node, FILE *fp)
1609 { <output_members>
1610 xmlNodeSetPtr result; <result>
1611 int i, n; <i> <n>
1612 char *xpath = "tag[@name='DW_TAG_member']"; <xpath>
1613 void *free_p; <free_p>
1614
1615 result = eval_xpath (xpath, node, &free_p, &n);
1616
1617 if (n == 0) return;
1618
1619 output_indent (fp);
1620 fprintf (fp, "{\n");
1621 indent_depth++;
1622
1623 for (i = 0; i < n; i++) {
1624 char buf [BUFLEN]; <buf>
1625 xmlNodePtr child = result->nodeTab [i]; <child>
1626 char *id = xmlGetProp (child, "offset"); <id>
1627 char *name = get_attr_value ("DW_AT_name", child); <name>
1628 char *value = get_attr_value ("DW_AT_const_value", child); <value>
1629 char *file = get_attr_value ("DW_AT_decl_file", child); <file>
1630 char *filename = get_filename_by_node (child, file); <filename>
1631 char *pathname = get_pathname_by_node (child, file); <pathname>
1632 char *line = get_attr_value ("DW_AT_decl_line", child); <line>
1633 char *line2 = get_line (line); <line2>
1634 char *location = get_attr_desc ("DW_AT_data_member_location", child); <location>
1635 char *type = get_type (child); <type>
1636
1637 snprintf (buf, sizeof (buf), "%s%s",
1638 href_src1 (pathname, line2, get_name (name)), a_name (id));
1639 output_indent (fp);
1640 fprintf (fp, type, buf);
1641
1642 if (location == NULL) {
1643 fprintf (fp, "; " COMM_BEGIN "%s" COMM_END "\n",
1644 href_src2 (pathname, line2, filename));
1645 } else {
1646 int offset; <offset>
1647 if (sscanf (location, "DW_OP_plus_uconst: %d", &offset) != 1) {
1648 fprintf (stderr, "unknown description (%s)\n", location);
1649 assert (0);
1650 }
1651 fprintf (fp, "; " COMM_BEGIN "%d, %s" COMM_END "\n",
1652 offset, href_src2 (pathname, line2, filename));
1653 }
1654
1655 free (type);
1656 xmlFree (id);
1657 xmlFree (name);
1658 xmlFree (value);
1659 xmlFree (file);
1660 xmlFree (line);
1661 xmlFree (location);
1662 }
1663 free (free_p);
1664 indent_depth--;
1665 output_indent (fp);
1666 fprintf (fp, "}");
1667 }
1668
1669 static void
1670 output_all_structs (void)
1671 { <output_all_structs>
1672 FILE *fp1, *fp2; <fp1> <fp2>
1673 xmlNodeSetPtr result; <result>
1674 int n, i; <n> <i>
1675 void *free_p; <free_p>
1676 char *work1 = WORKING_DIR XREF_STRUCTS1; <work1>
1677 char *work2 = WORKING_DIR XREF_STRUCTS2; <work2>
1678
1679 if (args.verbose) printf ("processing all structures\n");
1680 fp1 = fopen (work1, "w");
1681 if (fp1 == NULL) { perror ("fopen(structs1)"); exit (1); }
1682 fp2 = fopen (work2, "w");
1683 if (fp2 == NULL) { perror ("fopen(structs2)"); exit (1); }
1684
1685 result = eval_xpath ("//tag[@name='DW_TAG_structure_type']",
1686 xml_root, &free_p, &n);
1687
1688 for (i = 0; i < n; i++) {
1689 xmlNodePtr node = result->nodeTab [i]; <node>
1690 char *id = xmlGetProp (node, "offset"); <id>
1691 char *tagname = get_attr_value ("DW_AT_name", node); <tagname>
1692 char *file = get_attr_value ("DW_AT_decl_file", node); <file>
1693 char *filename = get_filename_by_node (node, file); <filename>
1694 char *pathname = get_pathname_by_node (node, file); <pathname>
1695 char *line = get_attr_value ("DW_AT_decl_line", node); <line>
1696 char *line2 = get_line (line); <line2>
1697
1698 if (tagname == NULL) goto loop_continue;
1699 fprintf (fp1, "%s @ struct %s; " COMM_BEGIN "%s" COMM_END "\n",
1700 tagname, href_info (id, tagname),
1701 href_src2 (pathname, line2, filename));
1702
1703 if (file == NULL) goto loop_continue;
1704 fprintf (fp2, "%s %s @ " COMM_BEGIN "%s" COMM_END " struct %s;\n",
1705 filename, line2,
1706 href_src2 (pathname, line2, filename),
1707 href_info (id, tagname));
1708
1709 loop_continue: <loop_continue>
1710 xmlFree (id);
1711 xmlFree (tagname);
1712 xmlFree (file);
1713 xmlFree (line);
1714 }
1715 free (free_p);
1716 fclose (fp1);
1717 fclose (fp2);
1718 }
1719
1720 static void
1721 output_all_unions (void)
1722 { <output_all_unions>
1723 FILE *fp1, *fp2; <fp1> <fp2>
1724 xmlNodeSetPtr result; <result>
1725 int n, i; <n> <i>
1726 void *free_p; <free_p>
1727 char *work1 = WORKING_DIR XREF_UNIONS1; <work1>
1728 char *work2 = WORKING_DIR XREF_UNIONS2; <work2>
1729
1730 if (args.verbose) printf ("processing all unions\n");
1731 fp1 = fopen (work1, "w");
1732 if (fp1 == NULL) { perror ("fopen(unions1)"); exit (1); }
1733 fp2 = fopen (work2, "w");
1734 if (fp2 == NULL) { perror ("fopen(unions2)"); exit (1); }
1735
1736 result = eval_xpath ("//tag[@name='DW_TAG_union_type']",
1737 xml_root, &free_p, &n);
1738
1739 for (i = 0; i < n; i++) {
1740 xmlNodePtr node = result->nodeTab [i]; <node>
1741 char *id = xmlGetProp (node, "offset"); <id>
1742 char *tagname = get_attr_value ("DW_AT_name", node); <tagname>
1743 char *file = get_attr_value ("DW_AT_decl_file", node); <file>
1744 char *filename = get_filename_by_node (node, file); <filename>
1745 char *pathname = get_pathname_by_node (node, file); <pathname>
1746 char *line = get_attr_value ("DW_AT_decl_line", node); <line>
1747 char *line2 = get_line (line2); <line2>
1748
1749 if (tagname == NULL) goto loop_continue;
1750 fprintf (fp1, "%s @ union %s; " COMM_BEGIN "%s" COMM_END "\n",
1751 tagname, href_info (id, tagname),
1752 href_src2 (pathname, line2, filename));
1753 if (file == NULL) goto loop_continue;
1754 fprintf (fp2, "%s %s @ " COMM_BEGIN "%s" COMM_END " union %s;\n",
1755 filename, line2,
1756 href_src2 (pathname, line2, filename),
1757 href_info (id, tagname));
1758
1759 loop_continue: <loop_continue>
1760 xmlFree (id);
1761 xmlFree (tagname);
1762 xmlFree (file);
1763 xmlFree (line);
1764 }
1765 free (free_p);
1766 fclose (fp1);
1767 fclose (fp2);
1768 }
1769
1770 static void
1771 output_all_typedefs (void)
1772 { <output_all_typedefs>
1773 FILE *fp1, *fp2; <fp1> <fp2>
1774 xmlNodeSetPtr result; <result>
1775 int n, i; <n> <i>
1776 void *free_p; <free_p>
1777 char *work1 = WORKING_DIR XREF_TYPEDEFS1; <work1>
1778 char *work2 = WORKING_DIR XREF_TYPEDEFS2; <work2>
1779
1780 if (args.verbose) printf ("processing all typedefs\n");
1781 fp1 = fopen (work1, "w");
1782 if (fp1 == NULL) { perror ("fopen(tdefs1)"); exit (1); }
1783 fp2 = fopen (work2, "w");
1784 if (fp2 == NULL) { perror ("fopen(tdefs2)"); exit (1); }
1785
1786 result = eval_xpath ("//tag[@name='DW_TAG_typedef']",
1787 xml_root, &free_p, &n);
1788
1789 for (i = 0; i < n; i++) {
1790 xmlNodePtr node = result->nodeTab [i]; <node>
1791 char *id = xmlGetProp (node, "offset"); <id>
1792 char *name = get_attr_value ("DW_AT_name", node); <name>
1793 char *file = get_attr_value ("DW_AT_decl_file", node); <file>
1794 char *filename = get_filename_by_node (node, file); <filename>
1795 char *pathname = get_pathname_by_node (node, file); <pathname>
1796 char *line = get_attr_value ("DW_AT_decl_line", node); <line>
1797 char *line2 = get_line (line); <line2>
1798
1799 if (name == NULL) goto loop_continue;
1800 fprintf (fp1, "%s @ typedef %s; " COMM_BEGIN "%s" COMM_END "\n",
1801 name, href_info (id, name),
1802 href_src2 (pathname, line2, filename));
1803 if (file == NULL) goto loop_continue;
1804 fprintf (fp2, "%s %s @ " COMM_BEGIN "%s" COMM_END " union %s;\n",
1805 filename, line2,
1806 href_src2 (pathname, line2, filename),
1807 href_info (id, name));
1808
1809 loop_continue: <loop_continue>
1810 xmlFree (id);
1811 xmlFree (name);
1812 xmlFree (file);
1813 xmlFree (line);
1814 }
1815 free (free_p);
1816 fclose (fp1);
1817 fclose (fp2);
1818 }
1819
1820 static void
1821 output_all_enum_tags (void)
1822 { <output_all_enum_tags>
1823 FILE *fp1, *fp2; <fp1> <fp2>
1824 xmlNodeSetPtr result; <result>
1825 int n, i; <n> <i>
1826 void *free_p; <free_p>
1827 char *work1 = WORKING_DIR XREF_ENUM_TAGS1; <work1>
1828 char *work2 = WORKING_DIR XREF_ENUM_TAGS2; <work2>
1829
1830 if (args.verbose) printf ("processing all enum tags\n");
1831 fp1 = fopen (work1, "w");
1832 if (fp1 == NULL) { perror ("fopen(etags1)"); exit (1); }
1833 fp2 = fopen (work2, "w");
1834 if (fp2 == NULL) { perror ("fopen(etags2)"); exit (1); }
1835
1836 result = eval_xpath ("//tag[@name='DW_TAG_enumeration_type']",
1837 xml_root, &free_p, &n);
1838
1839 for (i = 0; i < n; i++) {
1840 xmlNodePtr node = result->nodeTab [i]; <node>
1841 char *id = xmlGetProp (node, "offset"); <id>
1842 char *name = get_attr_value ("DW_AT_name", node); <name>
1843 char *file = get_attr_value ("DW_AT_decl_file", node); <file>
1844 char *filename = get_filename_by_node (node, file); <filename>
1845 char *pathname = get_pathname_by_node (node, file); <pathname>
1846 char *line = get_attr_value ("DW_AT_decl_line", node); <line>
1847 char *line2 = get_line (line); <line2>
1848
1849 if (name == NULL) goto loop_continue;
1850 fprintf (fp1, "%s @ enum %s; " COMM_BEGIN "%s" COMM_END "\n",
1851 name, href_info (id, name),
1852 href_src2 (pathname, line2, filename));
1853 if (file == NULL) goto loop_continue;
1854 fprintf (fp2, "%s %s @ " COMM_BEGIN "%s" COMM_END " enum %s;\n",
1855 filename, line2,
1856 href_src2 (pathname, line2, filename),
1857 href_info (id, name));
1858
1859 loop_continue: <loop_continue>
1860 xmlFree (id);
1861 xmlFree (name);
1862 xmlFree (file);
1863 xmlFree (line);
1864 }
1865 free (free_p);
1866 fclose (fp1);
1867 fclose (fp2);
1868 }
1869
1870 static void
1871 output_all_enum_consts (void)
1872 { <output_all_enum_consts>
1873 FILE *fp1, *fp2; <fp1> <fp2>
1874 xmlNodeSetPtr result; <result>
1875 int n, i; <n> <i>
1876 void *free_p; <free_p>
1877 char *work1 = WORKING_DIR XREF_ENUM_CONSTS1; <work1>
1878 char *work2 = WORKING_DIR XREF_ENUM_CONSTS2; <work2>
1879
1880 if (args.verbose) printf ("processing all enum constants\n");
1881 fp1 = fopen (work1, "w");
1882 if (fp1 == NULL) { perror ("fopen(econs1)"); exit (1); }
1883 fp2 = fopen (work2, "w");
1884 if (fp2 == NULL) { perror ("fopen(econs2)"); exit (1); }
1885
1886 result = eval_xpath ("//tag[@name='DW_TAG_enumerator']",
1887 xml_root, &free_p, &n);
1888
1889 for (i = 0; i < n; i++) {
1890 xmlNodePtr node = result->nodeTab [i]; <node>
1891 char *id = xmlGetProp (node, "offset"); <id>
1892 char *name = get_attr_value ("DW_AT_name", node); <name>
1893 char *file = get_attr_value ("DW_AT_decl_file", node->parent); <file>
1894 char *filename = get_filename_by_node (node, file); <filename>
1895 char *pathname = get_pathname_by_node (node, file); <pathname>
1896 char *line = get_attr_value ("DW_AT_decl_line", node->parent); <line>
1897 char *line2 = get_line (line); <line2>
1898
1899 if (name == NULL) goto loop_continue;
1900 fprintf (fp1, "%s @ %s; " COMM_BEGIN "%s" COMM_END "\n",
1901 name, href_info (id, name),
1902 href_src2 (pathname, line2, filename));
1903 if (file == NULL) goto loop_continue;
1904 fprintf (fp2, "%s %s @ " COMM_BEGIN "%s" COMM_END " %s;\n",
1905 filename, line2,
1906 href_src2 (pathname, line2, filename),
1907 href_info (id, name));
1908
1909 loop_continue: <loop_continue>
1910 xmlFree (id);
1911 xmlFree (name);
1912 xmlFree (file);
1913 xmlFree (line);
1914 }
1915 free (free_p);
1916 fclose (fp1);
1917 fclose (fp2);
1918 }
1919
1920 static void
1921 output_all_labels (void)
1922 { <output_all_labels>
1923 FILE *fp1, *fp2; <fp1> <fp2>
1924 xmlNodeSetPtr result; <result>
1925 int n, i; <n> <i>
1926 void *free_p; <free_p>
1927 char *work1 = WORKING_DIR XREF_LABELS1; <work1>
1928 char *work2 = WORKING_DIR XREF_LABELS2; <work2>
1929
1930 if (args.verbose) printf ("processing all labels\n");
1931 fp1 = fopen (work1, "w");
1932 if (fp1 == NULL) { perror ("fopen(labels1)"); exit (1); }
1933 fp2 = fopen (work2, "w");
1934 if (fp2 == NULL) { perror ("fopen(labels2)"); exit (1); }
1935
1936 result = eval_xpath ("//tag[@name='DW_TAG_label']",
1937 xml_root, &free_p, &n);
1938
1939 for (i = 0; i < n; i++) {
1940 xmlNodePtr node = result->nodeTab [i]; <node>
1941 char *id = xmlGetProp (node, "offset"); <id>
1942 char *name = get_attr_value ("DW_AT_name", node); <name>
1943 char *file = get_attr_value ("DW_AT_decl_file", node); <file>
1944 char *filename = get_filename_by_node (node, file); <filename>
1945 char *pathname = get_pathname_by_node (node, file); <pathname>
1946 char *line = get_attr_value ("DW_AT_decl_line", node); <line>
1947 char *line2 = get_line (line); <line2>
1948
1949 if (name == NULL) goto loop_continue;
1950 fprintf (fp1, "%s @ %s: " COMM_BEGIN "%s" COMM_END "\n",
1951 name, href_info (id, name),
1952 href_src2 (pathname, line2, filename));
1953 if (file == NULL) goto loop_continue;
1954 fprintf (fp2, "%s %s @ " COMM_BEGIN "%s" COMM_END " %s:\n",
1955 filename, line2, href_src2 (pathname, line2, filename),
1956 href_info (id, name));
1957
1958 loop_continue: <loop_continue>
1959 xmlFree (id);
1960 xmlFree (name);
1961 xmlFree (file);
1962 xmlFree (line);
1963 }
1964 free (free_p);
1965 fclose (fp1);
1966 fclose (fp2);
1967 }
1968
1969 static void
1970 output_all_functions (void)
1971 { <output_all_functions>
1972 FILE *fp1, *fp2; <fp1> <fp2>
1973 xmlNodeSetPtr result; <result>
1974 int n, i; <n> <i>
1975 void *free_p; <free_p>
1976 char *work1 = WORKING_DIR XREF_FUNCTIONS1; <work1>
1977 char *work2 = WORKING_DIR XREF_FUNCTIONS2; <work2>
1978
1979 if (args.verbose) printf ("processing all functions\n");
1980 fp1 = fopen (work1, "w");
1981 if (fp1 == NULL) { perror ("fopen(funcs1)"); exit (1); }
1982 fp2 = fopen (work2, "w");
1983 if (fp2 == NULL) { perror ("fopen(funcs2)"); exit (1); }
1984
1985 result = eval_xpath ("//tag[@name='DW_TAG_subprogram']",
1986 xml_root, &free_p, &n);
1987
1988 for (i = 0; i < n; i++) {
1989 char buf [BUFLEN], buf2 [BUFLEN]; <buf> <buf2>
1990 xmlNodePtr node = result->nodeTab [i]; <node>
1991 char *id = xmlGetProp (node, "offset"); <id>
1992 char *name = get_attr_value ("DW_AT_name", node); <name>
1993 char *file = get_attr_value ("DW_AT_decl_file", node); <file>
1994 char *filename = get_filename_by_node (node, file); <filename>
1995 char *pathname = get_pathname_by_node (node, file); <pathname>
1996 char *line = get_attr_value ("DW_AT_decl_line", node); <line>
1997 char *line2 = get_line (line); <line2>
1998 char *ret_type = get_type (node); <ret_type>
1999 char *params = get_params (node); <params>
2000 char *external = get_attr_value ("DW_AT_external", node); <external>
2001
2002 if (name == NULL) goto loop_continue;
2003
2004 snprintf (buf2, sizeof (buf2), "%%s (%s)", params);
2005 snprintf (buf, sizeof (buf), ret_type, buf2);
2006 free (ret_type);
2007 free (params);
2008
2009 fprintf (fp1, "%s @ ", name);
2010 if (external != NULL && !strcmp (external, "0"))
2011 fprintf (fp1, "static ");
2012 snprintf (buf2, sizeof (buf2), "%s", href_info (id, name));
2013 fprintf (fp1, buf, buf2);
2014 fprintf (fp1, "; " COMM_BEGIN "%s" COMM_END "\n",
2015 href_src2 (pathname, line2, filename));
2016
2017 if (file == NULL) goto loop_continue;
2018
2019 fprintf (fp2, "%s %s @ ", filename, pathname);
2020 fprintf (fp2, COMM_BEGIN "%s" COMM_END " ",
2021 href_src2 (pathname, line2, filename));
2022 if (external != NULL && !strcmp (external, "0"))
2023 fprintf (fp2, "static ");
2024 snprintf (buf2, sizeof (buf2), "%s", href_info (id, name));
2025 fprintf (fp2, buf, buf2);
2026 fprintf (fp2, ";\n");
2027
2028 loop_continue: <loop_continue>
2029 xmlFree (id);
2030 xmlFree (name);
2031 xmlFree (file);
2032 xmlFree (line);
2033 xmlFree (external);
2034 }
2035 free (free_p);
2036 fclose (fp1);
2037 fclose (fp2);
2038 }
2039
2040 static void
2041 output_all_variables (void)
2042 { <output_all_variables>
2043 FILE *fp1, *fp2; <fp1> <fp2>
2044 xmlNodeSetPtr result; <result>
2045 int n, i; <n> <i>
2046 void *free_p; <free_p>
2047 char *work1 = WORKING_DIR XREF_VARIABLES1; <work1>
2048 char *work2 = WORKING_DIR XREF_VARIABLES2; <work2>
2049
2050 if (args.verbose) printf ("processing all variables\n");
2051 fp1 = fopen (work1, "w");
2052 if (fp1 == NULL) { perror ("fopen(vars1)"); exit (1); }
2053 fp2 = fopen (work2, "w");
2054 if (fp2 == NULL) { perror ("fopen(vars2)"); exit (1); }
2055
2056 result = eval_xpath ("//tag[@name='DW_TAG_variable']",
2057 xml_root, &free_p, &n);
2058
2059 for (i = 0; i < n; i++) {
2060 char buf [BUFLEN]; <buf>
2061 xmlNodePtr node = result->nodeTab [i]; <node>
2062 char *id = xmlGetProp (node, "offset"); <id>
2063 char *name = get_attr_value ("DW_AT_name", node); <name>
2064 char *file = get_attr_value ("DW_AT_decl_file", node); <file>
2065 char *filename = get_filename_by_node (node, file); <filename>
2066 char *pathname = get_pathname_by_node (node, file); <pathname>
2067 char *line = get_attr_value ("DW_AT_decl_line", node); <line>
2068 char *line2 = get_line (line); <line2>
2069 char *type = get_type (node); <type>
2070 char *external = get_attr_value ("DW_AT_external", node); <external>
2071
2072 if (name == NULL) goto loop_continue;
2073
2074 fprintf (fp1, "%s @ ", name);
2075 if (external != NULL && !strcmp (external, "0"))
2076 fprintf (fp1, "static ");
2077 snprintf (buf, sizeof (buf), "%s", href_info (id, name));
2078 fprintf (fp1, type, buf);
2079 fprintf (fp1, "; " COMM_BEGIN "%s" COMM_END "\n",
2080 href_src2 (pathname, line2, filename));
2081
2082 if (file == NULL) goto loop_continue;
2083
2084 fprintf (fp2, "%s %s @ ", filename, line2);
2085 fprintf (fp2, COMM_BEGIN "%s" COMM_END " ",
2086 href_src2 (pathname, line2, filename));
2087 if (external != NULL && !strcmp (external, "0"))
2088 fprintf (fp2, "static ");
2089 snprintf (buf, sizeof (buf), "%s", href_info (id, name));
2090 fprintf (fp2, type, buf);
2091 fprintf (fp2, ";\n");
2092
2093 loop_continue: <loop_continue>
2094 xmlFree (id);
2095 xmlFree (name);
2096 xmlFree (file);
2097 xmlFree (line);
2098 xmlFree (external);
2099 free (type);
2100 }
2101 free (free_p);
2102 fclose (fp1);
2103 fclose (fp2);
2104 }
2105
2106 static void
2107 output_all_files (void)
2108 { <output_all_files>
2109 FILE *fp1; <fp1>
2110 xmlNodeSetPtr result; <result>
2111 int n, i; <n> <i>
2112 void *free_p; <free_p>
2113 char *work1 = WORKING_DIR XREF_FILES1; <work1>
2114
2115 if (args.verbose) printf ("processing all files\n");
2116 fp1 = fopen (work1, "w");
2117 if (fp1 == NULL) { perror ("fopen(files1)"); exit (1); }
2118
2119 result = eval_xpath ("//tag[@name='DW_TAG_compile_unit']",
2120 xml_root, &free_p, &n);
2121
2122 for (i = 0; i < n; i++) {
2123 xmlNodePtr node = result->nodeTab [i]; <node>
2124 char *id = xmlGetProp (node, "offset"); <id>
2125 char *name = get_attr_value ("DW_AT_name", node); <name>
2126
2127 if (name == NULL) goto loop_continue;
2128
2129 fprintf (fp1, "%s @ %s", name, href_info (id, name));
2130 fprintf (fp1, " " COMM_BEGIN "%s" COMM_END "\n",
2131 href_src1 (name, "top", name));
2132
2133 loop_continue: <loop_continue>
2134 xmlFree (id);
2135 xmlFree (name);
2136 }
2137 free (free_p);
2138 fclose (fp1);
2139 }
2140
2141 static char *
2142 get_macinfo_id (void)
2143 { <get_macinfo_id>
2144 static char buf [BUFLEN]; <buf>
2145 static int counter = 0; <counter>
2146 snprintf (buf, sizeof (buf), "MACINFOID%d", counter++);
2147 return buf;
2148 }
2149
2150 static void
2151 output_all_macros (void)
2152 { <output_all_macros>
2153 FILE *fp1, *fp2, *fp3, *fp4; <fp1> <fp2> <fp3> <fp4>
2154 xmlNodeSetPtr result; <result>
2155 int n, i; <n> <i>
2156 int curr_comp_unit = -1; <curr_comp_unit>
2157 void *free_p; <free_p>
2158 char *work1 = WORKING_DIR XREF_MACROS1; <work1>
2159 char *work2 = WORKING_DIR XREF_MACROS2; <work2>
2160 char *work3 = WORKING_DIR XREF_MACROS3; <work3>
2161 char *work4 = WORKING_DIR XREF_MACINFO; <work4>
2162
2163 enum { STACK_SIZE = 1024 }; <STACK_SIZE>
2164 int file_stack [STACK_SIZE], sp = 0; <file_stack> <sp>
2165
2166 if (args.verbose) printf ("processing all macros\n");
2167 fp1 = fopen (work1, "w");
2168 if (fp1 == NULL) { perror ("fopen(macros1)"); exit (1); }
2169 fp2 = fopen (work2, "w");
2170 if (fp2 == NULL) { perror ("fopen(macros2)"); exit (1); }
2171 fp3 = fopen (work3, "w");
2172 if (fp3 == NULL) { perror ("fopen(macros3)"); exit (1); }
2173 fp4 = fopen (work4, "w");
2174 if (fp4 == NULL) { perror ("fopen(macros4)"); exit (1); }
2175
2176 result = eval_xpath ("//section[@name='.debug_macinfo']/*",
2177 xml_root, &free_p, &n);
2178 /* for font-lock sanity */
2179
2180 for (i = 0; i < n; i++) {
2181 char buf [BUFLEN]; <buf>
2182 xmlNodePtr node = result->nodeTab [i]; <node>
2183
2184 if (node->type != XML_ELEMENT_NODE) continue;
2185
2186 if (!strcmp (node->name, "start_file")) {
2187 char *line = xmlGetProp (node, "line"); <line>
2188 char *file_num = xmlGetProp (node, "file_index"); <file_num>
2189 char *filename, *pathname; <filename> <pathname>
2190 if (sp >= STACK_SIZE) {
2191 fprintf (stderr, "file stack overflow\n");
2192 exit (1);
2193 }
2194 if (sp == 0) {
2195 int j; <j>
2196 char *offset = xmlGetProp (node, "offset"); <offset>
2197 assert (offset != NULL);
2198
2199 if (strcmp (line, "0")) {
2200 if (line == NULL) line = "(null)";
2201 printf ("line = %s, offset = %s\n", line, offset);
2202 }
2203 assert (!strcmp (line, "0"));
2204
2205 for (j = 0; j < n_comp_unit; j++) {
2206 if (!strcmp (offset, comp_unit [j].macinfo_offset)) {
2207 curr_comp_unit = j;
2208 break;
2209 }
2210 }
2211 /* not found, so skip this comp_unit */
2212 if (j >= n_comp_unit) {
2213 while (1) {
2214 char *line; <line>
2215 i++;
2216 if (i >= n) break;
2217 node = result->nodeTab [i];
2218 if (strcmp (node->name, "start_file"))
2219 continue;
2220 line = xmlGetProp (node, "line");
2221 if (strcmp (line, "0")) {
2222 xmlFree (line);
2223 continue;
2224 }
2225 xmlFree (line);
2226 break;
2227 }
2228 #if 0
2229 xmlAttrPtr attr;
2230 unsigned long offset2;
2231 sscanf (offset, "macinfo:%ld", &offset2);
2232 for (j = 0; j < n_comp_unit; j++) {
2233 if (offset2 > comp_unit [j].macinfo_offset2)
2234 break;
2235 }
2236 attr = xmlGetID (xml_doc, comp_unit [i].macinfo_offset);
2237 assert (attr != NULL);
2238 node = attr->parent;
2239 #endif
2240 i--;
2241 goto start_file_exit;
2242 }
2243 }
2244 assert (file_num != NULL);
2245 file_stack [sp++] = atoi (file_num);
2246 filename = get_filename_by_int (curr_comp_unit,
2247 file_stack [sp - 1]);
2248 pathname = get_pathname_by_int (curr_comp_unit,
2249 file_stack [sp - 1]);
2250
2251 if (sp < 2) {
2252 fprintf (fp4, "<hr><h1>%s, %s</h1><hr>",
2253 filename, pathname);
2254 } else {
2255 char *id = get_macinfo_id (); <id>
2256 char *filename2 = get_filename_by_int (curr_comp_unit, <filename2>
2257 file_stack [sp - 2]);
2258 char *pathname2 = get_pathname_by_int (curr_comp_unit, <pathname2>
2259 file_stack [sp - 2]);
2260 fprintf (fp1,
2261 "%s @ #include %s " COMM_BEGIN "%s" COMM_END "\n",
2262 filename, href_macinfo (id, filename),
2263 href_src2 (pathname2, line, filename2));
2264 fprintf (fp2,
2265 "a%s @ #include %s " COMM_BEGIN "%s" COMM_END "\n",
2266 filename, href_macinfo (id, filename),
2267 href_src2 (pathname2, line, filename2));
2268 fprintf (fp3,
2269 "%s %s @ " COMM_BEGIN "%s" COMM_END " #include %s\n",
2270 filename, line,
2271 href_src2 (pathname2, line, filename2),
2272 href_macinfo (id, filename));
2273 fprintf (fp4,
2274 "%s#include %s " COMM_BEGIN "%s" COMM_END "\n",
2275 a_name (id), href_src1 (pathname2, line, filename),
2276 href_src2 (pathname2, line, filename2));
2277 }
2278
2279 start_file_exit: <start_file_exit>
2280 xmlFree (line);
2281 xmlFree (file_num);
2282 } else if (!strcmp (node->name, "end_file")) {
2283 char *filename = get_filename_by_int (curr_comp_unit, <filename>
2284 file_stack [sp - 1]);
2285 if (sp < 0) {
2286 fprintf (stderr, "file stack underflow\n");
2287 exit (1);
2288 }
2289 sp--;
2290 } else if (!strcmp (node->name, "define_func")
2291 || !strcmp (node->name, "define_normal")) {
2292 char *id = get_macinfo_id (); <id>
2293 char *line = xmlGetProp (node, "line"); <line>
2294 char *line2 = get_line (line); <line2>
2295 char *name = xmlGetProp (node, "name"); <name>
2296 char *filename = get_filename_by_int (curr_comp_unit, <filename>
2297 file_stack [sp - 1]);
2298 char *pathname = get_pathname_by_int (curr_comp_unit, <pathname>
2299 file_stack [sp - 1]);
2300 char *body = xmlGetProp (node, "body"); <body>
2301 char *signature = xmlGetProp (node, "signature"); <signature>
2302
2303 fprintf (fp1, "%s @ #define %s " COMM_BEGIN "%s" COMM_END "\n",
2304 name, href_macinfo (id, signature),
2305 href_src2 (pathname, line2, filename));
2306 fprintf (fp2, "d%s @ #define %s " COMM_BEGIN "%s" COMM_END "\n",
2307 name, href_macinfo (id, signature),
2308 href_src2 (pathname, line2, filename));
2309 fprintf (fp3, "%s %s @ " COMM_BEGIN "%s" COMM_END " #define %s\n",
2310 filename, line2, href_src2 (pathname, line2, filename),
2311 href_macinfo (id, signature));
2312 fprintf (fp4, "%s#define %s %s " COMM_BEGIN "%s" COMM_END "\n",
2313 a_name (id),
2314 href_src1 (pathname, line2, signature),
2315 body,
2316 href_src2 (pathname, line2, filename));
2317
2318 xmlFree (line);
2319 xmlFree (name);
2320 xmlFree (body);
2321 xmlFree (signature);
2322 } else if (!strcmp (node->name, "undef")) {
2323 char *id = get_macinfo_id (); <id>
2324 char *line = xmlGetProp (node, "line"); <line>
2325 char *line2 = get_line (line); <line2>
2326 char *name = xmlGetProp (node, "name"); <name>
2327 char *filename = get_filename_by_int (curr_comp_unit, <filename>
2328 file_stack [sp - 1]);
2329 char *pathname = get_pathname_by_int (curr_comp_unit, <pathname>
2330 file_stack [sp - 1]);
2331
2332 fprintf (fp1, "%s @ #undef %s " COMM_BEGIN "%s" COMM_END "\n",
2333 name, href_macinfo (id, name),
2334 href_src2 (pathname, line2, filename));
2335 fprintf (fp2, "u%s @ #undef %s " COMM_BEGIN "%s" COMM_END "\n",
2336 name, href_macinfo (id, name),
2337 href_src2 (pathname, line2, filename));
2338 fprintf (fp3, "%s %s @ " COMM_BEGIN "%s" COMM_END " #undef %s\n",
2339 filename, line2, href_src2 (pathname, line2, filename),
2340 href_macinfo (id, name));
2341 fprintf (fp4, "%s#undef %s " COMM_BEGIN "%s" COMM_END "\n",
2342 a_name (id),
2343 href_src1 (pathname, line2, name),
2344 href_src2 (pathname, line2, filename));
2345
2346 xmlFree (line);
2347 xmlFree (name);
2348 }
2349 }
2350
2351 free (free_p);
2352 fclose (fp1);
2353 fclose (fp2);
2354 fclose (fp3);
2355 fclose (fp4);
2356 }
2357 /* ====================================================================== */
2358 int
2359 main (int argc, char *argv [])
2360 { <main>
2361 if (argc <= 1) {
2362 print_usage ();
2363 exit (1);
2364 }
2365 process_args (argc, argv);
2366 init ();
2367
2368 output_debug_info_top ();
2369 output_all_structs ();
2370 output_all_unions ();
2371 output_all_typedefs ();
2372 output_all_enum_tags ();
2373 output_all_enum_consts ();
2374 output_all_labels ();
2375 output_all_functions ();
2376 output_all_variables ();
2377 output_all_files ();
2378 output_all_macros ();
2379
2380 final ();
2381 return 0;
2382 }
2383 /* ====================================================================== */