diff options
Diffstat (limited to 'scripts/movedocs.pl')
-rwxr-xr-x | scripts/movedocs.pl | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/scripts/movedocs.pl b/scripts/movedocs.pl new file mode 100755 index 0000000000..923c633f13 --- /dev/null +++ b/scripts/movedocs.pl @@ -0,0 +1,180 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +if ($ARGV[0] eq '--help') { + print << "EOF"; +Usage: + + $0 file.h file.c + +Removes documentation attached to function declarations in file.h and adds them +to function definitions found in file.c. + + $0 file.c + +Moves documentation attached to function declaration present in the same file as +the definition. +EOF + exit 0; +} + +my $hfile = shift @ARGV; +my @cfiles = @ARGV; + +my %docs = (); +my $F; + +sub write_lines { + my $file = shift; + my @lines = @_; + + my $F; + + open $F, '>', $file; + print $F (join "", @lines); + close $F; +} + +if (@cfiles) { + open $F, '<', $hfile + or die "Failed to open $hfile."; + + my @hlines = (); + + my $lastdoc = ''; + + while (<$F>) { + if (/^\/\/\/?/) { + $lastdoc .= $_; + } elsif (/^\S.*?(\w+)\(.*(?:,|\);?|FUNC_ATTR_\w+;?)$/) { + die "Documentation for $1 was already defined" if (defined $docs{$1}); + if ($lastdoc ne '') { + $docs{$1} = $lastdoc; + $lastdoc = ''; + } + push @hlines, $_; + } elsif ($lastdoc ne '') { + push @hlines, $lastdoc; + $lastdoc = ''; + push @hlines, $_; + } else { + push @hlines, $_; + } + } + + close $F; + + my %clines_hash = (); + + for my $cfile (@cfiles) { + open $F, '<', $cfile + or die "Failed to open $cfile."; + + my @clines = (); + + while (<$F>) { + if (/^\S.*?(\w+)\(.*[,)]$/ and defined $docs{$1}) { + push @clines, $docs{$1}; + delete $docs{$1}; + } elsif (/^(?!static\s)\S.*?(\w+)\(.*[,)]$/ and not defined $docs{$1}) { + print STDERR "Documentation not defined for $1\n"; + } + push @clines, $_; + } + + close $F; + + $clines_hash{$cfile} = \@clines; + } + + while (my ($func, $value) = each %docs) { + die "Function not found: $func\n"; + } + + write_lines($hfile, @hlines); + while (my ($cfile, $clines) = each %clines_hash) { + write_lines($cfile, @$clines); + } +} else { + open $F, '<', $hfile; + + my @lines; + + my $lastdoc = ''; + my $defstart = ''; + my $funcname; + + sub clear_lastdoc { + if ($lastdoc ne '') { + push @lines, $lastdoc; + $lastdoc = ''; + } + } + + sub record_lastdoc { + my $funcname = shift; + if ($lastdoc ne '') { + $docs{$funcname} = $lastdoc; + $lastdoc = ''; + } + } + + sub add_doc { + my $funcname = shift; + if (defined $docs{$funcname}) { + push @lines, $docs{$funcname}; + delete $docs{$funcname}; + } + } + + sub clear_defstart { + push @lines, $defstart; + $defstart = ''; + } + + while (<$F>) { + if (/\/\*/ .. /\*\// and not /\/\*.*?\*\//) { + push @lines, $_; + } elsif (/^\/\/\/?/) { + $lastdoc .= $_; + } elsif (/^\S.*?(\w+)\(.*(?:,|(\);?))$/) { + if (not $2) { + $defstart .= $_; + $funcname = $1; + } elsif ($2 eq ');') { + record_lastdoc $1; + push @lines, $_; + } elsif ($2 eq ')') { + clear_lastdoc; + add_doc $1; + push @lines, $_; + } + } elsif ($defstart ne '') { + $defstart .= $_; + if (/[{}]/) { + clear_lastdoc; + clear_defstart; + } elsif (/\);$/) { + record_lastdoc $funcname; + clear_defstart; + } elsif (/\)$/) { + clear_lastdoc; + add_doc $funcname; + clear_defstart; + } + } else { + clear_lastdoc; + push @lines, $_; + } + } + + close $F; + + while (my ($func, $value) = each %docs) { + die "Function not found: $func\n"; + } + + write_lines($hfile, @lines); +} |