su-filter.pl revision 296465
1#!/usr/bin/env perl
2#
3# su-filter.pl
4#
5use strict;
6
7my $in_su = 0;
8my $indent = 0;
9my $out;
10my $braces = 0;
11my $arrcnt;
12my $data;
13my $tststr;
14my $incomm = 0;
15
16while(<>) {
17    $tststr = $_;
18    $incomm++ while $tststr =~ /\/\*/g;
19    $incomm-- while $tststr =~ /\*\//g;
20
21    if($in_su == 1) {
22        if(/}(.*);/) {
23            $out .= $_;
24            do_output($out);
25            $in_su = 0;
26        } elsif(/^ *\} [^\s]+(\[\d*\])* = \{/) {
27           $tststr = $1;
28           $arrcnt = 0;
29           $arrcnt++ while $tststr =~ /\[/g;
30           $in_su++;
31           $braces = 1;
32           /^(.* = \{)(.*)$/;
33           $data = $2;
34           $out .= $1."\n";
35        } else {
36            $out .= $_;
37        }
38    } elsif($in_su == 2) {
39        $data .= $_;
40        if(/};$/) {
41            #$data = "\n$data";
42            $data =~ s/\n */\n/g;
43            $data =~ s/};\n?//s;
44            my @strucdata = structureData($data);
45            $out .= displayData($indent, 0, \@strucdata);
46            $out .= "\n$indent};\n";
47            do_output($out);
48            $in_su = 0;
49        }
50    } elsif($incomm <= 0 && /( *)(static )?(const )?(union|struct) ([^\s]+ )?\{/) {
51        $in_su = 1;
52        $indent = $1;
53        $out = $_;
54        next;
55    } else {
56        do_output($_);
57    }
58}
59
60
61sub structureData {
62    my $data = $_[0];
63    my @datalist = split(/(\{|\}|,|"|#|\n|\/\*|\*\/|\(|\))/, $data);
64    my $item;
65    my $dataitem = "";
66    my @struclist = ();
67    my $substruc;
68    my $inquote = 0;
69    my $inbrace = 0;
70    my $preproc = 0;
71    my $comment = 0;
72    my $inparen = 0;
73
74
75    foreach $item (@datalist) {
76        if($comment) {
77            if($item eq "*/") {
78                $comment = 0;
79                $dataitem .= "*/";
80                push @struclist, $dataitem;
81                $dataitem = "";
82                next;
83            }
84            $dataitem .= $item;
85            next;
86        }
87        if($inquote) {
88            $dataitem .= $item;
89            if($item eq "\"") {
90                $inquote--;
91            }
92            next;
93        }
94        if($preproc) {
95            if($item eq "\n") {
96                $preproc = 0;
97                push @struclist, $dataitem;
98                $dataitem = "";
99                next;
100            }
101            $dataitem .= $item;
102            next;
103        }
104        if($inbrace) {
105            if($item eq "}") {
106                $inbrace --;
107
108                if(!$inbrace) {
109                    $substruc = structureData($dataitem);
110                    $dataitem = $substruc;
111                    next;
112                }
113            } elsif($item eq "{") {
114                $inbrace++;
115            } elsif ($item eq "\"") {
116                $inquote++;
117            }
118            $dataitem .= $item;
119            next;
120        }
121        if($inparen) {
122            if($item eq ")") {
123                $inparen--;
124            }
125            $dataitem .= $item;
126            next;
127        }
128        if($item eq "\n") {
129            next;
130        }
131        if($item eq "#") {
132            $preproc = 1;
133            push @struclist, $dataitem;
134            $dataitem = "#";
135            next;
136        }
137        if($item eq "/*") {
138            $comment = 1;
139            push @struclist, $dataitem;
140            $dataitem= "/*";
141            next;
142        }
143        if($item eq "\"") {
144            $dataitem .= $item;
145            $inquote++;
146            next;
147        }
148        if($item eq "{") {
149            $inbrace++;
150            next;
151        }
152        if($item eq ",") {
153            push @struclist, $dataitem;
154            $dataitem = "";
155            next;
156        }
157        if($item eq "(") {
158            $dataitem .= $item;
159            $inparen++;
160            next;
161        }
162        if($item =~ /^\s*$/) {
163            next;
164        }
165        if(ref $dataitem eq 'ARRAY') {
166            push @struclist, $dataitem;
167            $dataitem = "";
168        }
169        $dataitem .= $item;
170    }
171    push @struclist, $dataitem;
172    return \@struclist;
173}
174
175sub displayData {
176    my $indent = shift;
177    my $depth = shift;
178    my $data = shift;
179    my $item;
180    my $out = "";
181    my $currline = "";
182    my $first = 1;
183    my $prevpreproc = 0;
184    my $prevcomment = 0;
185
186    foreach $item (@{$data}) {
187        if($item =~ /^\/\*/) {
188            #Comment
189            $item =~ s/\n/\n$indent/g;
190            if($out =~ /\n\s*$/s) {
191                $out .= $item."\n".$indent;
192            } else {
193                $out .= "\n".$indent.$item."\n".$indent;
194            }
195            $currline = $indent;
196            $prevcomment = 1;
197            next;
198        }
199        $item =~ s/^\s+//;
200        if($item =~ /^#/) {
201            #Pre-processor directive
202            if($out =~ /\n\s*$/s) {
203                $out =~ s/\n\s*$/\n/;
204                $out .= $item."\n".$indent;
205            } else {
206                $out .= "\n".$item."\n".$indent;
207            }
208            $currline = $indent;
209            $prevpreproc = 1;
210            next;
211        }
212        if($first) {
213            $first = 0;
214            if($depth != 0) {
215                $out .= $indent;
216                $currline = $indent;
217            }
218        } else {
219            if(!$prevpreproc && !$prevcomment) {
220                $out .= ", ";
221                $currline .= ", ";
222                if($depth == 1) {
223                    $out .= "\n";
224                    $currline = "";
225                }
226                if($depth == 1) {
227                    $out .= $indent;
228                    $currline .= $indent;
229                }
230            }
231
232        }
233        $prevpreproc = 0;
234        $prevcomment = 0;
235
236        if (ref $item eq 'ARRAY') {
237            if($depth == 0) {
238                $out .= displayData("$indent    ", $depth+1, $item);
239            } else {
240                $out .= "{\n".displayData("$indent    ", $depth+1, $item)."\n".$indent."}";
241                $currline = $indent."}";
242            }
243        } else {
244            if(length $currline.$item > 79) {
245                $currline = $indent;
246                $out .= "\n$indent";
247            }
248            $out .= $item;
249            $currline .= $item;
250        }
251    }
252    return $out;
253}
254
255sub do_output {
256    my $out = shift;
257    # Strip any trailing whitespace
258    $out =~ s/\s+\n/\n/g;
259    print $out;
260}
261