root/dxref.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. emalloc
  2. print_usage
  3. process_args
  4. init
  5. final
  6. count_children
  7. search_sibling
  8. create_dir_table
  9. delete_dir_table
  10. create_file_table
  11. create_line_table
  12. create_comp_unit_table
  13. create_abbrev_table
  14. do_src2html
  15. href_info
  16. href_info2
  17. href_macinfo
  18. href_macinfo2
  19. href_src1
  20. href_src2
  21. a_name
  22. eval_xpath
  23. get_child
  24. get_tag
  25. get_attr
  26. get_attr_value
  27. get_attr_value_ref
  28. get_attr_desc
  29. get_type
  30. get_params
  31. get_subscript
  32. get_comp_unit
  33. get_filename_by_char
  34. get_filename_by_node
  35. get_filename_by_int
  36. get_pathname_by_char
  37. get_pathname_by_node
  38. get_pathname_by_int
  39. get_line
  40. get_name
  41. type_to_string
  42. base_type_to_string
  43. array_type_to_string
  44. ptr_type_to_string
  45. func_type_to_string
  46. volatile_to_string
  47. const_to_string
  48. struct_union_to_string
  49. struct_to_string
  50. union_to_string
  51. members_to_string
  52. enum_to_string
  53. enum_constants_to_string
  54. output_indent
  55. visit_all_children
  56. output_debug_info_top
  57. output_debug_info
  58. output_compile_unit
  59. output_subprogram
  60. output_lexical_block
  61. output_variable
  62. output_label
  63. output_typedef
  64. output_enum
  65. output_enum_constants
  66. output_struct_union
  67. output_struct
  68. output_union
  69. output_members
  70. output_all_structs
  71. output_all_unions
  72. output_all_typedefs
  73. output_all_enum_tags
  74. output_all_enum_consts
  75. output_all_labels
  76. output_all_functions
  77. output_all_variables
  78. output_all_files
  79. get_macinfo_id
  80. output_all_macros
  81. 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. (&lt;) */
 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", &reg) == 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 /* ====================================================================== */

/* [<][>][^][v][top][bottom][index][help] */