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