chiark / gitweb /
multiple input files
authorian <ian>
Wed, 14 Apr 2004 21:56:48 +0000 (21:56 +0000)
committerian <ian>
Wed, 14 Apr 2004 21:56:48 +0000 (21:56 +0000)
farnell/farnell-find

index 7eb890923adae3634525501b949fda5f852ccabd..f6edb3bef19100ec215c49a264e200eee9d1f803 100755 (executable)
@@ -1,13 +1,16 @@
 #!/usr/bin/perl -w
 
 # Usages:
-#   ./farnell-find.pl NNN-NNNN
+#   ./farnell-find.pl [<options>] NNN-NNNN
 #       Prints info about the specified relevant part.
-#   ./farnell-find.pl <file> [<sort>...]
-#       Processes input file <file> and sorts output according to
-#       <sort> (several may be specified).  <sort>s can be `desc'
-#       `avail' `price' (first mentioned is most significant.
-#       Default sort order is `avail price desc'.
+#   ./farnell-find.pl [<options>] <file> ...
+#       Processes input files and produces BOM parts list.
+# Options:
+#   -S<sort>
+#       Specifies sort order for BOM.  Several may be specified, first
+#       one on the command line is least significant.  Can be `desc'
+#       `avail' `price'.  Default sort order is avail, then price,
+#       then desc (equivalent to -Sdesc -Sprice -Savail).
 #
 # Input format: lines, #-comments, blank lines ignored.
 # Indent level is relevant, but only 0, 1, >1 relevant.
 #        is <desc prefix> with a space and the remainder of the part
 #        name appended.
 #   end
-#        Ends the file.  Mandatory.
+#        Ends the file.  Optional.
 
 use strict;
 use POSIX;
 use IO::Handle;
+use IO::File;
 
 our(@warn);
 our(@fault);
@@ -61,7 +65,7 @@ our(%parts);
 # $parts{"$circuit\n$sper"}[]{Part}       or item
 # $parts{"$circuit\n$sper"}[]{Qty}
 # $parts{"$circuit\n$sper"}[]{Use}
-# $parts{"$circuit\n$sper"}[]{LineNo}
+# $parts{"$circuit\n$sper"}[]{FileLine}
 
 our(%partdef);
 # $partdef{"part name"}= $item;
@@ -75,7 +79,7 @@ our(%iteminstances);
 # $iteminstances{$item}[]{Use}   includes circuit
 # $iteminstances{$item}[]{Qty}
 # $iteminstances{$item}[]{Mult}   number of this iteratable
-# $iteminstances{$item}[]{LineNo}
+# $iteminstances{$item}[]{FileLine}
 
 our(%itemdesc);
 # $itemdesc{$item}[]= $desc;
@@ -161,12 +165,16 @@ sub snarf ($;$) {
     return $1;
 }
 
-sub read_spec () {
+sub read_spec ($) {
+    my ($filename) = @_;
     local ($_);
     my ($circuit,$iteratable,$desc);
-    my ($part,$qty,$use);
+    my ($part,$qty,$use,$f);
+    $f= new IO::File $filename, 'r' or die "$filename: $!\n";
     for (;;) {
-       $!=0; $_=<F>; die unless defined $_;
+       $_=<$f>;
+       die "$filename: read: $!\n" if $f->error;
+       last unless defined $_;
        chomp; s/\s+$//;
        last if m/^end$/;
        next if m/^\#/ || !m/\S/;
@@ -181,8 +189,9 @@ sub read_spec () {
            ($part,$qty,$use) = ($1,$2,$3);
            $qty .= $partfrac_unique++ if $qty =~ m,/$,;
            push @{ $parts{"$circuit\n$iteratable"} }, {
-               Part => $part, Qty => $qty, Use => $use, LineNo => $.
-               };
+               Part => $part, Qty => $qty, Use => $use,
+               FileLine => "$filename:$."
+           };
        } elsif (m/^($part_re)\s+\?\s+\=\s+(\S.*)$/) {
            die if exists $pkinddesc{$1};
            $pkinddesc{$1}= $2;
@@ -196,6 +205,7 @@ sub read_spec () {
            die "$_ ?";
        }
     }
+    $f->close;
 }
 
 sub itemsortmap ($) {
@@ -214,7 +224,7 @@ sub itemsortmap ($) {
        } elsif ($how eq 'avail') {
            $o .= $bi->{Avail};
        } else {
-           die "unknown sort option \`$o'\n";
+           die;
        }
     }
     return $o;
@@ -261,14 +271,14 @@ sub analyse_spec () {
            } elsif (exists $partdef{$part}) {
                $item= $partdef{$part};
            } else {
-               push @fault, "unknown part $part (line $pe->{LineNo})";
+               push @fault, "unknown part $part ($pe->{FileLine})";
                next;
            }
            push @{ $iteminstances{$item} }, {
                Use => $use,
                Qty => $pe->{Qty},
                Mult => $count,
-               LineNo => $pe->{LineNo}
+               FileLine => $pe->{FileLine}
                };
        }
     }
@@ -276,15 +286,14 @@ sub analyse_spec () {
     $desclen= 42;
     foreach $item (sort keys %iteminstances) {
        $why= defined $itemdesc{$item} ? $itemdesc{$item}[0].'; ' : '';
-       $why .= "line ".(join ",", map { $_->{LineNo} }
-                      @{ $iteminstances{$item} });
+       $why .= join ",", map { $_->{FileLine} } @{ $iteminstances{$item} };
        $bi= by_item($item, $why);
        $iteminfo{$item}= $bi;
     }  
     foreach $item (keys %iteminstances) {
        $totalqty= { };
        foreach $ii (@{ $iteminstances{$item} }) {
-           addqty($totalqty, $ii->{Qty}, $ii->{Mult}, $item, $ii->{LineNo});
+           addqty($totalqty, $ii->{Qty}, $ii->{Mult}, $item, $ii->{FileLine});
        }
        $bi= $iteminfo{$item};
        next unless $bi;
@@ -408,6 +417,18 @@ sub dump_warnerrs () {
     die "errors\n" if @fault;
 }
 
+@sorthow= qw(avail price desc);
+
+while (@ARGV && $ARGV[0] =~ m/^\-/) {
+    $_= shift @ARGV;
+    last if m/^\-\-$/;
+    if (m/^\-S(avail|price|desc)$/) {
+       unshift @sorthow, $1;
+    } else {
+       die "unknown option \`$_'\n";
+    }
+}
+
 if (@ARGV==1 && $ARGV[0] =~ m/^\d\d\d\-/) {
     my ($chr, $k);
     $chr= by_item($ARGV[0]);
@@ -415,13 +436,11 @@ if (@ARGV==1 && $ARGV[0] =~ m/^\d\d\d\-/) {
     foreach $k (sort keys %$chr) {
        printf "%-20s %s\n", $k, $chr->{$k} or die $!;
     }
-} elsif (@ARGV>=1) {
+} elsif (@ARGV) { 
     my ($filename);
-    ($filename, @sorthow) = @ARGV;
-    push @sorthow, qw(avail price desc);
-    open F, "< $filename" or die $!;
-    read_spec();
-    close F or die $!;
+    foreach $filename (@ARGV) {
+       read_spec($filename);
+    }
     analyse_spec();
     exit !!@fault;
 } else {