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