-
Notifications
You must be signed in to change notification settings - Fork 0
/
uninclude
executable file
·271 lines (208 loc) · 7.62 KB
/
uninclude
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
#!/usr/bin/perl
# uninclude generated from pcpp-0.9/uninclude.pl 2024-07-06
# included ".version.pl"
our $PACKAGE = "pcpp";
our $VERSION = "0.9";
our $AUTHOR = "R.Jaksa 2008,2024 GPLv3";
our $SUBVERSION = "";
# end ".version.pl"
# included ".uninclude.built.pl"
our $BUILT = "2024-07-06";
# end ".uninclude.built.pl"
$HELP=<<EOF;
NAME
uninclude - remove included parts from pcpp generated files
USAGE
uninclude [OPTIONS] file
DESCRIPTION
Removes all included parts from a pcpp generated file. Depends
on pcpp watermarking. Can return back the #include statements,
but they are flattened to a single level direct includes.
OPTIONS
-h This help.
-v Verbose.
-l Just list all includes, indentation by the include level.
-ni Don't return back #include statements.
VERSION
$PACKAGE-$VERSION$SUBVERSION CK($AUTHOR) CK(built $BUILT)
EOF
# ------------------------------------------------------------------------------------- ARGV
# included "colors.pl"
# colors-0.1c (c) R.Jaksa 2008,2019, GPLv3
# built: ~/prj/libraries/colors/colors.pl
# installed: /map/colors/pl/colors.pl
our $CR_="\033[31m"; # color red
our $CG_="\033[32m"; # color green
our $CY_="\033[33m"; # color yellow
our $CB_="\033[34m"; # color blue
our $CM_="\033[35m"; # color magenta
our $CC_="\033[36m"; # color cyan
our $CW_="\033[37m"; # color white
our $CK_="\033[90m"; # color black
our $CP_="\033[91m"; # color pink
our $CL_="\033[92m"; # color lime
our $CS_="\033[93m"; # color sulphur yellow
our $CZ_="\033[94m"; # color azure
our $CO_="\033[95m"; # color orchid
our $CA_="\033[96m"; # color aqua cyan
our $CF_="\033[97m"; # color fluorescent white
our $CD_="\033[0m"; # color default
# return length of string without escape sequences
our sub esclen {
my $s = shift;
$s =~ s/\033\[[0-9]+m//g;
return length $s; }
# end "colors.pl"
# included "inar.pl"
# inar \@a,$s; checks whether the string $s is in an array @a
sub inar { for(@{$_[0]}) { return 1 if $_ eq $_[1] } return 0 }
# delar \@a,$s; removes 1st instance of the string $s from an array @a, i.e. set it to empty ""
sub delar { for(@{$_[0]}) { $_="" if $_ eq $_[1] }}
# return the length of array without empty "" elements
sub lenar { my $i=0; for(@{$_[0]}) { $i++ if $_ ne "" } return $i }
# end "inar.pl"
# included "print.pl"
sub pr { print STDERR @_ }
sub pf { printf STDERR @_ }
# end "print.pl"
# included "helpman.pl"
# helpman-0.2 (c) R.Jaksa 2015,2019, GPLv3
# built: ~/prj/libraries/helpman/helpman.pl
# installed: /map/helpman/pl/helpman.pl
# require "colors.pl"
{
our ($PKGBUILT,$PKGMSG,$SUBVERSION);
our sub printhelp {
my $help = shift;
my $colors = "CWRDKGM";
my $L = "\#\#\>"; # private left brace
my $R = "\<\#\#"; # private right brace
my %STR; # private substitutions content strings
my $id = 0; # last ID
sub SBS { return "$L$_[0]$R"; } # return complete private substitution identifier
# skip commented-out lines
$help =~ s/(\n\#.*)*\n/\n/g;
# add version/copyright section
# my $built = " $CK_($PKGBUILT)$CD_" if $SUBVERSION ne "none";
# $help .= "VERSION\n";
# $help .= " $PKGMSG$built\n\n";
# escapes
$help =~ s/\\\)/SBS "brc2"/eg; # escaped bracket
# CC(text)
my $RE1 = qr/(\((([^()]|(?-3))*)\))/x; # () group, $1=withparens, $2=without
$STR{$id++}=$4 while $help =~ s/([^A-Z0-9])(C[$colors])$RE1/$1.SBS("c$2$id")/e;
# options lists
$STR{$id++}=$2 while $help =~ s/(\n[ ]*)(-[a-zA-Z0-9]+(\[?[ =][A-Z]{2,}(x[A-Z]{2,})?\]?)?)([ \t])/$1.SBS("op$id").$5/e;
# bracketed uppercase words
$STR{$id++}="$1$2" while $help =~ s/\[([+-])?([A-Z]+)\]/SBS "br$id"/e;
# plain uppercase words, like sections headers
$STR{$id++}=$2 while $help =~ s/(\n|[ \t])(([A-Z_\/-]+[ ]?){4,})/$1.SBS("pl$id")/e;
# re-substitute
$help =~ s/${L}pl([0-9]+)$R/$CC_$STR{$1}$CD_/g;
$help =~ s/${L}op([0-9]+)$R/$CC_$STR{$1}$CD_/g;
$help =~ s/${L}br([0-9]+)$R/\[$CC_$STR{$1}$CD_\]/g;
# CC(text)
my %cc; $cc{$_} = ${"C".$_."_"} for split //,$colors;
$help =~ s/${L}cC([$colors])([0-9]+)$R/$cc{$1}$STR{$2}$CD_/g;
# escapes
$help =~ s/${L}brc2$R/)/g;
# star bullets
$help =~ s/\n \* /\n $CC_\*$CD_ /g;
print $help; }
}
# end "helpman.pl"
# included "mode.pl"
# included "sx.pl"
# return file suffix
sub sx { my $s=$_[0]; $s=~s/^.*\.//; return $s }
# end "sx.pl"
{
# return the file mode by the suffix of filename: pl, py or c
my sub getbysx {
return "pl" if $_[0] eq "pl";
return "py" if $_[0] eq "py";
return "c" if $_[0] eq "c++";
return "c" if $_[0] eq "c"; }
# return the mode by the filename, or return the default perl mode
our sub getmode {
my $sx = sx $_[0];
my $mode = getbysx $sx;
$mode = "pl" if not $mode;
return $mode }
# auto-identify the mode of a list of files by the first identifiable
# file suffix, or return the default perl mode
our sub firstmode {
my $mode;
for(@{$_[0]}) {
$mode = getbysx sx $_;
last if $mode }
$mode = "pl" if not $mode;
return $mode }
# return the comment identifier string by the mode: # or //
our sub getsy {
return "//" if $_[0] eq "c";
return "#" }
} # R.Jaksa 2024 GPLv3
# end "mode.pl"
# TODO: uninclude only specified file
for(@ARGV) { if($_ eq "-h") { printhelp $HELP; exit 0 }}
for(@ARGV) { if($_ eq "-v") { $VERBOSE=1; $_=""; last }}
for(@ARGV) { if($_ eq "-l") { $LIST=1; $_=""; last }}
for(@ARGV) { if($_ eq "-ni") { $NOINC=1; $_=""; last }}
# input file
for(@ARGV) { $FILE=$_ and last if $_ ne "" and -f $_ }
# no input file
if(not $FILE) { pr "No input file specified.\n"; exit(1) }
# ------------------------------------------------------------------------------------- MAIN
our $MODE = getmode $FILE; # input file mode: pl, py or c
our $SY = getsy $MODE; # comment identifier
our $SYQ = quotemeta $SY;
# read the file
my @included; # at-current-line list of original files we are inc.
my @body = split /\n/,`cat $FILE`; # full text
# remove includes - replace included content with :DEL tags
for my $i (0..$#body) {
my $file=""; # active for include directive line only, included filename
my $end=0; # whether we are on the end directive
# start of included section
if($body[$i] =~ /^\h*$SYQ\h*included\h+\"([^\"]+)\"/) {
push @included,$1; $file=$1;
my $n = lenar \@included,$1;
my $sp = " " x (lenar(\@included,$1)-1);
if($VERBOSE) { pr "${CK_}# uninclude$CD_ $sp$CC_$file$CD_\n" }
if($LIST) { print "$sp$file\n" }}
# end of section
if($body[$i] =~ /^\h*$SYQ\h*end\h+\"([^\"]+)\"/) {
delar \@included,$1; $end=1; }
# return the #include directive
my $n = lenar \@included,$1;
if($file ne "") {
if($NOINC) { $body[$i] = "$SY:DEL" }
else { $body[$i] = "$SY include \"$file\"" }}
# remove the line, or not
elsif($n>0 or $end) {
$body[$i] = "$SY:DEL" }}
# skip the rest in the list mode
exit if $LIST;
# remove :DEL lines and accompanying empty lines
my @output; my $i=0;
while($i<=$#body) {
if($body[$i]=~/^$SYQ:DEL/) {
push @output,"" if $body[$i-1]!~/^\h*$/; # add empty line if not already there
$i++ while $body[$i]=~/^$SYQ:DEL/ or $body[$i]=~/^\h*$/ } # skip DELs
push @output,$body[$i++] }
# put together multiple #include
for my $i (0..$#output) {
$output[$i+1]="$SY:DEL" if $output[$i] =~ /^$SYQ include \"/ and
$output[$i+1] =~ /^\h*$/ and
$output[$i+2] =~ /^$SYQ include \"/ }
# TODO: group consecutive includes
# TODO: do quoting according to original (needs pcpp update)
# assembly of the final body string
my $out;
for my $i (0..$#output) {
if($output[$i] =~ /^$SYQ:DEL/) { next }
$out .= "$output[$i]\n" }
# emit the output
print $out;
# ----------------------------------------------------------------------- R.Jaksa 2024 GPLv3