| #!/usr/bin/perl |
| |
| # Transform K&R C function definitions into ANSI equivalent. |
| # |
| # Author: Paul Marquess |
| # Version: 1.0 |
| # Date: 3 October 2006 |
| |
| # TODO |
| # |
| # Asumes no function pointer parameters. unless they are typedefed. |
| # Assumes no literal strings that look like function definitions |
| # Assumes functions start at the beginning of a line |
| |
| use strict; |
| use warnings; |
| |
| local $/; |
| $_ = <>; |
| |
| my $sp = qr{ \s* (?: /\* .*? \*/ )? \s* }x; # assume no nested comments |
| |
| my $d1 = qr{ $sp (?: [\w\*\s]+ $sp)* $sp \w+ $sp [\[\]\s]* $sp }x ; |
| my $decl = qr{ $sp (?: \w+ $sp )+ $d1 }xo ; |
| my $dList = qr{ $sp $decl (?: $sp , $d1 )* $sp ; $sp }xo ; |
| |
| |
| while (s/^ |
| ( # Start $1 |
| ( # Start $2 |
| .*? # Minimal eat content |
| ( ^ \w [\w\s\*]+ ) # $3 -- function name |
| \s* # optional whitespace |
| ) # $2 - Matched up to before parameter list |
| |
| \( \s* # Literal "(" + optional whitespace |
| ( [^\)]+ ) # $4 - one or more anythings except ")" |
| \s* \) # optional whitespace surrounding a Literal ")" |
| |
| ( (?: $dList )+ ) # $5 |
| |
| $sp ^ { # literal "{" at start of line |
| ) # Remember to $1 |
| //xsom |
| ) |
| { |
| my $all = $1 ; |
| my $prefix = $2; |
| my $param_list = $4 ; |
| my $params = $5; |
| |
| StripComments($params); |
| StripComments($param_list); |
| $param_list =~ s/^\s+//; |
| $param_list =~ s/\s+$//; |
| |
| my $i = 0 ; |
| my %pList = map { $_ => $i++ } |
| split /\s*,\s*/, $param_list; |
| my $pMatch = '(\b' . join('|', keys %pList) . '\b)\W*$' ; |
| |
| my @params = split /\s*;\s*/, $params; |
| my @outParams = (); |
| foreach my $p (@params) |
| { |
| if ($p =~ /,/) |
| { |
| my @bits = split /\s*,\s*/, $p; |
| my $first = shift @bits; |
| $first =~ s/^\s*//; |
| push @outParams, $first; |
| $first =~ /^(\w+\s*)/; |
| my $type = $1 ; |
| push @outParams, map { $type . $_ } @bits; |
| } |
| else |
| { |
| $p =~ s/^\s+//; |
| push @outParams, $p; |
| } |
| } |
| |
| |
| my %tmp = map { /$pMatch/; $_ => $pList{$1} } |
| @outParams ; |
| |
| @outParams = map { " $_" } |
| sort { $tmp{$a} <=> $tmp{$b} } |
| @outParams ; |
| |
| print $prefix ; |
| print "(\n" . join(",\n", @outParams) . ")\n"; |
| print "{" ; |
| |
| } |
| |
| # Output any trailing code. |
| print ; |
| exit 0; |
| |
| |
| sub StripComments |
| { |
| |
| no warnings; |
| |
| # Strip C & C++ coments |
| # From the perlfaq |
| $_[0] =~ |
| |
| s{ |
| /\* ## Start of /* ... */ comment |
| [^*]*\*+ ## Non-* followed by 1-or-more *'s |
| ( |
| [^/*][^*]*\*+ |
| )* ## 0-or-more things which don't start with / |
| ## but do end with '*' |
| / ## End of /* ... */ comment |
| |
| | ## OR C++ Comment |
| // ## Start of C++ comment // |
| [^\n]* ## followed by 0-or-more non end of line characters |
| |
| | ## OR various things which aren't comments: |
| |
| ( |
| " ## Start of " ... " string |
| ( |
| \\. ## Escaped char |
| | ## OR |
| [^"\\] ## Non "\ |
| )* |
| " ## End of " ... " string |
| |
| | ## OR |
| |
| ' ## Start of ' ... ' string |
| ( |
| \\. ## Escaped char |
| | ## OR |
| [^'\\] ## Non '\ |
| )* |
| ' ## End of ' ... ' string |
| |
| | ## OR |
| |
| . ## Anything other char |
| [^/"'\\]* ## Chars which doesn't start a comment, string or escape |
| ) |
| }{$2}gxs; |
| |
| } |