1275793eaSopenharmony_ci#!/usr/bin/perl
2275793eaSopenharmony_ci
3275793eaSopenharmony_ci# Transform K&R C function definitions into ANSI equivalent.
4275793eaSopenharmony_ci#
5275793eaSopenharmony_ci# Author: Paul Marquess
6275793eaSopenharmony_ci# Version: 1.0
7275793eaSopenharmony_ci# Date: 3 October 2006
8275793eaSopenharmony_ci
9275793eaSopenharmony_ci# TODO
10275793eaSopenharmony_ci#
11275793eaSopenharmony_ci# Assumes no function pointer parameters. unless they are typedefed.
12275793eaSopenharmony_ci# Assumes no literal strings that look like function definitions
13275793eaSopenharmony_ci# Assumes functions start at the beginning of a line
14275793eaSopenharmony_ci
15275793eaSopenharmony_ciuse strict;
16275793eaSopenharmony_ciuse warnings;
17275793eaSopenharmony_ci
18275793eaSopenharmony_cilocal $/;
19275793eaSopenharmony_ci$_ = <>;
20275793eaSopenharmony_ci
21275793eaSopenharmony_cimy $sp = qr{ \s* (?: /\* .*? \*/ )? \s* }x; # assume no nested comments
22275793eaSopenharmony_ci
23275793eaSopenharmony_cimy $d1    = qr{ $sp (?: [\w\*\s]+ $sp)* $sp \w+ $sp [\[\]\s]* $sp }x ;
24275793eaSopenharmony_cimy $decl  = qr{ $sp (?: \w+ $sp )+ $d1 }xo ;
25275793eaSopenharmony_cimy $dList = qr{ $sp $decl (?: $sp , $d1 )* $sp ; $sp }xo ;
26275793eaSopenharmony_ci
27275793eaSopenharmony_ci
28275793eaSopenharmony_ciwhile (s/^
29275793eaSopenharmony_ci            (                  # Start $1
30275793eaSopenharmony_ci                (              #   Start $2
31275793eaSopenharmony_ci                    .*?        #     Minimal eat content
32275793eaSopenharmony_ci                    ( ^ \w [\w\s\*]+ )    #     $3 -- function name
33275793eaSopenharmony_ci                    \s*        #     optional whitespace
34275793eaSopenharmony_ci                )              # $2 - Matched up to before parameter list
35275793eaSopenharmony_ci
36275793eaSopenharmony_ci                \( \s*         # Literal "(" + optional whitespace
37275793eaSopenharmony_ci                ( [^\)]+ )     # $4 - one or more anythings except ")"
38275793eaSopenharmony_ci                \s* \)         # optional whitespace surrounding a Literal ")"
39275793eaSopenharmony_ci
40275793eaSopenharmony_ci                ( (?: $dList )+ ) # $5
41275793eaSopenharmony_ci
42275793eaSopenharmony_ci                $sp ^ {        # literal "{" at start of line
43275793eaSopenharmony_ci            )                  # Remember to $1
44275793eaSopenharmony_ci        //xsom
45275793eaSopenharmony_ci      )
46275793eaSopenharmony_ci{
47275793eaSopenharmony_ci    my $all = $1 ;
48275793eaSopenharmony_ci    my $prefix = $2;
49275793eaSopenharmony_ci    my $param_list = $4 ;
50275793eaSopenharmony_ci    my $params = $5;
51275793eaSopenharmony_ci
52275793eaSopenharmony_ci    StripComments($params);
53275793eaSopenharmony_ci    StripComments($param_list);
54275793eaSopenharmony_ci    $param_list =~ s/^\s+//;
55275793eaSopenharmony_ci    $param_list =~ s/\s+$//;
56275793eaSopenharmony_ci
57275793eaSopenharmony_ci    my $i = 0 ;
58275793eaSopenharmony_ci    my %pList = map { $_ => $i++ }
59275793eaSopenharmony_ci                split /\s*,\s*/, $param_list;
60275793eaSopenharmony_ci    my $pMatch = '(\b' . join('|', keys %pList) . '\b)\W*$' ;
61275793eaSopenharmony_ci
62275793eaSopenharmony_ci    my @params = split /\s*;\s*/, $params;
63275793eaSopenharmony_ci    my @outParams = ();
64275793eaSopenharmony_ci    foreach my $p (@params)
65275793eaSopenharmony_ci    {
66275793eaSopenharmony_ci        if ($p =~ /,/)
67275793eaSopenharmony_ci        {
68275793eaSopenharmony_ci            my @bits = split /\s*,\s*/, $p;
69275793eaSopenharmony_ci            my $first = shift @bits;
70275793eaSopenharmony_ci            $first =~ s/^\s*//;
71275793eaSopenharmony_ci            push @outParams, $first;
72275793eaSopenharmony_ci            $first =~ /^(\w+\s*)/;
73275793eaSopenharmony_ci            my $type = $1 ;
74275793eaSopenharmony_ci            push @outParams, map { $type . $_ } @bits;
75275793eaSopenharmony_ci        }
76275793eaSopenharmony_ci        else
77275793eaSopenharmony_ci        {
78275793eaSopenharmony_ci            $p =~ s/^\s+//;
79275793eaSopenharmony_ci            push @outParams, $p;
80275793eaSopenharmony_ci        }
81275793eaSopenharmony_ci    }
82275793eaSopenharmony_ci
83275793eaSopenharmony_ci
84275793eaSopenharmony_ci    my %tmp = map { /$pMatch/;  $_ => $pList{$1}  }
85275793eaSopenharmony_ci              @outParams ;
86275793eaSopenharmony_ci
87275793eaSopenharmony_ci    @outParams = map  { "    $_" }
88275793eaSopenharmony_ci                 sort { $tmp{$a} <=> $tmp{$b} }
89275793eaSopenharmony_ci                 @outParams ;
90275793eaSopenharmony_ci
91275793eaSopenharmony_ci    print $prefix ;
92275793eaSopenharmony_ci    print "(\n" . join(",\n", @outParams) . ")\n";
93275793eaSopenharmony_ci    print "{" ;
94275793eaSopenharmony_ci
95275793eaSopenharmony_ci}
96275793eaSopenharmony_ci
97275793eaSopenharmony_ci# Output any trailing code.
98275793eaSopenharmony_ciprint ;
99275793eaSopenharmony_ciexit 0;
100275793eaSopenharmony_ci
101275793eaSopenharmony_ci
102275793eaSopenharmony_cisub StripComments
103275793eaSopenharmony_ci{
104275793eaSopenharmony_ci
105275793eaSopenharmony_ci  no warnings;
106275793eaSopenharmony_ci
107275793eaSopenharmony_ci  # Strip C & C++ comments
108275793eaSopenharmony_ci  # From the perlfaq
109275793eaSopenharmony_ci  $_[0] =~
110275793eaSopenharmony_ci
111275793eaSopenharmony_ci    s{
112275793eaSopenharmony_ci       /\*         ##  Start of /* ... */ comment
113275793eaSopenharmony_ci       [^*]*\*+    ##  Non-* followed by 1-or-more *'s
114275793eaSopenharmony_ci       (
115275793eaSopenharmony_ci         [^/*][^*]*\*+
116275793eaSopenharmony_ci       )*          ##  0-or-more things which don't start with /
117275793eaSopenharmony_ci                   ##    but do end with '*'
118275793eaSopenharmony_ci       /           ##  End of /* ... */ comment
119275793eaSopenharmony_ci
120275793eaSopenharmony_ci     |         ##     OR  C++ Comment
121275793eaSopenharmony_ci       //          ## Start of C++ comment //
122275793eaSopenharmony_ci       [^\n]*      ## followed by 0-or-more non end of line characters
123275793eaSopenharmony_ci
124275793eaSopenharmony_ci     |         ##     OR  various things which aren't comments:
125275793eaSopenharmony_ci
126275793eaSopenharmony_ci       (
127275793eaSopenharmony_ci         "           ##  Start of " ... " string
128275793eaSopenharmony_ci         (
129275793eaSopenharmony_ci           \\.           ##  Escaped char
130275793eaSopenharmony_ci         |               ##    OR
131275793eaSopenharmony_ci           [^"\\]        ##  Non "\
132275793eaSopenharmony_ci         )*
133275793eaSopenharmony_ci         "           ##  End of " ... " string
134275793eaSopenharmony_ci
135275793eaSopenharmony_ci       |         ##     OR
136275793eaSopenharmony_ci
137275793eaSopenharmony_ci         '           ##  Start of ' ... ' string
138275793eaSopenharmony_ci         (
139275793eaSopenharmony_ci           \\.           ##  Escaped char
140275793eaSopenharmony_ci         |               ##    OR
141275793eaSopenharmony_ci           [^'\\]        ##  Non '\
142275793eaSopenharmony_ci         )*
143275793eaSopenharmony_ci         '           ##  End of ' ... ' string
144275793eaSopenharmony_ci
145275793eaSopenharmony_ci       |         ##     OR
146275793eaSopenharmony_ci
147275793eaSopenharmony_ci         .           ##  Anything other char
148275793eaSopenharmony_ci         [^/"'\\]*   ##  Chars which doesn't start a comment, string or escape
149275793eaSopenharmony_ci       )
150275793eaSopenharmony_ci     }{$2}gxs;
151275793eaSopenharmony_ci
152275793eaSopenharmony_ci}
153