Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Connect log category xbt_heap.
[simgrid.git] / tools / doxygen / xbt_log_extract_hierarchy.pl
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 my $debug = 0;
7
8 print "/* Generated file, do not edit */\n";
9 print "/** \\addtogroup XBT_log_cats\n";
10 print "        \@{\n";
11
12 # Search for calls to macros defining new channels, and prepare the tree representation
13 my %ancestor;
14 my %desc;
15 # $ancestor{"toto"} is the ancestor of the toto channel
16 #    as declared by XBT_LOG_NEW_SUBCATEGORY and XBT_LOG_NEW_DEFAULT_SUBCATEGORY
17 #    ie, when the channel toto is initialized (does not work under windows)
18
19 # $desc{"toto"} is its description
20 my %connected;
21 # $connected{"toto"} is defined if XBT_LOG_CONNECT("toto") is used
22
23 sub cleanup_ctn {
24     my $ctn = shift;        # cleanup the content of a macro call
25     $ctn =~ s/^\s*(.*)\s*$/$1/gs;
26     my @elms;
27     print "ctn=$ctn\n" if $debug > 1;
28     if ($ctn =~ m/^(\w+)\s*,\s*(\w+)\s*,\s*"?([^"]*)"?$/s) {
29         # Perfect, we got 0->name; 1->anc; 2->desc
30         $elms[0] = $1;
31         $elms[1] = $2;
32         $elms[2] = $3;
33     } elsif ($ctn =~ m/^(\w+)\s*,\s*"?([^"]*)"?$/s) {
34         # Mmm. got no ancestor. Add the default one.
35         $elms[0] = $1;
36         $elms[1] = "XBT_LOG_ROOT_CAT";
37         $elms[2] = $2;
38     } else {
39         die "Unparsable content: $ctn\n";
40     }
41     $elms[2] =~ s/\\\\/\\/gs;
42     return @elms;
43 }
44
45
46 sub parse_file {
47     my $filename = shift;
48     
49     my $data = "";
50     
51     print "Parse $filename\n" if $debug;
52     open IN, "$filename" || die "Cannot read $filename: $!\n";
53     while (<IN>) {
54         $data .= $_;
55     }
56     close IN;
57
58     # Purge $data from C comments
59     $data =~ s|/\*.*?\*/||sg;
60
61     # C++ comments are forbiden in SG for portability reasons, but deal with it anyway
62     $data =~ s|//.*$||mg;
63
64     my $connect_data = $data; # save a copy for second parsing phase
65     while ($data =~ s/^.*?XBT_LOG_NEW(_DEFAULT)?_(SUB)?CATEGORY\(//s) {
66         $data =~ s/([^"]*"[^"]*")\)//s || die "unparsable macro: $data";
67             
68         my ($name,$anc,$desc) = cleanup_ctn($1);
69             
70         # build the tree, checking for name conflict
71         die "ERROR: Category name conflict: $name used several times (in $ancestor{$name} and $anc, last time in $filename)\n"
72            if defined ($ancestor{$name}) && $ancestor{$name} ne $anc &&
73               defined ($desc{$name}) && $desc{$name} ne $desc;
74        $ancestor{$name}=$anc;
75        $desc{$name}=$desc;
76    
77        print " $name -> $anc\n" if $debug;
78    }
79
80    # Now, look for XBT_LOG_CONNECT calls
81    $data = $connect_data;
82    while ($data =~ s/^.*?XBT_LOG_CONNECT\(//s) {
83        $data =~ s/\s*(\w+)\s*\)//s || die "unparsable macro: $data";
84        $connected{$1} = 1;
85    }
86 }
87 # Retrieve all the file names, and add their content to $data
88 my $data;
89 open FILES, "find ../src/ ../tools/ ../include/ -name '*.c'|" || die "Cannot search for the source file names: $!\n";
90 while (my $file=<FILES>) {
91     chomp $file;
92     parse_file($file);  
93 }
94 close FILES;
95
96 # Display the tree, looking for disconnected elems    
97 my %used;
98         
99 sub display_subtree {
100     my $name=shift;
101     my $indent=shift;
102     
103     $used{$name} = 1;
104     unless ($name eq "XBT_LOG_ROOT_CAT") { # do not display the root
105         print "$indent - $name: ".($desc{$name}|| "(undocumented)")."\n";
106     }
107     foreach my $cat (grep {$ancestor{$_} eq $name} sort keys %ancestor) {
108         display_subtree($cat,"$indent  ");
109     }
110 }
111     
112 display_subtree("XBT_LOG_ROOT_CAT","");
113
114 map {
115     warn "Category $_ does not seem to be connected.  Use XBT_LOG_CONNECT($_).\n";
116 } grep {!defined $connected{$_}} sort keys %ancestor;
117 map {
118     warn "Category $_ does not seem to be connected to the root (anc=$ancestor{$_})\n";
119 } grep {!defined $used{$_}} sort keys %ancestor;
120
121         
122 print "@}*/\n";