Subversion Repositories OpenARM Single-board Computer

Rev

Rev 293 | Rev 318 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 293 Rev 313
Line 1... Line 1...
1
#!/usr/bin/perl -w
1
#!/usr/bin/perl -w
2
use strict;
2
use strict;
3
# $Id: inventory.pl 293 2008-11-18 22:52:14Z agaran $
3
# $Id: inventory.pl 313 2008-12-28 23:03:20Z agaran $
4
# Thu, 13 Nov 2008 21:06:23 +0100
4
# Thu, 13 Nov 2008 21:06:23 +0100
5
# Maciej 'agaran' Pijanka <agaran@pld-linux.org>
5
# Maciej 'agaran' Pijanka <agaran@pld-linux.org>
6
# for OpenARM SBC Project
6
# for OpenARM SBC Project
7
# license: gpl v3
7
# license: gpl v3
8
8
9
9
10
use Getopt::Long qw//;
10
use Getopt::Long qw//;
11
use File::Basename qw/basename/;
11
use File::Basename qw/basename/;
12
12
13
my %opts;
13
my %Config;
14
14
-
 
15
# ==================================================
-
 
16
$Config{docdir} = '.';
15
$opts{dir} = '.';
17
$Config{bomdir} = '.';
16
$opts{verbose} = 1;
18
$Config{verbose} = 1;
17
19
-
 
20
# 0 mean not show, -1 show all, positive value limits depth of shown
-
 
21
$Config{dbg_showdirs} = 0;
-
 
22
-
 
23
-
 
24
# modes
18
my $dirprintoffset = 0;
25
my $build_inventory = 0;
-
 
26
my $build_bom = 0;
-
 
27
my $show_conf = 0;
-
 
28
my $show_help = 0;
-
 
29
-
 
30
# ==================================================
-
 
31
-
 
32
my %Inv_By_PartNo;
-
 
33
my @Inv;
19
34
20
sub err_printf($@) {
35
sub err_printf($@) {
21
        my ($format, @args) = @_;
36
        my ($format, @args) = @_;
22
37
23
        printf STDERR "\n-E- ".$format."\n\n", @args;
38
        printf STDERR "-E- ".$format."\n", @args;
-
 
39
        # exit? or fail-exit here
24
}
40
}
25
41
26
sub wrn_printf($@) {
42
sub wrn_printf($@) {
27
        my ($format, @args) = @_;
43
        my ($format, @args) = @_;
28
44
Line 33... Line 49...
33
        my ($format, @args) = @_;
49
        my ($format, @args) = @_;
34
50
35
        printf STDERR "-I- ".$format."\n", @args;
51
        printf STDERR "-I- ".$format."\n", @args;
36
}
52
}
37
53
-
 
54
sub Config_Show {
-
 
55
        printf "Config for %s\n----------------------------------------\n", basename($0);
-
 
56
        foreach my $name (sort keys %Config) {
-
 
57
                printf "%-20s %s\n", $name, $Config{$name};
-
 
58
        }
-
 
59
}
-
 
60
-
 
61
sub Help_Show {
-
 
62
        printf "Help for %s\n----------------------------------------\n", basename($0);
-
 
63
        unless (defined($_[1]) && length($_[1]) != 0) {
-
 
64
                print "Basic help\n\t--showrc|showconf shows current configuration\n".
-
 
65
                        "\t--docdir|-d <dir> tells script where information.txt files should be searched\n".
-
 
66
                        "\t--define <something>=<somethingelseornot> defines some configration value\n".
-
 
67
                        "\t--verbose|-v [level] sets verbosity level\nOrder of options DOES matter\n";
-
 
68
                return;
-
 
69
        }
-
 
70
        if ($_[1] =~ /^foo$/) {
-
 
71
                print "Noo, there is no foo's here\n";
-
 
72
        } else {
-
 
73
                printf "Sorry, help for `%s' don't exist (eventually) yet\n", $_[1];
-
 
74
        }
-
 
75
        exit;
-
 
76
}
-
 
77
-
 
78
sub fix_dir ($) {
-
 
79
        my $dir = shift @_;
-
 
80
-
 
81
        $dir =~ s/\/$//;
-
 
82
-
 
83
        if (! -d $dir) {
-
 
84
                err_printf("Sorry `%s' is not valid directory, exiting", $dir);
-
 
85
        }
-
 
86
-
 
87
        return $dir;
-
 
88
}
-
 
89
-
 
90
sub shortdir ($) {
-
 
91
        my $path = shift @_;
-
 
92
-
 
93
        return substr($path, 2) if ($path =~ /^\.\//) ;
-
 
94
        return $path;
-
 
95
}
-
 
96
-
 
97
-
 
98
sub trim($) {
-
 
99
        my ($value) = @_;
-
 
100
-
 
101
        $value =~ s/^ +//;
-
 
102
        $value =~ s/ +$//;
-
 
103
        return $value;
-
 
104
}
-
 
105
-
 
106
sub etrim($) {
-
 
107
        my ($value) = @_;
-
 
108
-
 
109
        $value =~ s/^[  ]+//;
-
 
110
        $value =~ s/[   ]+$//;
-
 
111
        return $value;
-
 
112
}
-
 
113
-
 
114
# this subroutine is used as callback function
-
 
115
# executed by file_lookup
38
sub parse_ifile($) {
116
sub parse_ifile($) {
39
        my ($filepath) = @_;
117
        my ($filepath) = @_;
40
118
41
        open(IN, $filepath) or return 1;
119
        open(IN, $filepath) or return 1;
42
120
Line 51... Line 129...
51
                next if ($line =~ /^;/);
129
                next if ($line =~ /^;/);
52
130
53
                last if ($line =~ /^--/);
131
                last if ($line =~ /^--/);
54
132
55
                if ($line =~ /^([A-Za-z ]+):(.*)$/) {
133
                if ($line =~ /^([A-Za-z ]+):(.*)$/) {
56
                        my ($name,$value) = ($1,$2);
134
                        my ($name,$value) = (lc etrim($1),etrim($2));
57
-
 
58
                        $name =~ s/^[   ]+//;
-
 
59
                        $value =~ s/^[  ]+//;
-
 
60
-
 
61
                        $name =~ s/[    ]+$//;
-
 
62
                        $value =~ s/[   ]+$//;
-
 
63
-
 
64
                        $name = lc $name;
-
 
65
135
66
                        if ($name =~ /^price$/) {
136
                        if ($name =~ /^price$/) {
67
                                $value =~ s/[^0-9\.\,]//g;
137
                                $value =~ s/[^0-9\.\,]//g;
68
                                if ($value =~ s/^([0-9]+)[,.]([0-9]+)$/$1.$2/) {
138
                                if ($value =~ s/^([0-9]+)[,.]([0-9]+)$/$1.$2/) {
69
                                        # printf STDERR "Price %.3f\n", $value;
139
                                        # printf STDERR "Price %.3f\n", $value;
70
                                        if (!defined($data{price})) {
140
                                        if (!defined($data{price})) {
71
                                                $data{price} = $value;
141
                                                $data{price} = $value;
72
                                        } else {
142
                                        } else {
73
                                                wrn_printf("Duplicated price field in file %s",
143
                                                wrn_printf("Duplicated price field in file %s", shortdir($filepath));
74
                                                        substr($filepath, $dirprintoffset));
-
 
75
                                        }
144
                                        }
76
                                } else {
145
                                } else {
77
                                        err_printf("Bad price field in file %s",
146
                                        err_printf("Bad price field in file %s", shortdir($filepath));
78
                                                substr($filepath, $dirprintoffset));
-
 
79
                                }
147
                                }
80
                        } elsif ($name =~ /^manufacturer$/i) {
148
                        } elsif ($name =~ /^manufacturer$/i) {
81
                                # printf STDERR "Manufacturer %s\n", $value;
149
                                # printf STDERR "Manufacturer %s\n", $value;
82
                                if (!defined($data{manufacturer})) {
150
                                if (!defined($data{manufacturer})) {
83
                                        $data{manufacturer} = $value;
151
                                        $data{manufacturer} = $value;
84
                                } else {
152
                                } else {
85
                                        wrn_printf("Duplicated manufacturer field in file %s",
153
                                        wrn_printf("Duplicated manufacturer field in file %s", shortdir($filepath));
86
                                                substr($filepath, $dirprintoffset));
-
 
87
                                }
154
                                }
88
                        } elsif ($name =~ /^manufacturer part no$/ ) {
155
                        } elsif ($name =~ /^manufacturer part no$/ ) {
89
                                # printf STDERR "ManPartNo %s\n", $value;
156
                                # printf STDERR "ManPartNo %s\n", $value;
90
                                if (!defined($data{manufact_partno})) {
157
                                if (!defined($data{manufact_partno})) {
91
                                        $data{manufact_partno} = $value;
158
                                        $data{manufact_partno} = trim($value);
92
                                } else {
159
                                } else {
93
                                        wrn_printf("Duplicated manufacturer part no field in file %s",
160
                                        wrn_printf("Duplicated manufacturer part no field in file %s",
94
                                                substr($filepath, $dirprintoffset));
161
                                                shortdir($filepath));
95
                                }
162
                                }
96
                        } elsif ($name =~ /^description$/i) {
163
                        } elsif ($name =~ /^description$/i) {
97
                                # printf STDERR "Desc %s\n", $value;
164
                                if (!defined($data{desc})) {
98
                                $data{desc} = [] unless defined $data{desc};
165
                                        $data{desc} = $value;
-
 
166
                                } else {
-
 
167
                                        wrn_printf("Duplicated description no field in file %s",
99
                                push @{$data{desc}}, $value;
168
                                                shortdir($filepath));
-
 
169
                                }
100
                        } elsif ($name =~ /^datasheet$/i) {
170
                        } elsif ($name =~ /^datasheet$/i) {
101
                                $data{datasheet} = [] unless defined $data{datasheet};
171
                                $data{datasheet} = [] unless defined $data{datasheet};
102
                                push @{$data{datasheet}}, $value;
172
                                push @{$data{datasheet}}, $value;
103
                                # printf STDERR "Datasheet %s\n", $value;
173
                                # printf STDERR "Datasheet %s\n", $value;
104
                        } elsif ($name =~ /^supplier$/i) {
174
                        } elsif ($name =~ /^supplier$/i) {
105
                                # printf STDERR "Supplier %s\n", $value;
175
                                # printf STDERR "Supplier %s\n", $value;
106
                                if (!defined($data{supplier})) {
176
                                if (!defined($data{supplier})) {
107
                                        $data{supplier} = $value;
177
                                        $data{supplier} = $value;
108
                                } else {
178
                                } else {
109
                                        wrn_printf("Duplicated supplier field in file %s",
179
                                        wrn_printf("Duplicated supplier field in file %s",
110
                                                substr($filepath, $dirprintoffset));
180
                                                shortdir($filepath));
111
                                }
181
                                }
112
                        } elsif ($name =~ /^order code$/) {
182
                        } elsif ($name =~ /^order code$/) {
113
                                # printf STDERR "Order Code %s\n", $value;
183
                                # printf STDERR "Order Code %s\n", $value;
114
                                if (!defined($data{ordercode})) {
184
                                if (!defined($data{ordercode})) {
115
                                        $data{ordercode} = $value;
185
                                        $data{ordercode} = $value;
116
                                } else {
186
                                } else {
117
                                        wrn_printf("Duplicated order code field in file %s",
187
                                        wrn_printf("Duplicated order code field in file %s",
118
                                                substr($filepath, $dirprintoffset));
188
                                                shortdir($filepath));
119
                                }
189
                                }
120
                                #push @DATA, { $name => $value };
190
                                #push @DATA, { $name => $value };
121
                        } elsif ($name =~ /^url .*$/) {
191
                        } elsif ($name =~ /^url .*$/) {
122
                                # printf STDERR "URL %s\n", $value;
192
                                # printf STDERR "URL %s\n", $value;
123
                        } elsif ($name =~ /^catalog(ue|) page$/) {
193
                        } elsif ($name =~ /^catalog(ue|) page$/) {
124
                                # printf STDERR "Catalogue Page %s\n", $value;
194
                                # printf STDERR "Catalogue Page %s\n", $value;
125
                        } else {
195
                        } else {
126
                                err_printf("Unhandled field %s in file %s", $name,
196
                                err_printf("Unhandled field %s in file %s", $name,
127
                                        substr($filepath, $dirprintoffset));
197
                                        shortdir($filepath));
128
                        }
198
                        }
129
199
130
                } else {
200
                } else {
131
                        wrn_printf("Unparseable line `%s', forgot ; to set it as comment in file %s\n", $line,
201
                        wrn_printf("Unparseable line `%s', forgot ; to set it as comment in file %s\n", $line,
132
                                substr($filepath, $dirprintoffset));
202
                                shortdir($filepath));
133
                }
203
                }
134
        }
204
        }
135
        close(IN);
205
        close(IN);
136
206
137
        if (scalar keys %data == 0) {
207
        if (scalar keys %data == 0) {
138
                inf_printf("Skipping file %s because contain no data for me",
208
                inf_printf("Skipping file %s because contain no data for me",
139
                        substr($filepath, $dirprintoffset));
209
                        shortdir($filepath));
140
                return;
210
                return;
141
        }
211
        }
142
212
143
        unless (defined ($data{price}) && $data{price} != 0) {
213
        unless (defined ($data{price}) && $data{price} != 0) {
144
                wrn_printf("Missing Price in file %s",
214
                wrn_printf("Missing Price in file %s",
145
                        substr($filepath, $dirprintoffset));
215
                        shortdir($filepath));
146
        }
216
        }
147
217
148
        unless (defined($data{manufact_partno})) {
218
        unless (defined($data{manufact_partno})) {
149
                inf_printf("Missing Manufacturer Part No in file %s",
219
                inf_printf("Missing Manufacturer Part No in file %s",
150
                        substr($filepath, $dirprintoffset));
220
                        shortdir($filepath));
151
        }
221
        }
152
222
153
        unless (defined($data{ordercode})) {
223
        unless (defined($data{ordercode})) {
154
                wrn_printf("Missing Order Code in file %s",
224
                wrn_printf("Missing Order Code in file %s",
155
                        substr($filepath, $dirprintoffset));
225
                        shortdir($filepath));
156
        }
226
        }
157
227
-
 
228
       
158
        use Data::Dumper qw/Dumper/;
229
        use Data::Dumper qw/Dumper/;
-
 
230
-
 
231
        my $id = scalar @Inv;
-
 
232
-
 
233
        $Inv[$id] = {};
-
 
234
-
 
235
        $Inv[$id]{Datasheet} = delete $data{'datasheet'} if defined $data{'datasheet'};
-
 
236
        $Inv[$id]{Manufacturer} = delete $data{'manufacturer'} if defined $data{'manufacturer'};
-
 
237
        $Inv[$id]{Description} = delete $data{'desc'} if defined $data{'desc'};
-
 
238
        $Inv[$id]{Price} = delete $data{'price'} if defined $data{'price'};
-
 
239
        $Inv[$id]{Ordercode} = delete $data{'ordercode'} if defined $data{'ordercode'};
-
 
240
        $Inv[$id]{Manufacturer_Partno} = delete $data{'manufact_partno'} if defined $data{'manufact_partno'};
-
 
241
        $Inv[$id]{Supplier} = delete $data{'supplier'} if defined $data{'supplier'};
-
 
242
-
 
243
        unless (defined ($Inv_By_PartNo{$Inv[$id]{Manufacturer_Partno}})) {
-
 
244
                $Inv_By_PartNo{$Inv[$id]{Manufacturer_Partno}} = $id;
-
 
245
        } else {
-
 
246
                wrn_printf("PartNumber %s happened more than once, using first occurence (id:%d)",
-
 
247
                        $Inv[$id]{Manufacturer_Partno}, $id);
-
 
248
        }
-
 
249
        #inf_printf("Part %s defined in file %s", $Inv[$id]{Manufacturer_Partno}, shortdir($filepath));
159
       
250
       
160
        #print Dumper(\%data);
251
        wrn_printf("Unhandled data from parsing: %s", Dumper(\%data)) if (scalar keys %data > 0);
161
}
252
}
162
253
163
sub build_ifile_list($$);
-
 
164
sub build_ifile_list($$) {
-
 
165
        my ($dir,$depth) = @_;
-
 
166
254
-
 
255
my %BomData;
-
 
256
sub parse_bom ($) {
-
 
257
        my ($filepath) = @_;
-
 
258
-
 
259
        open(IN, $filepath) or return 1;
-
 
260
-
 
261
        #wrn_printf("GotARg: %s", shortdir($filepath));
-
 
262
-
 
263
        my @Fields;
-
 
264
-
 
265
        my %data;
-
 
266
        my $v = '';
-
 
267
        while (not eof IN) {
-
 
268
                my $line = <IN>;
-
 
269
-
 
270
                chomp $line;
-
 
271
-
 
272
                if ($line =~ /^\.START$/) {
-
 
273
                        $v = 'boms';
-
 
274
                        next;
-
 
275
                }
-
 
276
-
 
277
                if ($line =~ /^\.END$/) {
-
 
278
                        $v = '';
-
 
279
                        next;
-
 
280
                }
-
 
281
-
 
282
                if ($v eq 'boms') {
-
 
283
                        @Fields = split(/\t/, substr($line,2));
-
 
284
                        $v = 'bom';
-
 
285
                        # some funny way to generate field-map
-
 
286
                        # that if someone reorder bom file columns we are still on place
-
 
287
                        next;
-
 
288
                }
-
 
289
-
 
290
                if ($v eq 'bom') {
-
 
291
                        my ($refdes, $device, $value, $footprint, $quantity) = split (/\t/, $line);
-
 
292
-
 
293
                        $device = trim($device);
-
 
294
-
 
295
#                       wrn_printf("Device: %s (value: %s) at refdes %s, %d pcs", $device, $value, $refdes, $quantity);
-
 
296
-
 
297
                        if (!defined $Inv_By_PartNo{$device}) {
-
 
298
                                wrn_printf("Device %s not found in inventory in file %s", $device, shortdir($filepath));
-
 
299
                                next;
-
 
300
                        }
-
 
301
                        my $id = $Inv_By_PartNo{$device};
-
 
302
                        next if ($Inv[$id]{Manufacturer} =~ /none/i); # skip parts whose manufacturer is none
-
 
303
                        #inf_printf("Found in Inventory at %d %s", $id, $Inv[$id]{Manufacturer_Partno});
-
 
304
                        push @{$data{$id}{RefDes}}, $refdes;
-
 
305
                }
-
 
306
        }
-
 
307
        close(IN);
-
 
308
-
 
309
        if (scalar keys %data == 0) {
-
 
310
                inf_printf("Skipping file %s because contain no data for me",
-
 
311
                        shortdir($filepath));
-
 
312
                return;
-
 
313
        }
-
 
314
-
 
315
        my $cost = 0;
-
 
316
        foreach my $id (keys %data) {
-
 
317
                my %tmp;
-
 
318
                map { $tmp{$_} = 1 } @{$data{$id}{RefDes}};
-
 
319
                @{$data{$id}{RefDes}} = keys %tmp;
-
 
320
                my $cnt = scalar @{$data{$id}{RefDes}};
-
 
321
                if (!defined $Inv[$id]{Price}) {
-
 
322
                        wrn_printf("%s has no price, setting to 0.0", $Inv[$id]{Manufacturer_Partno});
-
 
323
                        $Inv[$id]{Price} = 0;
-
 
324
                }
-
 
325
                my $icost = $Inv[$id]{Price} * $cnt;
-
 
326
#               printf "%-20s %.4f %s\n", $Inv[$id]{Manufacturer_Partno}, $cnt, $icost, join (', ', @{$data{$id}{RefDes}});
-
 
327
                $cost += $icost;
-
 
328
#               %BomData{ById}{$id}{RefDes}
-
 
329
        }
-
 
330
        printf "Total (%s): %.4f\n", shortdir($filepath), $cost;
-
 
331
}
-
 
332
-
 
333
sub file_lookup ($$$$) ;
-
 
334
sub file_lookup ($$$$) {
-
 
335
        my ($dir, $depth, $regexp, $callback) = @_;
-
 
336
-
 
337
        err_printf("Sorry, callback must be CODE ref") unless (ref $callback eq 'CODE');
167
338
168
        if ( -d $dir) {
339
        if ( -d $dir) {
169
                opendir(DIR, $dir) or return 1;
340
                opendir(DIR, $dir) or return 1;
170
                foreach my $e (readdir(DIR)) {
341
                foreach my $e (readdir(DIR)) {
171
                        my $fe = $dir .'/'. $e;
342
                        my $fe = $dir .'/'. $e;
172
                        if ( -f $fe) {
343
                        if ( -f $fe) {
173
                                # Whoo file we have
-
 
174
                                if ($e eq 'information.txt') {
344
                                if ($fe =~ $regexp) {
175
                                        # we found an information.txt file
-
 
176
                                        parse_ifile($fe);
345
                                        &$callback($fe);
177
                                } elsif ($e =~ /\.[pP][dD][fF]$/) {
-
 
178
                                        # its an pdf file if filename is correct
-
 
179
                                } elsif ($e =~ /\.sch$/) {
-
 
180
                                } else {
-
 
181
#                                       printf STDERR "FILE %s\n", $fe;
-
 
182
                                }
346
                                }
183
                        } elsif (-d $fe) { # now its dir...
347
                        } elsif (-d $fe) { # now its dir...
184
                                if ($e eq '.svn') { # if entry name is equal to svn
348
                                if ($e eq '.svn') { # if entry name is equal to svn
185
                                        next; # go to next entry in foreach loop
349
                                        next; # go to next entry in foreach loop
186
                                }
350
                                }
187
                                next if ($e eq '.' or $e eq '..'); # skip to next if dir entry is . or ..
351
                                next if ($e eq '.' or $e eq '..'); # skip to next if dir entry is . or ..
188
352
189
                                if ($opts{verbose} >= 2+$depth) {
353
                                if ($Config{dbg_showdirs} == -1 or $Config{dbg_showdirs} > $depth) {
190
                                        printf STDERR "Entering directory %s\n", substr($fe,length($opts{dir})+1);
354
                                        printf STDERR "Entering directory %s\n", shortdir($fe);
191
                                }
355
                                }
192
                                build_ifile_list($fe,$depth+1);
356
                                return 1 if (file_lookup($fe, $depth+1, $regexp, $callback) == 1);
193
                        } else {
357
                        } else {
194
                                # symlink or other myserius beast
358
                                # symlink or other mysterius beast
195
                        }
359
                        }
196
                }
360
                }
197
                closedir(DIR);
361
                closedir(DIR);
198
        }
362
        }
-
 
363
        return 0;
199
}
364
}
200
365
201
Getopt::Long::Configure("bundling");
366
Getopt::Long::Configure("bundling");
202
367
203
my $result = Getopt::Long::GetOptions (\%opts,
368
my $result = Getopt::Long::GetOptions (
-
 
369
        "showrc|showconf" => sub { $show_conf = 1 },
-
 
370
        "docdir|d=s" => sub { $Config{docdir} = $_[1]; },
204
        "dir|d=s",
371
        # not sure if bomdir or SCH dir
-
 
372
        "bomdir|b=s" => sub { $Config{$_[0]} = $_[1]; },  # $_[0] contain basename of option, so in few cases could be (ab)used
-
 
373
        "define|D=s" => sub { my ($p,$q) = split(/=/,$_[1],2); $Config{$p} = $q; },
-
 
374
        "verbose|v:+" => sub { $Config{$_[0]} = ($_[1]>1?0:$Config{$_[0]}) + $_[1]; },
-
 
375
        "help|h|?:s" => sub { $show_help = 1 },
-
 
376
205
        "verbose|v+",
377
        # options 
206
);
378
);
207
if (!$result) {
379
if (!$result) {
208
        printf "Usage: %s [-d directory] [-v]\n",basename($0);
380
        printf "Usage: %s [-d directory] [-v]\n",basename($0);
209
        exit;
381
        exit;
210
}
382
}
-
 
383
-
 
384
# ==================================================
-
 
385
# processing of options/config values, checking ranges etc
-
 
386
# 
-
 
387
-
 
388
$Config{docdir} = fix_dir ($Config{docdir});
211
$opts{dir} =~ s/\/$//;
389
$Config{bomdir} = fix_dir ($Config{bomdir});
-
 
390
212
if ($opts{dir} eq '.') {
391
if ( $show_help == 1) {
213
        $dirprintoffset = 2;
392
        Help_Show();
214
} else {
393
        exit;
-
 
394
}
-
 
395
215
        # i was thinking about some code which could shorten pathes in few cases but didnt created it yet
396
if ( $show_conf == 1) {
-
 
397
        Config_Show();
-
 
398
        exit;
216
}
399
}
217
400
-
 
401
# make Inventory
-
 
402
file_lookup($Config{docdir}, 0, qr/\/information.txt$/, \&parse_ifile);
-
 
403
-
 
404
# process BOM files
218
print Data::Dumper::Dumper(\%opts);
405
file_lookup($Config{bomdir}, 0, qr/\.bom$/, \&parse_bom);
219
406
220
build_ifile_list($opts{dir},0);
-