1*4e00368fSchristos#!/usr/bin/perl 2*4e00368fSchristos 3*4e00368fSchristos# Transform K&R C function definitions into ANSI equivalent. 4*4e00368fSchristos# 5*4e00368fSchristos# Author: Paul Marquess 6*4e00368fSchristos# Version: 1.0 7*4e00368fSchristos# Date: 3 October 2006 8*4e00368fSchristos 9*4e00368fSchristos# TODO 10*4e00368fSchristos# 11*4e00368fSchristos# Asumes no function pointer parameters. unless they are typedefed. 12*4e00368fSchristos# Assumes no literal strings that look like function definitions 13*4e00368fSchristos# Assumes functions start at the beginning of a line 14*4e00368fSchristos 15*4e00368fSchristosuse strict; 16*4e00368fSchristosuse warnings; 17*4e00368fSchristos 18*4e00368fSchristoslocal $/; 19*4e00368fSchristos$_ = <>; 20*4e00368fSchristos 21*4e00368fSchristosmy $sp = qr{ \s* (?: /\* .*? \*/ )? \s* }x; # assume no nested comments 22*4e00368fSchristos 23*4e00368fSchristosmy $d1 = qr{ $sp (?: [\w\*\s]+ $sp)* $sp \w+ $sp [\[\]\s]* $sp }x ; 24*4e00368fSchristosmy $decl = qr{ $sp (?: \w+ $sp )+ $d1 }xo ; 25*4e00368fSchristosmy $dList = qr{ $sp $decl (?: $sp , $d1 )* $sp ; $sp }xo ; 26*4e00368fSchristos 27*4e00368fSchristos 28*4e00368fSchristoswhile (s/^ 29*4e00368fSchristos ( # Start $1 30*4e00368fSchristos ( # Start $2 31*4e00368fSchristos .*? # Minimal eat content 32*4e00368fSchristos ( ^ \w [\w\s\*]+ ) # $3 -- function name 33*4e00368fSchristos \s* # optional whitespace 34*4e00368fSchristos ) # $2 - Matched up to before parameter list 35*4e00368fSchristos 36*4e00368fSchristos \( \s* # Literal "(" + optional whitespace 37*4e00368fSchristos ( [^\)]+ ) # $4 - one or more anythings except ")" 38*4e00368fSchristos \s* \) # optional whitespace surrounding a Literal ")" 39*4e00368fSchristos 40*4e00368fSchristos ( (?: $dList )+ ) # $5 41*4e00368fSchristos 42*4e00368fSchristos $sp ^ { # literal "{" at start of line 43*4e00368fSchristos ) # Remember to $1 44*4e00368fSchristos //xsom 45*4e00368fSchristos ) 46*4e00368fSchristos{ 47*4e00368fSchristos my $all = $1 ; 48*4e00368fSchristos my $prefix = $2; 49*4e00368fSchristos my $param_list = $4 ; 50*4e00368fSchristos my $params = $5; 51*4e00368fSchristos 52*4e00368fSchristos StripComments($params); 53*4e00368fSchristos StripComments($param_list); 54*4e00368fSchristos $param_list =~ s/^\s+//; 55*4e00368fSchristos $param_list =~ s/\s+$//; 56*4e00368fSchristos 57*4e00368fSchristos my $i = 0 ; 58*4e00368fSchristos my %pList = map { $_ => $i++ } 59*4e00368fSchristos split /\s*,\s*/, $param_list; 60*4e00368fSchristos my $pMatch = '(\b' . join('|', keys %pList) . '\b)\W*$' ; 61*4e00368fSchristos 62*4e00368fSchristos my @params = split /\s*;\s*/, $params; 63*4e00368fSchristos my @outParams = (); 64*4e00368fSchristos foreach my $p (@params) 65*4e00368fSchristos { 66*4e00368fSchristos if ($p =~ /,/) 67*4e00368fSchristos { 68*4e00368fSchristos my @bits = split /\s*,\s*/, $p; 69*4e00368fSchristos my $first = shift @bits; 70*4e00368fSchristos $first =~ s/^\s*//; 71*4e00368fSchristos push @outParams, $first; 72*4e00368fSchristos $first =~ /^(\w+\s*)/; 73*4e00368fSchristos my $type = $1 ; 74*4e00368fSchristos push @outParams, map { $type . $_ } @bits; 75*4e00368fSchristos } 76*4e00368fSchristos else 77*4e00368fSchristos { 78*4e00368fSchristos $p =~ s/^\s+//; 79*4e00368fSchristos push @outParams, $p; 80*4e00368fSchristos } 81*4e00368fSchristos } 82*4e00368fSchristos 83*4e00368fSchristos 84*4e00368fSchristos my %tmp = map { /$pMatch/; $_ => $pList{$1} } 85*4e00368fSchristos @outParams ; 86*4e00368fSchristos 87*4e00368fSchristos @outParams = map { " $_" } 88*4e00368fSchristos sort { $tmp{$a} <=> $tmp{$b} } 89*4e00368fSchristos @outParams ; 90*4e00368fSchristos 91*4e00368fSchristos print $prefix ; 92*4e00368fSchristos print "(\n" . join(",\n", @outParams) . ")\n"; 93*4e00368fSchristos print "{" ; 94*4e00368fSchristos 95*4e00368fSchristos} 96*4e00368fSchristos 97*4e00368fSchristos# Output any trailing code. 98*4e00368fSchristosprint ; 99*4e00368fSchristosexit 0; 100*4e00368fSchristos 101*4e00368fSchristos 102*4e00368fSchristossub StripComments 103*4e00368fSchristos{ 104*4e00368fSchristos 105*4e00368fSchristos no warnings; 106*4e00368fSchristos 107*4e00368fSchristos # Strip C & C++ coments 108*4e00368fSchristos # From the perlfaq 109*4e00368fSchristos $_[0] =~ 110*4e00368fSchristos 111*4e00368fSchristos s{ 112*4e00368fSchristos /\* ## Start of /* ... */ comment 113*4e00368fSchristos [^*]*\*+ ## Non-* followed by 1-or-more *'s 114*4e00368fSchristos ( 115*4e00368fSchristos [^/*][^*]*\*+ 116*4e00368fSchristos )* ## 0-or-more things which don't start with / 117*4e00368fSchristos ## but do end with '*' 118*4e00368fSchristos / ## End of /* ... */ comment 119*4e00368fSchristos 120*4e00368fSchristos | ## OR C++ Comment 121*4e00368fSchristos // ## Start of C++ comment // 122*4e00368fSchristos [^\n]* ## followed by 0-or-more non end of line characters 123*4e00368fSchristos 124*4e00368fSchristos | ## OR various things which aren't comments: 125*4e00368fSchristos 126*4e00368fSchristos ( 127*4e00368fSchristos " ## Start of " ... " string 128*4e00368fSchristos ( 129*4e00368fSchristos \\. ## Escaped char 130*4e00368fSchristos | ## OR 131*4e00368fSchristos [^"\\] ## Non "\ 132*4e00368fSchristos )* 133*4e00368fSchristos " ## End of " ... " string 134*4e00368fSchristos 135*4e00368fSchristos | ## OR 136*4e00368fSchristos 137*4e00368fSchristos ' ## Start of ' ... ' string 138*4e00368fSchristos ( 139*4e00368fSchristos \\. ## Escaped char 140*4e00368fSchristos | ## OR 141*4e00368fSchristos [^'\\] ## Non '\ 142*4e00368fSchristos )* 143*4e00368fSchristos ' ## End of ' ... ' string 144*4e00368fSchristos 145*4e00368fSchristos | ## OR 146*4e00368fSchristos 147*4e00368fSchristos . ## Anything other char 148*4e00368fSchristos [^/"'\\]* ## Chars which doesn't start a comment, string or escape 149*4e00368fSchristos ) 150*4e00368fSchristos }{$2}gxs; 151*4e00368fSchristos 152*4e00368fSchristos} 153