Subject: | Patch for c++ parser in autodia |
Date: | Thu, 12 Apr 2012 19:23:47 +0300 |
To: | bug-Autodia [...] rt.cpan.org |
From: | Kim Nylund <kinylund [...] gmail.com> |
Hi,
I want to thank you for putting your autodia code publicly available.
Your tool is the best tool I have found for documenting c++ code.
I made the following patch to the c++ parser. helps for the following
issues:
Parse simple dependencies by adding dependency to includefiles
Support for class declarations that including namespace "class
NAME_SPACE classname"
fix a bug where } would exit parsing of classes including inline methods
Ignore inline declarations of structs and enums in classes
Fixed parsing of methods containing dots "method(...)", parenthesis
method"(int, (float, int, int))" and double pointers method(**int)
There are still a couple of bugs but if you are interested you can use
parts or the whole patch in the quest for a better c++ parser. There are
still some bugs like the issue when a inparameter dont contain a name in
the declaration in the .h file
example "int setMyValues(int, int, float)"
Probably there are many many more :)
Thanx again for the effort.
br.
Kim Nylund
ps I can probably send you a patch file later if you need one
diff -aur Autodia-2.14Orig/lib/Autodia/Handler/Cpp.pm
Autodia-2.14/lib/Autodia/Handler/Cpp.pm
--- Autodia-2.14Orig/lib/Autodia/Handler/Cpp.pm 2010-02-18
23:30:25.000000000 +0200
+++ Autodia-2.14/lib/Autodia/Handler/Cpp.pm 2012-04-12
17:07:29.000000000 +0300
@@ -58,6 +58,8 @@
$self->{in_method} = 0;
$self->{brace_depth} = 0;
+ my @dependancies = ();
+
my $i = 0;
# parse through file looking for stuff
@@ -71,13 +73,17 @@
# print "line $i : $line \n";
$i++;
+ if ($line =~ /#include\s+\"(\w+\/)*(\w+)\.h\"/) {
+ push(@dependancies, $2);
+ }
+
# check for class declaration
- if ($line =~ m/^\s*class\s+(\w+)/)
+ if ($line =~ m/^\s*class\s+(\w+\s+)?(\w+)/)
{
# print "found class : $line \n";
- my $classname = $1;
+ my $classname = $2;
$self->{in_class} = 1;
$self->{privacy} = "private";
$self->{visibility} = 1;
@@ -97,7 +103,7 @@
foreach my $super (@superclasses) {
$super =~ s/\s*//ig;
# warn "superclass : $super\n";
- $super =~ s/^\s*(\w+\s+)?([A-Za-z0-9\_]+)\s*$/$2/;
+ $super =~ s/^\s*(\w+\:\:)?([A-Za-z0-9\_]+)\s*.*$/$2/;
# warn "superclass : $super\n";
my $Superclass =
Autodia::Diagram::Superclass->new($super);
my $exists_already =
$Diagram->add_superclass($Superclass);
@@ -110,13 +116,33 @@
$Diagram->add_inheritance($Inheritance);
}
}
+
+ #Insert all dependancies
+ foreach my $dependancy (@dependancies) {
+# create component
+ my $Component =
Autodia::Diagram::Component->new($dependancy);
+# add component to diagram
+ my $exists = $Diagram->add_component($Component);
+# replace component if redundant
+ if (ref $exists) {
+ $Component = $exists;
+ }
+# create new dependancy
+ my $Dependancy =
Autodia::Diagram::Dependancy->new($Class, $Component);
+# add dependancy to diagram
+ $Diagram->add_dependancy($Dependancy);
+# add dependancy to class
+ $Class->add_dependancy($Dependancy);
+ # add dependancy to component
+ $Component->add_dependancy($Dependancy);
+ }
last LINE;
}
# check for end of class declaration
- if ($self->{in_class} && ($line =~ m|^\s*\}\;|))
+ if ($self->{in_class} && !$self->{in_method} && ($line =~
m|^\s*\}\;|))
{
-# print "found end of class\n";
+ #print "found end of class\n";
$self->{in_class} = 0;
$self->{privacy} = 0;
last LINE;
@@ -155,39 +181,39 @@
last LINE;
}
- if ($line =~ m/operator/)
+ # if inside a class method then discard line
+ if ($self->{in_method})
{
-# print "found overloaded operator\n";
- last LINE if $line =~ /;/;
-
- while ($line !~ /{/)
- {
- $line = <$fh>;
-# print "waiting for start of overload def: $line\n";
- }
+ # count number of braces and increment decrement depth
accordingly
+ # if depth = 0 then reset in_method and next;
+ # else next;
my $start_brace_cnt = $line =~ tr/{/{/ ;
my $end_brace_cnt = $line =~ tr/}/}/ ;
- $self->{brace_depth} = $start_brace_cnt - $end_brace_cnt;
- $self->{in_method} = 1 unless $self->{brace_depth}
== 0;
-# print "OvStart: ",$start_brace_cnt, $end_brace_cnt,
$self->{brace_depth}, $self->{in_method} ,"\n";
+ $self->{brace_depth} = $self->{brace_depth} +
$start_brace_cnt - $end_brace_cnt;
+ $self->{in_method} = ($self->{brace_depth} == 0 ? 0
: 1);
+ #print "Inline method: ", $start_brace_cnt,
$end_brace_cnt, $self->{brace_depth}, $self->{in_method} ,"\n";
last LINE;
}
- # if inside a class method then discard line
- if ($self->{in_method})
+ if ($line =~ m/operator|enum|struct/)
{
- # count number of braces and increment decrement depth
accordingly
- # if depth = 0 then reset in_method and next;
- # else next;
+ #print "found overloaded operator, enum or struct\n";
+ last LINE if $line =~ /;/;
+
+ while ($line !~ /{/)
+ {
+ $line = <$fh>;
+ print "waiting for start of def: $line\n";
+ }
my $start_brace_cnt = $line =~ tr/{/{/ ;
my $end_brace_cnt = $line =~ tr/}/}/ ;
- $self->{brace_depth} = $self->{brace_depth} +
$start_brace_cnt - $end_brace_cnt;
- $self->{in_method} = $self->{brace_depth} == 0 ? 0 : 1;
+ $self->{brace_depth} = $start_brace_cnt - $end_brace_cnt;
+ $self->{in_method} = 1 unless $self->{brace_depth}
== 0;
+ #print "Inline start: ",$start_brace_cnt,
$end_brace_cnt, $self->{brace_depth}, $self->{in_method} ,"\n";
-# print "In method: ",$start_brace_cnt, $end_brace_cnt,
$self->{brace_depth}, $self->{in_method} ,"\n";
last LINE;
}
@@ -198,7 +224,7 @@
{
my $name = $3;
my $type = $1;
-# print "found simple variable declaration : name =
$name, type = $type\n";
+ #print "found simple variable declaration : name =
$name, type = $type\n";
#my $visibility = ( $name =~ m/^\_/ ) ? 1 : 0;
@@ -219,8 +245,8 @@
(~?\w+) # name of the
method: $3
\s* # whitespace
\(\s* # start of
parameter list
- ([:\w\,\s\*=&\"<>\\\d\-]*) # all
parameters: $4
- (\)?) # may be an ending
bracket: $5
+ ([:\w\,\s\*=&\"<>\\\d\-\.\(\)\/]*) # all
parameters: $4
+ (\)) # may be an ending
bracket: $5
[\w\s=]*(;?) # possibly end of
signature $6
.*$/x
)
@@ -307,7 +333,7 @@
foreach my $parameter (@params)
{
$parameter =~ s/const\s+//;
- $parameter =~
m/\s*((\w+::)*[\w<>]+\s*[\*|\&]?)\s*(\w+)/ ;
+ $parameter =~
m/\s*((\w+::)*[\w<>]+\s*[\*|\*\*|\&]?)\s*(\w+)/ ;
my ($type, $name) = ($1,$3);
$type =~ s/\s//g;
@@ -339,7 +365,7 @@
$self->{brace_depth} = $start_brace_cnt - $end_brace_cnt;
$self->{in_method} = 1 unless $self->{brace_depth}
== 0;
-# print "Start: ",$start_brace_cnt, $end_brace_cnt,
$self->{brace_depth}, $self->{in_method} ,"\n";
+ #print "Start: ",$start_brace_cnt, $end_brace_cnt,
$self->{brace_depth}, $self->{in_method} ,"\n";
last LINE;
}