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