xref: /freebsd/crypto/openssl/util/lang-compress.pl (revision e0c4386e7e71d93b0edc0c8fa156263fc4a8b0b6)
1*e0c4386eSCy Schubert#! /usr/bin/env perl
2*e0c4386eSCy Schubert#
3*e0c4386eSCy Schubert# C source compressor.  This:
4*e0c4386eSCy Schubert#
5*e0c4386eSCy Schubert# - merges continuation lines
6*e0c4386eSCy Schubert# - removes comments (not in strings)
7*e0c4386eSCy Schubert# - removes empty lines (not in strings)
8*e0c4386eSCy Schubert
9*e0c4386eSCy Schubertuse strict;
10*e0c4386eSCy Schubertuse warnings;
11*e0c4386eSCy Schubert
12*e0c4386eSCy Schubertmy $debug = defined $ENV{DEBUG};
13*e0c4386eSCy Schubertmy $lang = shift @ARGV;
14*e0c4386eSCy Schubert
15*e0c4386eSCy Schubert# Slurp the file
16*e0c4386eSCy Schubert$/ = undef;
17*e0c4386eSCy Schubert$_ = <>;
18*e0c4386eSCy Schubert
19*e0c4386eSCy Schubertif ($lang eq 'C') {
20*e0c4386eSCy Schubert    # Merge continuation lines
21*e0c4386eSCy Schubert    s{\\\n}{}g;
22*e0c4386eSCy Schubert
23*e0c4386eSCy Schubert    # Regexp for things that should be preserved
24*e0c4386eSCy Schubert    my $preserved =
25*e0c4386eSCy Schubert        qr{
26*e0c4386eSCy Schubert              (?:
27*e0c4386eSCy Schubert                  "                 # String start
28*e0c4386eSCy Schubert                  (?: \\. | [^\"])* # Any character, including escaped ones
29*e0c4386eSCy Schubert                  "                 # String end
30*e0c4386eSCy Schubert              )
31*e0c4386eSCy Schubert
32*e0c4386eSCy Schubert          |                         # OR
33*e0c4386eSCy Schubert
34*e0c4386eSCy Schubert              (?:
35*e0c4386eSCy Schubert                  '                 # Character start (multi-chars supported)
36*e0c4386eSCy Schubert                  (?: \\. | [^\'])+ # Any character, including escaped ones
37*e0c4386eSCy Schubert                  '                 # String end
38*e0c4386eSCy Schubert              )
39*e0c4386eSCy Schubert        }x;
40*e0c4386eSCy Schubert
41*e0c4386eSCy Schubert    # Remove comments while preserving strings
42*e0c4386eSCy Schubert    s{
43*e0c4386eSCy Schubert         (?|                        # All things preserved end up in $1
44*e0c4386eSCy Schubert
45*e0c4386eSCy Schubert             /\*                    # C comment start
46*e0c4386eSCy Schubert             .*?                    # Contents up until
47*e0c4386eSCy Schubert             \*/                    # C comment end
48*e0c4386eSCy Schubert
49*e0c4386eSCy Schubert         |                          # OR
50*e0c4386eSCy Schubert
51*e0c4386eSCy Schubert             (                      # Grouping for the replacement
52*e0c4386eSCy Schubert                 $preserved
53*e0c4386eSCy Schubert             )
54*e0c4386eSCy Schubert
55*e0c4386eSCy Schubert         )
56*e0c4386eSCy Schubert    }{
57*e0c4386eSCy Schubert        if ($debug) {
58*e0c4386eSCy Schubert            print STDERR "DEBUG: '$&' => '$1'\n" if defined $1;
59*e0c4386eSCy Schubert            print STDERR "DEBUG: '$&' removed\n" unless defined $1;
60*e0c4386eSCy Schubert        }
61*e0c4386eSCy Schubert        defined $1 ? $1 : ""
62*e0c4386eSCy Schubert    }gsxe;
63*e0c4386eSCy Schubert
64*e0c4386eSCy Schubert    # Remove empty lines
65*e0c4386eSCy Schubert    s{
66*e0c4386eSCy Schubert         (?|                        # All things preserved end up in $1
67*e0c4386eSCy Schubert
68*e0c4386eSCy Schubert             (^|\n)(?:\s*(?:\n|$))+ # Empty lines, preserve one newline
69*e0c4386eSCy Schubert
70*e0c4386eSCy Schubert         |                          # OR
71*e0c4386eSCy Schubert
72*e0c4386eSCy Schubert             (                      # Grouping for the replacement
73*e0c4386eSCy Schubert                 $preserved
74*e0c4386eSCy Schubert             )
75*e0c4386eSCy Schubert
76*e0c4386eSCy Schubert         )
77*e0c4386eSCy Schubert    }{$1}gsx;
78*e0c4386eSCy Schubert
79*e0c4386eSCy Schubert    # Remove extra spaces
80*e0c4386eSCy Schubert    s{
81*e0c4386eSCy Schubert         (?|                        # All things preserved end up in $1
82*e0c4386eSCy Schubert
83*e0c4386eSCy Schubert             \h+                    # Horizontal spaces replaced with one
84*e0c4386eSCy Schubert
85*e0c4386eSCy Schubert         |                          # OR
86*e0c4386eSCy Schubert
87*e0c4386eSCy Schubert             (                      # Grouping for the replacement
88*e0c4386eSCy Schubert                 $preserved
89*e0c4386eSCy Schubert             )
90*e0c4386eSCy Schubert
91*e0c4386eSCy Schubert         )
92*e0c4386eSCy Schubert    }{
93*e0c4386eSCy Schubert        if ($debug) {
94*e0c4386eSCy Schubert            print STDERR "DEBUG: '$&' => '$1'\n" if defined $1;
95*e0c4386eSCy Schubert            print STDERR "DEBUG: '$&' => ' '\n" unless defined $1;
96*e0c4386eSCy Schubert        }
97*e0c4386eSCy Schubert        defined $1 ? $1 : " "
98*e0c4386eSCy Schubert    }gsxe;
99*e0c4386eSCy Schubert
100*e0c4386eSCy Schubert    # Clean up spaces at start and end of lines
101*e0c4386eSCy Schubert    s/^ //mg;
102*e0c4386eSCy Schubert    s/ $//mg;
103*e0c4386eSCy Schubert} elsif ($lang eq 'S') {
104*e0c4386eSCy Schubert    # Because we use C++ style comments in our .S files, all we can do
105*e0c4386eSCy Schubert    # is to drop them
106*e0c4386eSCy Schubert    s{
107*e0c4386eSCy Schubert         ^([^\n]*?)//[^\n]*?$   # Any line with a // comment
108*e0c4386eSCy Schubert    }{
109*e0c4386eSCy Schubert        if ($debug) {
110*e0c4386eSCy Schubert            print STDERR "DEBUG: '$&' => '$1'\n" if defined $1;
111*e0c4386eSCy Schubert            print STDERR "DEBUG: '$&' removed\n" unless defined $1;
112*e0c4386eSCy Schubert        }
113*e0c4386eSCy Schubert        defined $1 ? $1 : ""
114*e0c4386eSCy Schubert    }mgsxe;
115*e0c4386eSCy Schubert
116*e0c4386eSCy Schubert    # Drop all empty lines
117*e0c4386eSCy Schubert    s{
118*e0c4386eSCy Schubert         (^|\n)(?:\s*(?:\n|$))+ # Empty lines, preserve one newline
119*e0c4386eSCy Schubert    }{$1}gsx;
120*e0c4386eSCy Schubert} elsif ($lang eq 'perl') {
121*e0c4386eSCy Schubert    # Merge continuation lines
122*e0c4386eSCy Schubert    s{\\\n}{}g;
123*e0c4386eSCy Schubert
124*e0c4386eSCy Schubert    # Regexp for things that should be preserved
125*e0c4386eSCy Schubert    my $preserved =
126*e0c4386eSCy Schubert        qr{
127*e0c4386eSCy Schubert              (?:
128*e0c4386eSCy Schubert                  <<["']?(\w+)["']? # HERE document start
129*e0c4386eSCy Schubert                  .*?               # Its contents
130*e0c4386eSCy Schubert                  ^\g{-1}$
131*e0c4386eSCy Schubert              )
132*e0c4386eSCy Schubert          |
133*e0c4386eSCy Schubert              (?:
134*e0c4386eSCy Schubert                  "                 # Double quoted string start
135*e0c4386eSCy Schubert                  (?: \\. | [^\"])* # Any character, including escaped ones
136*e0c4386eSCy Schubert                  "                 # Double quoted string end
137*e0c4386eSCy Schubert              )
138*e0c4386eSCy Schubert
139*e0c4386eSCy Schubert          |                         # OR
140*e0c4386eSCy Schubert
141*e0c4386eSCy Schubert              (?:
142*e0c4386eSCy Schubert                  '                 # Single quoted string start
143*e0c4386eSCy Schubert                  [^\']*            # Any character
144*e0c4386eSCy Schubert                  '                 # Single quoted string end
145*e0c4386eSCy Schubert              )
146*e0c4386eSCy Schubert        }msx;
147*e0c4386eSCy Schubert
148*e0c4386eSCy Schubert    # Remove comments while preserving strings
149*e0c4386eSCy Schubert    s{
150*e0c4386eSCy Schubert         (?|                        # All things preserved end up in $1
151*e0c4386eSCy Schubert
152*e0c4386eSCy Schubert             \#.*?(\n|$)            # Perl comments
153*e0c4386eSCy Schubert
154*e0c4386eSCy Schubert         |                          # OR
155*e0c4386eSCy Schubert
156*e0c4386eSCy Schubert             (                      # Grouping for the replacement
157*e0c4386eSCy Schubert                 $preserved
158*e0c4386eSCy Schubert             )
159*e0c4386eSCy Schubert
160*e0c4386eSCy Schubert         )
161*e0c4386eSCy Schubert    }{
162*e0c4386eSCy Schubert        if ($debug) {
163*e0c4386eSCy Schubert            print STDERR "DEBUG: '$&' => '$1'\n" if defined $1;
164*e0c4386eSCy Schubert            print STDERR "DEBUG: '$&' removed\n" unless defined $1;
165*e0c4386eSCy Schubert        }
166*e0c4386eSCy Schubert        defined $1 ? $1 : ""
167*e0c4386eSCy Schubert    }gsxe;
168*e0c4386eSCy Schubert
169*e0c4386eSCy Schubert    # Remove empty lines
170*e0c4386eSCy Schubert    s{
171*e0c4386eSCy Schubert         (?|                        # All things preserved end up in $1
172*e0c4386eSCy Schubert
173*e0c4386eSCy Schubert             (^|\n)(?:\s*(?:\n|$))+ # Empty lines, preserve one newline
174*e0c4386eSCy Schubert
175*e0c4386eSCy Schubert         |                          # OR
176*e0c4386eSCy Schubert
177*e0c4386eSCy Schubert             (                      # Grouping for the replacement
178*e0c4386eSCy Schubert                 $preserved
179*e0c4386eSCy Schubert             )
180*e0c4386eSCy Schubert
181*e0c4386eSCy Schubert         )
182*e0c4386eSCy Schubert    }{$1}gsx;
183*e0c4386eSCy Schubert}
184*e0c4386eSCy Schubert
185*e0c4386eSCy Schubertprint;
186