File indexing completed on 2024-12-15 03:36:25

0001 #!/usr/bin/perl
0002 
0003 # Transform K&R C function definitions into ANSI equivalent.
0004 #
0005 # Author: Paul Marquess
0006 # Version: 1.0
0007 # Date: 3 October 2006
0008 
0009 # TODO
0010 #
0011 # Asumes no function pointer parameters. unless they are typedefed.
0012 # Assumes no literal strings that look like function definitions
0013 # Assumes functions start at the beginning of a line
0014 
0015 use strict;
0016 use warnings;
0017 
0018 local $/;
0019 $_ = <>;
0020 
0021 my $sp = qr{ \s* (?: /\* .*? \*/ )? \s* }x; # assume no nested comments
0022 
0023 my $d1    = qr{ $sp (?: [\w\*\s]+ $sp)* $sp \w+ $sp [\[\]\s]* $sp }x ;
0024 my $decl  = qr{ $sp (?: \w+ $sp )+ $d1 }xo ;
0025 my $dList = qr{ $sp $decl (?: $sp , $d1 )* $sp ; $sp }xo ;
0026 
0027 
0028 while (s/^
0029             (                  # Start $1
0030                 (              #   Start $2
0031                     .*?        #     Minimal eat content
0032                     ( ^ \w [\w\s\*]+ )    #     $3 -- function name
0033                     \s*        #     optional whitespace
0034                 )              # $2 - Matched up to before parameter list
0035 
0036                 \( \s*         # Literal "(" + optional whitespace
0037                 ( [^\)]+ )     # $4 - one or more anythings except ")"
0038                 \s* \)         # optional whitespace surrounding a Literal ")"
0039 
0040                 ( (?: $dList )+ ) # $5
0041 
0042                 $sp ^ {        # literal "{" at start of line
0043             )                  # Remember to $1
0044         //xsom
0045       )
0046 {
0047     my $all = $1 ;
0048     my $prefix = $2;
0049     my $param_list = $4 ;
0050     my $params = $5;
0051 
0052     StripComments($params);
0053     StripComments($param_list);
0054     $param_list =~ s/^\s+//;
0055     $param_list =~ s/\s+$//;
0056 
0057     my $i = 0 ;
0058     my %pList = map { $_ => $i++ }
0059                 split /\s*,\s*/, $param_list;
0060     my $pMatch = '(\b' . join('|', keys %pList) . '\b)\W*$' ;
0061 
0062     my @params = split /\s*;\s*/, $params;
0063     my @outParams = ();
0064     foreach my $p (@params)
0065     {
0066         if ($p =~ /,/)
0067         {
0068             my @bits = split /\s*,\s*/, $p;
0069             my $first = shift @bits;
0070             $first =~ s/^\s*//;
0071             push @outParams, $first;
0072             $first =~ /^(\w+\s*)/;
0073             my $type = $1 ;
0074             push @outParams, map { $type . $_ } @bits;
0075         }
0076         else
0077         {
0078             $p =~ s/^\s+//;
0079             push @outParams, $p;
0080         }
0081     }
0082 
0083 
0084     my %tmp = map { /$pMatch/;  $_ => $pList{$1}  }
0085               @outParams ;
0086 
0087     @outParams = map  { "    $_" }
0088                  sort { $tmp{$a} <=> $tmp{$b} }
0089                  @outParams ;
0090 
0091     print $prefix ;
0092     print "(\n" . join(",\n", @outParams) . ")\n";
0093     print "{" ;
0094 
0095 }
0096 
0097 # Output any trailing code.
0098 print ;
0099 exit 0;
0100 
0101 
0102 sub StripComments
0103 {
0104 
0105   no warnings;
0106 
0107   # Strip C & C++ coments
0108   # From the perlfaq
0109   $_[0] =~
0110 
0111     s{
0112        /\*         ##  Start of /* ... */ comment
0113        [^*]*\*+    ##  Non-* followed by 1-or-more *'s
0114        (
0115          [^/*][^*]*\*+
0116        )*          ##  0-or-more things which don't start with /
0117                    ##    but do end with '*'
0118        /           ##  End of /* ... */ comment
0119 
0120      |         ##     OR  C++ Comment
0121        //          ## Start of C++ comment //
0122        [^\n]*      ## followed by 0-or-more non end of line characters
0123 
0124      |         ##     OR  various things which aren't comments:
0125 
0126        (
0127          "           ##  Start of " ... " string
0128          (
0129            \\.           ##  Escaped char
0130          |               ##    OR
0131            [^"\\]        ##  Non "\
0132          )*
0133          "           ##  End of " ... " string
0134 
0135        |         ##     OR
0136 
0137          '           ##  Start of ' ... ' string
0138          (
0139            \\.           ##  Escaped char
0140          |               ##    OR
0141            [^'\\]        ##  Non '\
0142          )*
0143          '           ##  End of ' ... ' string
0144 
0145        |         ##     OR
0146 
0147          .           ##  Anything other char
0148          [^/"'\\]*   ##  Chars which doesn't start a comment, string or escape
0149        )
0150      }{$2}gxs;
0151 
0152 }