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