#! /usr/bin/perl use strict; use warnings; my $debug = 0; # Search for calls to macros defining new channels, and prepare the tree representation my %ancestor; my %desc; # $ancestor{"toto"} is the ancestor of the toto channel # $desc{"toto"} is its description sub parse_file { my $filename = shift; my $data = ""; print "Parse $filename\n" if $debug; open IN, "$filename" || die "Cannot read $filename: $!\n"; while () { $data .= $_; } close IN; # Purge $data from C comments $data =~ s|/\*.*?\*/||sg; # C++ comments are forbiden in SG for portability reasons, but deal with it anyway $data =~ s|//.*$||mg; while ($data =~ s/^.*?XBT_LOG_NEW(_DEFAULT)?_(SUB)?CATEGORY\(//s) { $data =~ s/([^"]*"[^"]*")\)//s || die "unparsable macro: $data"; # ]]); my $ctn = $1; # cleanup the content $ctn =~ s/ *\n//gs; $ctn =~ s/,\s*"/,"/gs; $ctn =~ s/"\s*$/"/gs; $ctn =~ s/,\s*/,/gs; my @elms_tmp=split (/,/,$ctn); my @elms; print "ctn=$ctn\n" if $debug > 1; # There may be some ',' in the description. Remerge the stuff like: "description, really" while (1) { my $acc = shift @elms_tmp; last unless defined $acc; if ($acc =~ /^"/) { # ") { while (shift @elms_tmp) { $acc .= $_; } die "Unparsable content: $ctn\n" unless ($acc =~ s/^"(.*)"$/$1/); } print " seen $acc\n" if $debug > 1; push @elms, $acc; } my ($name,$anc,$desc); # build the tree, checking for name conflict if (scalar(@elms) eq 3) { $name = $elms[0]; $anc = $elms[1]; $desc = $elms[2]; } elsif (scalar(@elms) eq 2) { $name = $elms[0]; $anc = "XBT_LOG_ROOT_CAT"; $desc = $elms[1]; } else { my $l = scalar(@elms); my $s = ""; map {$s .= $_;} @elms; die "Unparsable content: $ctn (length=$l) (content=$s)\n"; } $name =~ s/^\s*(\S*)\s*$/$1/; # trim $anc =~ s/^\s*(\S*)\s*$/$1/; # trim die "ERROR: Category name conflict: $name used several times\n" if defined ($ancestor{$name}) && $ancestor{$name} ne $anc && defined ($desc{$name}) && $desc{$name} ne $desc; $ancestor{$name}=$anc; $desc{$name}=$desc; print " $name -> $anc\n" if $debug; } } # Retrieve all the file names, and add their content to $data my $data; open FILES, "find -name '*.c'|" || die "Cannot search for the source file names; $!\n"; while (my $file=) { chomp $file; parse_file($file); } close FILES; # Display the tree, looking for disconnected elems my %used; sub display_subtree { my $name=shift; my $indent=shift; $used{$name} = 1; unless ($name eq "XBT_LOG_ROOT_CAT") { # do not display the root print "$indent - $name: ".($desc{$name}|| "(undocumented)")."\n"; } foreach my $cat (grep {$ancestor{$_} eq $name} sort keys %ancestor) { display_subtree($cat,"$indent "); } } display_subtree("XBT_LOG_ROOT_CAT",""); map {warn "Category $_ does not seem to be connected to the root (anc=$ancestor{$_})\n";} grep {!defined $used{$_}} sort keys %ancestor;