Root/
| 1 | #!/usr/bin/perl |
| 2 | |
| 3 | require "parser.pl"; |
| 4 | require "misc.pl"; |
| 5 | |
| 6 | |
| 7 | sub usage |
| 8 | { |
| 9 | print STDERR <<"END"; |
| 10 | usage: $0 [-c] [-f|-t] [-r] [-s/from/to/ ...] ... |
| 11 | |
| 12 | -c generate CSV output (default: generate formatted text) |
| 13 | -f generate SMT fab output (default: generate shopping list) |
| 14 | -r sort by component reference (default: sort by part number) |
| 15 | -s/from/to/ substitute description and treat result as reference |
| 16 | -t print the total number of items and the total cost. |
| 17 | -t cannot be combined with -c or -f. |
| 18 | END |
| 19 | exit(1); |
| 20 | } |
| 21 | |
| 22 | $shop = 1; |
| 23 | $by_pn = 1; |
| 24 | while ($ARGV[0] =~ /^-./) { |
| 25 | if ($ARGV[0] =~ /^-s/) { |
| 26 | &usage unless &dsc_xlat_arg($'); |
| 27 | } elsif ($ARGV[0] eq "-c") { |
| 28 | $csv = 1; |
| 29 | } elsif ($ARGV[0] eq "-f") { |
| 30 | $shop = 0; |
| 31 | } elsif ($ARGV[0] eq "-r") { |
| 32 | $by_pn = 0; |
| 33 | } elsif ($ARGV[0] eq "-t") { |
| 34 | $total = 1; |
| 35 | } else { |
| 36 | &usage; |
| 37 | } |
| 38 | shift @ARGV; |
| 39 | } |
| 40 | |
| 41 | &usage if $total && !$shop; |
| 42 | &usage if $total && $csv; |
| 43 | |
| 44 | &parse; |
| 45 | |
| 46 | $out[0][0] = "Pos"; |
| 47 | $out[1][0] = "Qty"; |
| 48 | $out[2][0] = "P/N"; |
| 49 | $out[3][0] = "Description"; |
| 50 | |
| 51 | if ($shop) { |
| 52 | $out[4][0] = "Value"; |
| 53 | $out[5][0] = ""; |
| 54 | } else { |
| 55 | $out[4][0] = "Ref"; |
| 56 | } |
| 57 | |
| 58 | for (sort { $by_pn ? $a cmp $b : &cmp_cref($order{$a}[3], $order{$b}[3]) } |
| 59 | keys %order) { |
| 60 | push(@{ $out[0] }, ++$n); |
| 61 | push(@{ $out[1] }, $shop ? $order{$_}[0] : @{ $order{$_} }-3); |
| 62 | @f = split(/\s+/, $_); |
| 63 | push(@{ $out[2] }, $shop ? $f[1] : "$f[0] $f[1]"); |
| 64 | my $dsc = &dsc_find($_); |
| 65 | print STDERR "$_: no description\n" unless defined $dsc; |
| 66 | push(@{ $out[3] }, defined $dsc ? $dsc : "???"); |
| 67 | if ($shop) { |
| 68 | push(@{ $out[4] }, $order{$_}[1]); |
| 69 | push(@{ $out[5] }, sprintf("%.2f", $order{$_}[2])); |
| 70 | $price{$order{$_}[1]} += $order{$_}[2]; |
| 71 | } else { |
| 72 | my @r = @{ $order{$_} }; |
| 73 | push(@{ $out[4] }, join(", ", @r[3..$#r])); |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | if ($csv) { |
| 78 | for ($i = 0; $i <= $#{ $out[0] }; $i++) { |
| 79 | for ($j = 0; $j <= $#out; $j++) { |
| 80 | print "," if $j; |
| 81 | if ($i && $j < 2) { |
| 82 | print $out[$j][$i]; |
| 83 | } else { |
| 84 | my $s = $out[$j][$i]; |
| 85 | $s =~ s/"/''/g; |
| 86 | print "\"$s\""; |
| 87 | } |
| 88 | } |
| 89 | print "\n"; |
| 90 | } |
| 91 | exit(0); |
| 92 | } |
| 93 | |
| 94 | for (@out) { |
| 95 | push(@max, 0); |
| 96 | if (length $_->[0]) { |
| 97 | $max[$last_pos] = $last_len if defined $last_pos; |
| 98 | $last_pos = $#max; |
| 99 | $last_len = length $_->[0]; |
| 100 | } |
| 101 | } |
| 102 | $i = 0; |
| 103 | for (@out) { |
| 104 | $first = 1; |
| 105 | for (@{ $_ }) { |
| 106 | next if $first-- > 0; |
| 107 | $max[$i] = length $_ if length $_ > $max[$i]; |
| 108 | } |
| 109 | $i++; |
| 110 | } |
| 111 | |
| 112 | for ($i = 0; $i <= $#{ $out[0] }; $i++) { |
| 113 | $l = ""; |
| 114 | for ($j = 0; $j != 6; $j++) { |
| 115 | my $s = $out[$j][$i];; |
| 116 | $l .= $s if $j == 2 || $j == 3 || $j == 4; |
| 117 | $l .= " " x ($max[$j]-length $s); |
| 118 | $l .= $s if $j == 0 || $j == 1 || $j == 5; |
| 119 | $l .= " " unless $j == 5; |
| 120 | } |
| 121 | $l =~ s/\s*$//; |
| 122 | print "$l\n"; |
| 123 | } |
| 124 | |
| 125 | if ($total) { |
| 126 | print "$n item".($n == 1 ? "" : "s"); |
| 127 | for (sort keys %price) { |
| 128 | print ", $_ $price{$_}"; |
| 129 | } |
| 130 | print "\n"; |
| 131 | } |
| 132 |
Branches:
master
