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