line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package C::Utility; |
2
|
2
|
|
|
2
|
|
137525
|
use warnings; |
|
2
|
|
|
|
|
13
|
|
|
2
|
|
|
|
|
67
|
|
3
|
2
|
|
|
2
|
|
10
|
use strict; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
38
|
|
4
|
2
|
|
|
2
|
|
13
|
use File::Spec; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
47
|
|
5
|
2
|
|
|
2
|
|
11
|
use Carp; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
137
|
|
6
|
2
|
|
|
2
|
|
1029
|
use File::Versions 'make_backup'; |
|
2
|
|
|
|
|
2213
|
|
|
2
|
|
|
|
|
125
|
|
7
|
2
|
|
|
2
|
|
957
|
use File::Slurper qw/read_text write_text/; |
|
2
|
|
|
|
|
27950
|
|
|
2
|
|
|
|
|
162
|
|
8
|
2
|
|
|
2
|
|
986
|
use C::Tokenize '$comment_re'; |
|
2
|
|
|
|
|
9064
|
|
|
2
|
|
|
|
|
329
|
|
9
|
2
|
|
|
2
|
|
1007
|
use Text::LineNumber; |
|
2
|
|
|
|
|
692
|
|
|
2
|
|
|
|
|
4571
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
require Exporter; |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
our @EXPORT_OK = qw/ |
16
|
|
|
|
|
|
|
add_lines |
17
|
|
|
|
|
|
|
brute_force_line |
18
|
|
|
|
|
|
|
c_string |
19
|
|
|
|
|
|
|
c_to_h_name |
20
|
|
|
|
|
|
|
ch_files |
21
|
|
|
|
|
|
|
convert_to_c_string |
22
|
|
|
|
|
|
|
convert_to_c_string_pc |
23
|
|
|
|
|
|
|
escape_string |
24
|
|
|
|
|
|
|
hash_to_c_file |
25
|
|
|
|
|
|
|
line_directive |
26
|
|
|
|
|
|
|
linein |
27
|
|
|
|
|
|
|
lineout |
28
|
|
|
|
|
|
|
print_bottom_h_wrapper |
29
|
|
|
|
|
|
|
print_top_h_wrapper |
30
|
|
|
|
|
|
|
read_includes |
31
|
|
|
|
|
|
|
remove_quotes |
32
|
|
|
|
|
|
|
stamp_file |
33
|
|
|
|
|
|
|
valid_c_variable |
34
|
|
|
|
|
|
|
/; |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
our %EXPORT_TAGS = ( |
37
|
|
|
|
|
|
|
'all' => \@EXPORT_OK, |
38
|
|
|
|
|
|
|
); |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
our $VERSION = '0.010'; |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
sub convert_to_c_string |
43
|
|
|
|
|
|
|
{ |
44
|
2
|
|
|
2
|
1
|
87
|
my ($text) = @_; |
45
|
2
|
50
|
|
|
|
9
|
if (length ($text) == 0) { |
46
|
0
|
|
|
|
|
0
|
return "\"\""; |
47
|
|
|
|
|
|
|
} |
48
|
|
|
|
|
|
|
# Convert backslashes to double backslashes. |
49
|
2
|
|
|
|
|
6
|
$text =~ s/\\/\\\\/g; |
50
|
|
|
|
|
|
|
# Escape double quotes |
51
|
2
|
|
|
|
|
6
|
$text = escape_string ($text); |
52
|
|
|
|
|
|
|
# If there was a backslash before a quote, as in \", the first |
53
|
|
|
|
|
|
|
# regex above converted it to \\", and then escape_string |
54
|
|
|
|
|
|
|
# converted that to \\\". |
55
|
2
|
|
|
|
|
6
|
$text =~ s/\\\\"/\\"/g; |
56
|
|
|
|
|
|
|
# Remove backslashes from before the @ symbol. |
57
|
2
|
|
|
|
|
5
|
$text =~ s/\\\@/@/g; |
58
|
|
|
|
|
|
|
# Turn each line into a string |
59
|
2
|
|
|
|
|
10
|
$text =~ s/(.*)\n/"$1\\n"\n/gm; |
60
|
|
|
|
|
|
|
# Catch a final line without any \n at its end. |
61
|
2
|
100
|
|
|
|
10
|
if ($text !~ /\\n\"$/) { |
62
|
1
|
|
|
|
|
9
|
$text =~ s/(.+)$/"$1"/g; |
63
|
|
|
|
|
|
|
} |
64
|
2
|
|
|
|
|
8
|
return $text; |
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
sub c_string |
68
|
|
|
|
|
|
|
{ |
69
|
0
|
|
|
0
|
1
|
0
|
goto & convert_to_c_string; |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
sub ch_files |
73
|
|
|
|
|
|
|
{ |
74
|
0
|
|
|
0
|
1
|
0
|
my ($c_file_name) = @_; |
75
|
0
|
0
|
|
|
|
0
|
if ($c_file_name !~ /\.c/) { |
76
|
0
|
|
|
|
|
0
|
die "$c_file_name is not a C file name"; |
77
|
|
|
|
|
|
|
} |
78
|
0
|
|
|
|
|
0
|
my $h_file_name = $c_file_name; |
79
|
0
|
|
|
|
|
0
|
$h_file_name =~ s/\.c$/\.h/; |
80
|
0
|
0
|
|
|
|
0
|
if (-f $c_file_name) { |
81
|
0
|
|
|
|
|
0
|
make_backup ($c_file_name); |
82
|
|
|
|
|
|
|
} |
83
|
0
|
0
|
|
|
|
0
|
if (-f $h_file_name) { |
84
|
0
|
|
|
|
|
0
|
make_backup ($h_file_name); |
85
|
|
|
|
|
|
|
} |
86
|
0
|
|
|
|
|
0
|
return $h_file_name; |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
sub convert_to_c_string_pc |
90
|
|
|
|
|
|
|
{ |
91
|
1
|
|
|
1
|
1
|
474
|
my ($text) = @_; |
92
|
1
|
|
|
|
|
20
|
$text =~ s/%/%%/g; |
93
|
1
|
|
|
|
|
3
|
return convert_to_c_string ($text); |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
sub escape_string |
97
|
|
|
|
|
|
|
{ |
98
|
2
|
|
|
2
|
1
|
4
|
my ($text) = @_; |
99
|
2
|
|
|
|
|
7
|
$text =~ s/\"/\\\"/g; |
100
|
2
|
|
|
|
|
5
|
return $text; |
101
|
|
|
|
|
|
|
} |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
sub c_to_h_name |
104
|
|
|
|
|
|
|
{ |
105
|
0
|
|
|
0
|
1
|
0
|
my ($c_file_name) = @_; |
106
|
0
|
0
|
|
|
|
0
|
if ($c_file_name !~ /\.c/) { |
107
|
0
|
|
|
|
|
0
|
die "$c_file_name is not a C file name"; |
108
|
|
|
|
|
|
|
} |
109
|
0
|
|
|
|
|
0
|
my $h_file_name = $c_file_name; |
110
|
0
|
|
|
|
|
0
|
$h_file_name =~ s/\.c$/\.h/; |
111
|
0
|
|
|
|
|
0
|
return $h_file_name; |
112
|
|
|
|
|
|
|
} |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
# This list of reserved words in C is from |
115
|
|
|
|
|
|
|
# http://crasseux.com/books/ctutorial/Reserved-words-in-C.html |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
my @reserved_words = sort {length $b <=> length $a} qw/auto if break |
118
|
|
|
|
|
|
|
int case long char register continue return default short do sizeof |
119
|
|
|
|
|
|
|
double static else struct entry switch extern typedef float union for |
120
|
|
|
|
|
|
|
unsigned goto while enum void const signed volatile/; |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
# A regular expression to match reserved words in C. |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
my $reserved_words_re = join '|', @reserved_words; |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
sub valid_c_variable |
127
|
|
|
|
|
|
|
{ |
128
|
0
|
|
|
0
|
1
|
0
|
my ($variable_name) = @_; |
129
|
0
|
0
|
0
|
|
|
0
|
if ($variable_name !~ /^[A-Za-z_][A-Za-z_0-9]+$/ || |
130
|
|
|
|
|
|
|
$variable_name =~ /^(?:$reserved_words_re)$/) { |
131
|
0
|
|
|
|
|
0
|
return; |
132
|
|
|
|
|
|
|
} |
133
|
0
|
|
|
|
|
0
|
return 1; |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
# Wrapper name |
137
|
|
|
|
|
|
|
# BKB 2009-10-05 14:09:41 |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
sub wrapper_name |
140
|
|
|
|
|
|
|
{ |
141
|
0
|
|
|
0
|
1
|
0
|
my ($string) = @_; |
142
|
0
|
|
|
|
|
0
|
$string =~ s/[.-]/_/g; |
143
|
0
|
0
|
|
|
|
0
|
if (! valid_c_variable ($string)) { |
144
|
0
|
|
|
|
|
0
|
croak "Bad string for wrapper '$string'"; |
145
|
|
|
|
|
|
|
} |
146
|
0
|
|
|
|
|
0
|
my $wrapper_name = uc $string; |
147
|
0
|
|
|
|
|
0
|
return $wrapper_name; |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
sub print_top_h_wrapper |
151
|
|
|
|
|
|
|
{ |
152
|
0
|
|
|
0
|
1
|
0
|
my ($fh, $file_name) = @_; |
153
|
|
|
|
|
|
|
|
154
|
0
|
|
|
|
|
0
|
my $wrapper_name = wrapper_name ($file_name); |
155
|
0
|
|
|
|
|
0
|
my $wrapper = <
|
156
|
|
|
|
|
|
|
#ifndef $wrapper_name |
157
|
|
|
|
|
|
|
#define $wrapper_name |
158
|
|
|
|
|
|
|
EOF |
159
|
0
|
|
|
|
|
0
|
print_out ($fh, $wrapper); |
160
|
|
|
|
|
|
|
} |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
sub print_out |
163
|
|
|
|
|
|
|
{ |
164
|
0
|
|
|
0
|
0
|
0
|
my ($fh, $wrapper) = @_; |
165
|
0
|
0
|
0
|
|
|
0
|
if (ref $fh && ref $fh eq 'SCALAR') { |
166
|
0
|
|
|
|
|
0
|
${$fh} .= $wrapper; |
|
0
|
|
|
|
|
0
|
|
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
else { |
169
|
0
|
|
|
|
|
0
|
print $fh $wrapper; |
170
|
|
|
|
|
|
|
} |
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
sub print_bottom_h_wrapper |
174
|
|
|
|
|
|
|
{ |
175
|
0
|
|
|
0
|
1
|
0
|
my ($fh, $file_name) = @_; |
176
|
0
|
|
|
|
|
0
|
my $wrapper_name = wrapper_name ($file_name); |
177
|
0
|
|
|
|
|
0
|
my $wrapper = <
|
178
|
|
|
|
|
|
|
#endif /* $wrapper_name */ |
179
|
|
|
|
|
|
|
EOF |
180
|
0
|
|
|
|
|
0
|
print_out ($fh, $wrapper); |
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
sub print_include |
184
|
|
|
|
|
|
|
{ |
185
|
0
|
|
|
0
|
1
|
0
|
my ($fh, $h_file_name) = @_; |
186
|
0
|
|
|
|
|
0
|
print $fh <
|
187
|
|
|
|
|
|
|
#include "$h_file_name" |
188
|
|
|
|
|
|
|
EOF |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
sub hash_to_c_file |
192
|
|
|
|
|
|
|
{ |
193
|
|
|
|
|
|
|
# $prefix is an optional prefix applied to all variables. |
194
|
0
|
|
|
0
|
1
|
0
|
my ($c_file_name, $hash_ref, $prefix) = @_; |
195
|
0
|
|
|
|
|
0
|
my $h_file_name = ch_files ($c_file_name); |
196
|
0
|
0
|
|
|
|
0
|
die "Not a hash ref" unless ref $hash_ref eq "HASH"; |
197
|
0
|
0
|
|
|
|
0
|
$prefix = "" unless $prefix; |
198
|
0
|
0
|
|
|
|
0
|
open my $c_out, ">:utf8", $c_file_name or die $!; |
199
|
0
|
|
|
|
|
0
|
my (undef, undef, $h_file) = File::Spec->splitpath ($h_file_name); |
200
|
0
|
|
|
|
|
0
|
print_include ($c_out, $h_file); |
201
|
0
|
0
|
|
|
|
0
|
open my $h_out, ">:utf8", $h_file_name or die $!; |
202
|
0
|
|
|
|
|
0
|
print_top_h_wrapper ($h_out, $h_file); |
203
|
0
|
|
|
|
|
0
|
for my $variable (sort keys %$hash_ref) { |
204
|
0
|
0
|
|
|
|
0
|
if (! valid_c_variable ($variable)) { |
205
|
0
|
|
|
|
|
0
|
croak "key '$variable' is not a valid C variable"; |
206
|
|
|
|
|
|
|
} |
207
|
0
|
|
|
|
|
0
|
my $value = $hash_ref->{$variable}; |
208
|
0
|
|
|
|
|
0
|
$value = convert_to_c_string ($value); |
209
|
0
|
|
|
|
|
0
|
print $c_out "const char * $prefix$variable = $value;\n"; |
210
|
0
|
|
|
|
|
0
|
print $h_out "extern const char * $prefix$variable; /* $value */\n"; |
211
|
|
|
|
|
|
|
} |
212
|
0
|
0
|
|
|
|
0
|
close $c_out or die $!; |
213
|
0
|
|
|
|
|
0
|
print_bottom_h_wrapper ($h_out, $h_file); |
214
|
0
|
0
|
|
|
|
0
|
close $h_out or die $!; |
215
|
0
|
|
|
|
|
0
|
return $h_file_name; |
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
sub line_directive |
219
|
|
|
|
|
|
|
{ |
220
|
0
|
|
|
0
|
1
|
0
|
my ($output, $line_number, $file_name) = @_; |
221
|
0
|
0
|
0
|
|
|
0
|
die "$line_number is not a positive integer number" |
222
|
|
|
|
|
|
|
unless $line_number =~ /^[0-9]+$/ && $line_number > 0; |
223
|
0
|
|
|
|
|
0
|
print_out ($output, "#line $line_number \"$file_name\"\n"); |
224
|
|
|
|
|
|
|
} |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
sub brute_force_line |
227
|
|
|
|
|
|
|
{ |
228
|
0
|
|
|
0
|
1
|
0
|
my ($input_file, $output_file) = @_; |
229
|
0
|
0
|
|
|
|
0
|
open my $input, "<:encoding(utf8)", $input_file or die $!; |
230
|
0
|
0
|
|
|
|
0
|
open my $output, ">:encoding(utf8)", $output_file or die $!; |
231
|
0
|
|
|
|
|
0
|
while (<$input>) { |
232
|
0
|
|
|
|
|
0
|
print $output "#line $. \"$input_file\"\n"; |
233
|
0
|
|
|
|
|
0
|
print $output $_; |
234
|
|
|
|
|
|
|
} |
235
|
0
|
0
|
|
|
|
0
|
close $input or die $!; |
236
|
0
|
0
|
|
|
|
0
|
close $output or die $!; |
237
|
|
|
|
|
|
|
} |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
sub add_lines |
240
|
|
|
|
|
|
|
{ |
241
|
0
|
|
|
0
|
1
|
0
|
my ($input_file) = @_; |
242
|
0
|
|
|
|
|
0
|
my $full_name = File::Spec->rel2abs ($input_file); |
243
|
0
|
|
|
|
|
0
|
my $text = ''; |
244
|
0
|
0
|
|
|
|
0
|
open my $input, "<:encoding(utf8)", $input_file or die $!; |
245
|
0
|
|
|
|
|
0
|
while (<$input>) { |
246
|
0
|
0
|
|
|
|
0
|
if (/^#line/) { |
|
|
0
|
|
|
|
|
|
247
|
0
|
|
|
|
|
0
|
my $line_no = $. + 1; |
248
|
0
|
|
|
|
|
0
|
$text .= "#line $line_no \"$full_name\"\n"; |
249
|
|
|
|
|
|
|
} |
250
|
|
|
|
|
|
|
elsif ($. == 1) { |
251
|
0
|
|
|
|
|
0
|
$text .= "#line 1 \"$full_name\"\n"; |
252
|
0
|
|
|
|
|
0
|
$text .= $_; |
253
|
|
|
|
|
|
|
} |
254
|
|
|
|
|
|
|
else { |
255
|
0
|
|
|
|
|
0
|
$text .= $_; |
256
|
|
|
|
|
|
|
} |
257
|
|
|
|
|
|
|
} |
258
|
0
|
|
|
|
|
0
|
return $text; |
259
|
|
|
|
|
|
|
} |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
sub remove_quotes |
262
|
|
|
|
|
|
|
{ |
263
|
3
|
|
|
3
|
1
|
90
|
my ($string) = @_; |
264
|
3
|
|
|
|
|
27
|
$string =~ s/^"|"$|"\s*"//g; |
265
|
3
|
|
|
|
|
15
|
return $string; |
266
|
|
|
|
|
|
|
} |
267
|
|
|
|
|
|
|
#use Data::Dumper; |
268
|
|
|
|
|
|
|
sub linedirective |
269
|
|
|
|
|
|
|
{ |
270
|
0
|
|
|
0
|
0
|
|
my ($intext, $file, $directive) = @_; |
271
|
0
|
0
|
0
|
|
|
|
die unless $intext && $file && $directive; |
|
|
|
0
|
|
|
|
|
272
|
|
|
|
|
|
|
# This module is pretty reliable for line numbering. |
273
|
0
|
|
|
|
|
|
my $tln = Text::LineNumber->new ($intext); |
274
|
0
|
|
|
|
|
|
my %renumbered; |
275
|
|
|
|
|
|
|
# Uniquifier for the lines. |
276
|
0
|
|
|
|
|
|
my $count = 0; |
277
|
|
|
|
|
|
|
# This is unlikely to occur. |
278
|
0
|
|
|
|
|
|
my $tag = 'ABRACADABRA'; |
279
|
|
|
|
|
|
|
# Watch for blue-moon occurences |
280
|
0
|
0
|
|
|
|
|
die if $intext =~ /$tag\d+/; |
281
|
0
|
|
|
|
|
|
while ($intext =~ s/^\Q$directive/$tag$count$tag/sm) { |
282
|
0
|
|
|
|
|
|
$count++; |
283
|
|
|
|
|
|
|
} |
284
|
|
|
|
|
|
|
# "pos" doesn't work well with s///g, so now we need to match the tags |
285
|
|
|
|
|
|
|
# one by one. |
286
|
0
|
|
|
|
|
|
while ($intext =~ /($tag\d+$tag)/g) { |
287
|
0
|
|
|
|
|
|
my $key = $1; |
288
|
0
|
|
|
|
|
|
my $pos = pos ($intext); |
289
|
0
|
|
|
|
|
|
my $line = $tln->off2lnr ($pos); |
290
|
|
|
|
|
|
|
# print "Position $pos in $file = line $line.\n"; |
291
|
0
|
|
|
|
|
|
$renumbered{$key} = $line; |
292
|
|
|
|
|
|
|
} |
293
|
|
|
|
|
|
|
#print Dumper (\%renumbered); |
294
|
0
|
|
|
|
|
|
$intext =~ s/($tag\d+$tag)/#line $renumbered{$1} "$file"/g; |
295
|
|
|
|
|
|
|
# Check for failures. We already checked this doesn't occur |
296
|
|
|
|
|
|
|
# naturally in the file above. |
297
|
0
|
0
|
|
|
|
|
die if $intext =~ /$tag\d+$tag/; |
298
|
0
|
|
|
|
|
|
return $intext; |
299
|
|
|
|
|
|
|
} |
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
sub linein |
302
|
|
|
|
|
|
|
{ |
303
|
0
|
|
|
0
|
1
|
|
my ($infile) = @_; |
304
|
0
|
|
|
|
|
|
my $intext = read_text ($infile); |
305
|
0
|
|
|
|
|
|
$intext = linedirective ($intext, $infile, '#linein'); |
306
|
0
|
|
|
|
|
|
return $intext; |
307
|
|
|
|
|
|
|
} |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
sub lineout |
310
|
|
|
|
|
|
|
{ |
311
|
0
|
|
|
0
|
1
|
|
my ($outtext, $outfile) = @_; |
312
|
|
|
|
|
|
|
|
313
|
0
|
|
|
|
|
|
$outtext = linedirective ($outtext, $outfile, "#lineout"); |
314
|
0
|
|
|
|
|
|
write_text ($outfile, $outtext); |
315
|
|
|
|
|
|
|
} |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
sub stamp_file |
318
|
|
|
|
|
|
|
{ |
319
|
0
|
|
|
0
|
1
|
|
my ($fh, $name) = @_; |
320
|
0
|
0
|
|
|
|
|
if (! defined $name) { |
321
|
0
|
|
|
|
|
|
$name = "This C file"; |
322
|
|
|
|
|
|
|
} |
323
|
0
|
|
|
|
|
|
my $now = scalar localtime (); |
324
|
0
|
|
|
|
|
|
my $stamp =<
|
325
|
|
|
|
|
|
|
/* |
326
|
|
|
|
|
|
|
$name was generated by $0 at $now. |
327
|
|
|
|
|
|
|
*/ |
328
|
|
|
|
|
|
|
EOF |
329
|
0
|
|
|
|
|
|
print_out ($fh, $stamp); |
330
|
|
|
|
|
|
|
} |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
sub read_includes |
333
|
|
|
|
|
|
|
{ |
334
|
0
|
|
|
0
|
1
|
|
my ($file) = @_; |
335
|
0
|
|
|
|
|
|
my $text = read_text ($file); |
336
|
0
|
|
|
|
|
|
$text =~ s/$comment_re//g; |
337
|
0
|
|
|
|
|
|
my @hfiles; |
338
|
0
|
|
|
|
|
|
while ($text =~ /#include\s*"(.*?)"/g) { |
339
|
0
|
|
|
|
|
|
push @hfiles, $1; |
340
|
|
|
|
|
|
|
} |
341
|
0
|
|
|
|
|
|
return \@hfiles; |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
1; |