hardcoded python path in garchive and tragesym
[geda-gaf.git] / utils / scripts / pcb_backannotate
blob4993118d1c54e7c256be9508f864147e16be3638
1 #!/usr/bin/perl -w
3 # Copyright (C) 2003, 2006, 2010 Dan McMahill
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 # MA 02111-1301 USA.
21 # This script is used to process annotation files from the PCB
22 # program (http://pcb.geda-project.org) to backannotate
23 # changes to gEDA schematics.
25 # It is heavily based on the pads_backannotate program which is also
26 # part of gEDA
28 # for parsing input options
29 use Getopt::Long;
31 # for ceil function
32 use POSIX;
34 # don't allow -he to be interpreted as --help
35 $Getopt::Long::autoabbrev=0;
37 # make the options be case sensitive
38 $Getopt::Long::ignorecase=0;
40 &GetOptions( ('h|help' => \&usage,
41 'n|nocopy' => \$nocopy,
42 'v|verbose' => \$verbose,
43 'V|version' => \&version
44 ) );
46 usage() if $Getopt::Long::error;
47 usage() unless @ARGV;
49 # Annotation file name
50 $eco = shift( @ARGV );
52 # if no schematic names follow, exit
53 usage() unless @ARGV;
55 # make sure the input netlist exists and we can open it
56 $i = 0;
57 while( @ARGV ) {
58 $fname[$i] = shift( @ARGV );
59 die "Schematic file $fname[$i] does not exist or can not be read"
60 unless -r $fname[$i];
61 $i++;
64 $filecnt = $i;
67 if( $verbose ){ print "Loading PCB annotation file file: $eco\n"; }
68 my $eco_state="DEFAULT";
69 open( ECO, "$eco" ) or die "Can't open PCB annotation file $eco !\n";
71 my $ver = 0;
72 while( $line = <ECO> ) {
73 if( $line =~ /^\*FILEVERSION\* / ) {
74 $ver = $line;
75 $ver =~ s/^\*FILEVERSION\*\s*//;
76 $ver =~ s/[^0-9]*$//;
77 } elsif( $line =~ /^\*VERSION\* 20060814/ ) {
78 $ver = 20060814;
81 close( ECO );
83 if( $ver == 0) {
84 print "ERROR: Unable to determine annotation file version.\n";
85 exit( 1 );
88 print "Annotation file version is $ver\n" if $verbose ;
89 if( $ver != 20061031 && $ver != 20060814 ) {
90 print "ERROR: This version of the program is unable to process\n";
91 print " PCB annotation files of version $ver.\n";
92 exit( 1 );
96 # reopen and parse the file this time
97 open( ECO, "$eco" ) or die "Can't open PCB annotation file $eco !\n";
98 while( $line = <ECO> ) {
99 # if( $verbose ){ print "$line\n"; }
100 if( $line =~ /^\*COMMENT\*/ ) {
101 print "Skipping comment line: $line\n";
102 next;
103 } elsif( $line =~ /^\*VERSION\* 20060814/ || $line =~ /^\*FILEVERSION\* [0-9]*/) {
104 # the version line. Note that the very first version of the annotation
105 # file used *VERSION* but it was quickly changed to FILEVERSION to avoid
106 # confusing it with the program version.
107 next;
108 } elsif( $line =~ /^\*RENAME\*/ ) {
109 # rename refdes in design (forward/backward annotation)
110 #$eco_state="RENAME";
111 print " *RENAME* (Refdes Renumber)\n" if $verbose;
112 $line =~ s/^\*RENAME\*\s*//;
113 parseRENAME($line);
114 next;
115 } elsif( $line =~ /^\*WARN\*/ ) {
116 # A warning generated by PCB
117 print "Found the following warning in the annotation file:\n";
118 print "$line\n";
119 next;
120 } elsif( $line =~ /^\*/ ) {
121 print "WARNING: Unknown command line:\n";
122 print " $line\n";
123 $eco_state="DEFAULT";
124 next;
125 } else {
126 # this must be a data line
127 #if( $verbose ){ print "Processing data line: $line"; }
131 close( ECO );
133 for($i=0; $i < $filecnt; $i++) {
134 print "Processing schematic file #", $i+1, ": $fname[$i]\n";
135 open(NETLIST,"$fname[$i]") or
136 die "Can't open schematic $fname[$i]: $!\n";
138 # open output netlist
139 $outfname="$fname[$i].new";
140 open(OUTSCH,">$outfname") or die "Can't open $outfname: $!\n";
142 while($line = <NETLIST>) {
143 $line = executeRENAME($line);
144 print OUTSCH "$line";
146 close(NETLIST);
147 close(OUTSCH);
149 if( $nocopy ) {
150 print "Leaving page #",$i+1," output in $outfname\n";
152 else {
153 system("mv $outfname $fname[$i]");
158 print "\n---- Gate Swapping ----\n";
159 executeSWPGATES();
160 print "\n---- Pin Swapping ----\n";
161 executeSWPPINS();
162 print "\nBackannotation finished ", scalar localtime, "\n";
164 exit;
167 #######################################################################
169 # Subroutines
171 #######################################################################
173 #---------------------------------
174 # executeRENAME(line)
175 #---------------------------------
177 sub executeRENAME {
178 my $line = shift(@_);
180 return $line unless defined %cmd_rename;
181 return $line unless $line =~ /^refdes=/;
183 # pick out the reference designator
184 $refdes = $line;
185 $refdes =~ s/^refdes=//;
186 $refdes =~ s/[\r\n]*$//;
188 # see if its listed in our hash of reference designators to be
189 # renamed
190 return $line unless exists $cmd_rename{$refdes};
192 print "executeRENAME(): Renaming $refdes to $cmd_rename{$refdes}\n"
193 if $verbose;
194 return "refdes=$cmd_rename{$refdes}\n";
198 #---------------------------------
199 # executeSWPGATES()
200 #---------------------------------
202 sub executeSWPGATES {
203 my $key;
205 foreach $key (keys %cmd_swap_gates ) {
206 print "Please manually swap gates $key and $cmd_swap_gates{$key}\n";
210 #---------------------------------
211 # executeSWPPINS()
212 #---------------------------------
214 sub executeSWPPINS {
215 my $key;
216 my @pins;
218 foreach $key (keys %cmd_swap_pins ) {
219 @pins = split '\.',,$cmd_swap_pins{$key};
220 print "Please manually swap pins $pins[0] and $pins[1] on $key\n";
224 #---------------------------------
225 # parseRENAME(line)
226 #---------------------------------
228 sub parseRENAME {
229 my $line = shift(@_);
230 my @refs;
231 @refs = split ' ',,$line;
233 $refs[0] =~ s/"//g; # "
234 $refs[1] =~ s/"//g; # "
236 print "parseRENAME(): Scheduling rename of $refs[0] to $refs[1]\n"
237 if $verbose;
238 $cmd_rename{$refs[0]} = $refs[1];
242 #---------------------------------
243 # parseSWPGATES(line)
244 #---------------------------------
246 sub parseSWPGATES {
247 my $line = shift(@_);
248 my @refs;
249 @refs = split ' ',,$line;
251 print "parseSWPGATES(): Scheduling swap of gate $refs[0] with $refs[1]\n"
252 if $verbose;
253 $cmd_swap_gates{$refs[0]} = $refs[1];
257 #---------------------------------
258 # parseSWPPINS(line)
259 #---------------------------------
261 sub parseSWPPINS {
262 my $line = shift(@_);
263 @refs = split ' ',,$line;
264 @pins = split '\.',,$refs[1];
266 print "parseSWPPINS(): Scheduling swap of pins on $refs[0] : pins ",
267 "$pins[0] and $pins[1]\n" if $verbose;
268 $cmd_swap_pins{$refs[0]} = $refs[1];
272 #---------------------------------
273 # usage()
275 # prints program usage
276 #---------------------------------
278 sub usage {
279 my $pname = $0;
280 $pname =~ s/.*\///g;
282 print <<EOF;
284 Usage:
286 $pname [-n|--nocopy] [-v|--verbose] change.log file1.sch [file2.sch ...]
287 $pname -h|--help\n
288 $pname -V|--version\n
290 $pname reads a PCB annotation file and backannotates changes\n
291 to a gEDA schematic.
293 $pname accepts the following options:
296 --help Displays this help message.
299 --nocopy If given, this flag leaves the modified files in new files
300 whose names are generated by appending a \".new\" to the
301 original file names. The default is to overwrite the original.
304 --verbose Enables verbose output.
307 --version Shows the version of this program.
310 $pname was written by Dan McMahill <dmcmahill\@netbsd.org>
315 exit;
318 #---------------------------------
319 # version()
321 # prints program version
322 #---------------------------------
324 sub version {
325 open(PROG,"$0") or die "Could not open \"$0\" to find version\n\n";
326 my $pname = $0;
327 $pname =~ s/.*\///g;
329 while($line = <PROG>) {
330 if( $line =~ /^#\s*\$Id.*\$/) {
331 @words = split ' ',,$line;
332 $version = $words[3];
333 $date = $words[4];
334 print "$pname ($0): Version $version, $date\n";
335 exit;
338 print "Could not determine version of \"$0\"\n\n";
339 exit;