Fix SOURCE_DATE_EPOCH bug; use UTC
[openssl.git] / util / su-filter.pl
1 #! /usr/bin/env perl
2 # Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
3 #
4 # Licensed under the OpenSSL license (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
9 use strict;
10
11 my $in_su = 0;
12 my $indent = 0;
13 my $out;
14 my $braces = 0;
15 my $arrcnt;
16 my $data;
17 my $tststr;
18 my $incomm = 0;
19
20 while(<>) {
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
65 sub 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
179 sub 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
259 sub do_output {
260     my $out = shift;
261     # Strip any trailing whitespace
262     $out =~ s/\s+\n/\n/g;
263     print $out;
264 }