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