gsch2pcb: Make --m4-file and -m4-pcbdir arguments work again.
[geda-gaf/peter-b.git] / utils / scripts / sarlacc_sym
blob6bad108363588d4adbe21ebbfff807fcfec62dc8
1 #!/usr/bin/perl
3 ## Library version 0.94
4 ## This program is released under the terms of the GNU GPL
5 ## See www.fsf.org for a copy of the license
6 ##
7 ## Copyright 1999 Matthew Ettus
8 ## For more info, email matt@ettus.com
9 ##
10 ## This program will convert ORCAD text libraries to gEDA components
12 ## Changes 0.94 by <egil@kvaleberg.no>, october 5th 2002
13 ## Implement CLK modifier
14 ## Implement negation for text ('\'-character)
15 ## Doubled size to better fit with gEDA symbols
16 ## Default to U? refdes, fixed refdes and made visible
17 ## Define sarlacc_dim attribute for sarlacc_scheme
18 ## Command line options
20 ## Changes 0.93 by <egil@kvaleberg.no>, october 4th 2002
21 ## Pin attribs modified for 20020825 convention
22 ## File format to 20020825 convention
23 ## Give duplicate components correct names
24 ## Implemented BITMAP
25 ## Implemented CONVERT
26 ## Implemented multiple slot component
27 ## Better syntax check for pin defs
28 ## Removed negative coordinates by adding an offset
29 ## Got rid of need to calculate text sizes
30 ## Got the ARC right
31 ## Graphics components has invisible pin labels
32 ## Implemented pintype PWR
33 ## Implement pintypes (IN, I/O, hiZ, OUT, PAS, OC, OE)
35 ## Todo
36 ## Implement symbols like THREE_STATE
37 ## Implement FILL (?)
40 $version = "0.94";
41 $gedaversion="20020825";
44 # colors
46 $pin_color = 1; # white
47 $graphic_color = 3; # green
48 $attribute_color = 5; # yellow
49 $text_color = 9; # green
52 # symbol scaling
55 # was 6:
56 $pinnumsize = 8;
57 $partnamesize = 10;
58 # was 100:
59 $scale = 200;
61 $pinlen = 3;
62 $xoffset = $pinlen * $scale;
63 $yoffset = $pinlen * $scale;
66 # character width table (approximate)
68 @char_width=(
69 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
70 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
71 11,14,14,22,28,28,24,10,12,12,16,20,14,20,12,18,
72 26,16,26,20,26,20,24,20,22,26,12,12,20,20,20,20,
73 36,29,29,28,26,29,21,30,29,9,21,27,22,32,28,32,
74 25,32,26,25,23,27,27,37,27,25,27,12,14,12,20,25,
75 10,24,22,22,20,20,12,24,20,8,10,19,9,32,20,20,
76 20,24,14,18,12,19,20,28,19,20,21,12,10,12,22,0,
77 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
78 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
79 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
80 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
81 0,0,0,0,29,29,0,0,0,0,0,0,0,0,0,0,
82 0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,
83 0,0,0,0,24,24,0,0,0,0,0,0,0,0,0,0,
84 0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0
85 );
87 sub string_len
89 $char_points = 2;
90 $width = 0;
91 @expanded = unpack "C*",$_[0];
92 foreach $char (@expanded)
94 $width += $char_width[$char];
96 $width = ($_[1]*$width)/$char_points;
97 return $width;
101 # draw a pin
102 # $x1
103 # $x2
104 # $dx
105 # $dy
107 sub draw_pin
109 local $sx,$sy;
110 local $x2,$y2;
111 $sx = 0;
112 $sx = 1 if ($dx > 0);
113 $sx = -1 if ($dx < 0);
114 $sy = 0;
115 $sy = 1 if ($dy > 0);
116 $sy = -1 if ($dy < 0);
118 $x2 = $x1 + $sx * $len;
119 $y2 = $y1 + $sy * $len;
121 if( $is_clk )
123 local $xa,$ya,$xb,$xb;
125 $xa = $x1 - $sy * $spacing;
126 $xb = $x1 - $sx * $spacing;
127 $ya = $y1 - $sx * $spacing;
128 $yb = $y1 - $sy * $spacing;
129 print COMPONENT "L $xa $ya $xb $yb $graphic_color".
130 " 0 0 0 -1 -1\n";
131 $xa = $x1 + $sy * $spacing;
132 $ya = $y1 + $sx * $spacing;
133 print COMPONENT "L $xa $ya $xb $yb $graphic_color".
134 " 0 0 0 -1 -1\n";
137 if ( not ($pinlabel =~ /\$/) && not $is_graphic)
139 # negation?
140 if ( $pinlabel =~ /\\/ )
142 local $w;
143 $pinlabel =~ tr/\\//d;
144 $w = string_len($pinlabel,$pinnumsize);
146 if ($w > 0) {
147 local $xa,$ya,$xb,$xb;
149 $xa = $x1 + abs($sy) * $spacing
150 - $sx * $spacing;
151 $xb = $x1 + abs($sy) * $spacing
152 - $sx * ($spacing + $w);
153 $ya = $y1 + abs($sx) * $spacing
154 - $sy * $spacing;
155 $yb = $y1 + abs($sx) * $spacing
156 - $sy * ($spacing + $w);
157 print COMPONENT "L $xa $ya $xb $yb $text_color".
158 " 0 0 0 -1 -1\n";
163 if( $dotsize )
165 local $rad;
167 $rad = $dotsize / 2;
168 $x1 += $sx * $rad;
169 $y1 += $sy * $rad;
170 print COMPONENT "V $x1 $y1 $rad $pin_color ",
171 " 0 0 0 -1 -1 0 -1 -1 -1 -1 -1\n";
172 $x1 += $sx * $rad;
173 $y1 += $sy * $rad;
176 print COMPONENT "P $x1 $y1 $x2 $y2 $pin_color\n";
180 # define a pin
181 # $pinseq
182 # $place
183 # $pinnumbers
184 # $pintype
185 # $pinlabel
186 # $slots
187 # $is_graphic
189 sub def_pin
191 if ($pinnumbers =~ /^(.*)[ \t]+([A-Za-z]+)[ \t]*$/ )
193 $pinnumbers = $1;
194 $modifier = $2;
196 else
198 $modifier = "";
200 chomp $pinnumbers;
202 $len = $pinlen * $scale;
203 $visibility = 1;
204 $dotsize = 0;
205 $is_clk = 0;
206 if ($modifier eq "DOT")
208 $dotsize = $scale / 2;
210 elsif ($modifier eq "SHORT")
212 $len = $scale;
214 elsif ($modifier eq "CLK")
216 $is_clk = 1;
218 elsif ($modifier ne "")
220 print "Modifier not supported: $modifier\n";
223 $is_pwr = 0;
224 if ($pintype eq "PWR")
226 $is_pwr = 1;
227 $visibility = 0;
229 elsif (($a = $pintype_assoc{$pintype}) ne "")
231 $pintype = $a;
233 elsif ($pintype ne "")
235 ## BAD others are: tp clk pwr
236 print "Pintype not supported: $pintype\n";
239 # by gEDA convention
240 $pinlabel = "Vcc" if ($pinlabel eq "VCC");
243 # extract the pin numbers
245 if ($slots > 1)
247 $length = @array = split(" ",$pinnumbers);
248 if ($length != $slots)
250 print "Error: incorrect number of pins $length, should be $slots\n";
251 exit;
253 if (not $is_pwr)
255 $def_slot[$pinseq] = [ @array ];
257 $pinnumber = $array[0];
259 else
261 $pinnumber = $pinnumbers;
263 $pinnumber =~ tr/ //d;
264 $pinnumber =~ tr/\'//d;
265 $pinnumalign = 0;
266 $pinnumangle = 0;
267 $pinlabelalign = 0;
268 $pinlabelangle = 0;
271 # place the label
273 $letter = $num = $place;
274 $letter =~ tr/0-9//d;
275 $num =~ tr/LRTB//d;
276 $spacing = $scale / 2;
278 if ($letter eq "L")
280 $x1 = $xoffset;
281 $y1 = $yoffset + $ysize - $num*$scale;
282 $dx = -$len;
283 $dy = 0;
284 $textx = $xoffset - $spacing;
285 $texty = $y1 + $scale/10;
286 $namex = $xoffset + $spacing;
287 $namey = $y1;
288 $pinlabelalign = 1;
289 $pinnumalign = 6;
291 elsif ($letter eq "R")
293 $x1 = $xoffset + $xsize;
294 $y1 = $yoffset + $ysize - $num*$scale;
295 $dx = $len;
296 $dy = 0;
297 $textx = $xoffset + $xsize + $spacing;
298 $texty = $y1 + $scale/10;
299 $namex = $xoffset + $xsize - $spacing;
300 $namey = $y1;
301 $pinlabelalign = 7;
303 elsif ($letter eq "T")
305 $x1 = $xoffset + $num*$scale;
306 $y1 = $yoffset + $ysize;
307 $dx = 0;
308 $dy = $len;
309 $textx = $x1 - $scale/10;
310 $texty = $yoffset + $ysize + $spacing;
311 $namex = $x1;
312 $namey = $yoffset + $ysize - $spacing;
313 $pinnumangle = $pinlabelangle = 90;
314 $pinlabelalign = 7;
316 elsif ($letter eq "B")
318 $y1 = $yoffset;
319 $x1 = $xoffset + $num*$scale;
320 $dx = 0;
321 $dy = -$len;
322 $textx = $x1 - $scale/10;
323 $texty = $yoffset - $spacing;
324 $namex = $x1;
325 $namey = $yoffset + $spacing;
326 $pinnumangle = $pinlabelangle = 90;
327 $pinlabelalign = 1;
328 $pinnumalign = 6;
330 else
332 print "Cannot happen: $letter\n";
333 exit;
336 if( $is_pwr )
338 if ($pinnumber ne "")
340 print COMPONENT "T $textx $texty $attribute_color $pinnumsize 0 0 0 0\n";
341 print COMPONENT "net=$pinlabel:$pinnumber\n";
344 else
346 draw_pin();
348 ++$pinseq;
350 print COMPONENT "{\n";
352 # *EK* use pinnumber= and pinseq= for 20020825
353 if ($pinnumber ne "")
355 print COMPONENT "T $textx $texty $attribute_color $pinnumsize $visibility 1 $pinnumangle $pinnumalign\n";
356 print COMPONENT "pinnumber=$pinnumber\n";
358 print COMPONENT "T $textx $texty $attribute_color $pinnumsize 0 0 0 0\n";
359 print COMPONENT "pinseq=$pinseq\n";
360 print COMPONENT "T $textx $texty $attribute_color $pinnumsize 0 0 0 0\n";
361 print COMPONENT "pintype=$pintype\n";
363 if ( not ($pinlabel =~ /\$/) )
365 # do not show label if graphic package
366 $visibility = 0 if ($is_graphic);
368 print COMPONENT "T $namex $namey $text_color ",
369 "$pinnumsize $visibility 1 $pinlabelangle $pinlabelalign\n";
370 print COMPONENT "pinlabel=$pinlabel\n";
372 print COMPONENT "}\n";
377 # define all pins
378 # $is_graphic
380 sub def_all_pins
382 $pinseq = 0;
385 # define the pins
387 for ($pin = 0; $pin < $pins; ++$pin)
389 $place = $def_place[$pin];
390 $pinnumbers = $def_pinnumbers[$pin];
391 $pintype = $def_pintype[$pin];
392 $pinlabel = $def_pinlabel[$pin];
394 def_pin();
399 # next component
400 # $component
401 # $namelist
402 # $slots
404 sub def_component
406 open(COMPONENT,">$component-$convert.sym");
407 print COMPONENT "v $gedaversion\n";
409 print COMPONENT "T $scale 0 $attribute_color $partnamesize 1 1 0 0\n";
410 print COMPONENT "refdes=$refdes?\n";
412 # make displayed name also an attribute
413 print COMPONENT "T $scale $scale $attribute_color $partnamesize 1 1 0 0\n";
414 print COMPONENT "partno=$component\n";
415 print COMPONENT "T $scale $scale $attribute_color $partnamesize 0 1 0 0\n";
416 print COMPONENT "device=$component\n";
419 if ( $slots > 1 )
421 print COMPONENT "T $scale $scale $attribute_color $partnamesize 0 0 0 0\n";
422 print COMPONENT "slot=1\n";
423 print COMPONENT "T $scale $scale $attribute_color $partnamesize 0 0 0 0\n";
424 print COMPONENT "numslots=$slots\n";
426 else
428 print COMPONENT "T $scale $scale $attribute_color $partnamesize 0 0 0 0\n";
429 print COMPONENT "numslots=0\n";
432 $pins = 0;
435 # scan the pins
437 while (($line = <LIBRARY>) =~
438 /(^[LRTB][0-9]+)(.*)[ \t]+([A-Za-z\/]+)[ \t]+'(.*)'/ )
439 # L1 3 DOT I/O 'OUTPUT'
441 $def_place[$pins] = $1;
442 $def_pinnumbers[$pins] = $2;
443 $def_pintype[$pins] = $3;
444 $def_pinlabel[$pins] = $4;
445 ++$pins;
449 # define the body
452 #skip Orcad bitmaps
453 while ($line =~ /\{/)
455 $line = <LIBRARY>;
458 if ( $line =~ /BITMAP[ \t]+'(.*)'/ )
460 $is_graphic = 1;
461 def_all_pins();
463 # re-use previous vector image
464 $def_body = $body{$1};
466 $line = <LIBRARY>;
468 elsif (( $line = <LIBRARY>) =~ /VECTOR/ )
470 $is_graphic = 1;
471 def_all_pins();
473 $def_body="";
474 while (not (( $line = <LIBRARY>) =~ /END/))
476 if ($line =~ /LINE/)
478 ($dummy,$x1,$y1,$x2,$y2)=
479 split(" ",$line);
480 $x1 = $xoffset + $x1*$scale;
481 $y1 = $yoffset + $ysize - $y1*$scale;
482 $x2 = $xoffset + $x2*$scale;
483 $y2 = $yoffset + $ysize - $y2*$scale;
484 $def_body .= "L $x1 $y1 $x2 $y2 $graphic_color".
485 " 0 0 0 -1 -1\n";
487 elsif($line =~ /TEXT/)
489 # BAD set textsize properly , check multi-line text
490 ($dummy,$x1,$y1,$textsize,$text)=split(" ",$line);
491 $x1 = $xoffset + $x1*$scale;
492 $y1 = $yoffset + $ysize - $y1*$scale;
494 # print "Text=$text\n";
495 if ($text eq "OPEN_L")
497 # BAD ignore
499 elsif ($text eq "OPEN_H")
501 # BAD ignore
503 elsif ($text eq "THREE_STATE")
505 # BAD ignore
507 elsif ($text !~ /'/)
509 print "Symbol not supported: $text\n";
511 else
513 $text=~ tr/\'//d;
514 $textsize *= $pinnumsize;
515 $def_body .= "T $x1 $y1 $graphic_color $textsize 1 0 0 0\n".
516 "$text\n";
519 elsif ($line =~ /CIRCLE/)
521 ($dummy,$x1,$y1,$radius) = split(" ",$line);
522 $x1 = $xoffset + $x1*$scale;
523 $y1 = $yoffset + $ysize - $y1*$scale;
524 $radius *= $scale;
525 $def_body .= "V $x1 $y1 $radius $graphic_color".
526 " 0 0 0 -1 -1 0 -1 -1 -1 -1 -1\n";
528 elsif ($line =~ /ARC/)
530 ($dummy,$x1,$y1,$dx1,$dy1,$dx2,$dy2,$rad) =
531 split(" ",$line);
532 $x1 = $xoffset + $x1*$scale;
533 $y1 = $yoffset + $ysize - $y1*$scale;
534 $factor = 180 / atan2(1,1) / 4;
535 $startangle = int ( $factor * atan2 (-$dy1, $dx1));
536 $endangle = int ( $factor * atan2 (-$dy2, $dx2));
537 $sweepangle = $endangle - $startangle;
538 # Orcad brain damage: ARC is always < 180 deg
539 if ($sweepangle > 180) {
540 $sweepangle -= 360;
542 if ($sweepangle < -180) {
543 $sweepangle += 360;
545 $rad *= $scale;
546 $def_body .= "A $x1 $y1 $rad".
547 " $startangle $sweepangle $graphic_color".
548 " 0 0 0 -1 -1\n";
550 elsif ($line =~ /FILL/)
552 # BAD Ignore FILL
554 else
556 print "Unrecognized tag:\n $line \n";
557 exit;
561 $line = <LIBRARY>;
563 else
565 $is_graphic = 0;
566 def_all_pins();
568 $x1 = $xoffset;
569 $y1 = $yoffset;
571 $def_body = "B $x1 $y1 $xsize $ysize $graphic_color".
572 " 0 0 0 -1 -1 0 -1 -1 -1 -1 -1\n";
577 # define slots, if any
579 if ($slots > 1)
581 for ($s = 0; $s < $slots; ++$s)
583 print COMPONENT "T $scale $scale $attribute_color $partnamesize 0 0 0 0\n";
584 print COMPONENT "slotdef=",$s+1;
585 $c = ":";
587 for ($n = 0; $n < $pinseq; ++$n)
589 $pin = $def_slot[$n][$s];
590 print COMPONENT "$c$pin";
591 $c = ",";
593 print COMPONENT "\n";
598 # emit text for body
600 print COMPONENT "$def_body";
601 $body{$component} = "$def_body";
604 # for sarlacc_schem
606 print COMPONENT "T $scale $scale $attribute_color $partnamesize 0 0 0 0\n";
607 print COMPONENT "sarlacc_dim=$xoffset,$yoffset,$xsize,$ysize\n";
609 close(COMPONENT);
612 # make copies for multiple component names.
613 # device= changed to suit
615 foreach $duplicate (@namelist)
617 # make duplicate component, remembering to change device name
618 `cat $component-1.sym |
619 sed "s/partno=$component/partno=$duplicate/" |
620 sed "s/device=$component/device=$duplicate/" |
621 cat >$duplicate-1.sym`;
626 # main loop
627 # arg: library name
629 sub main_loop
631 local $library = $_[0];
633 open(LIBRARY,$library ) or die "Can't open $library: $!\n";
635 $line = <LIBRARY>;
636 if ( not ($line =~ /Compiled/ ))
638 print $line;
639 print "Not a library file: $library\n";
640 die;
643 while (not (<LIBRARY> =~ /PREFIX/)){};
644 while (not (<LIBRARY> =~ /END/)){};
646 $line = <LIBRARY>;
648 while (not (eof LIBRARY))
650 if ($line =~ /\'/)
652 $component = $line;
653 $component =~ s/\'//g;
654 chomp $component;
655 $component =~ s/\r//g;
656 $component =~ s/\ /_/g;
657 $convert = 1;
658 $refdes="U";
660 # Handle components with multiple names....
661 @namelist = ();
662 while (($line = <LIBRARY>) =~ /^\'/)
664 $line =~ s/\'//g;
665 chomp $line;
666 $line =~ s/\r//g;
667 $line =~ s/\ /_/g;
668 push @namelist ,( $line);
671 if ($line =~ /REFERENCE/)
673 ($dummy,$refdes) = split("\'",$line);
674 $line = <LIBRARY>;
677 ($dummy,$x,$y,$slots) = split("=}",$line);
678 ($xsize) = split(" ",$x);
679 ($ysize) = split(" ",$y);
680 $xsize *= $scale;
681 $ysize *= $scale;
683 chomp $slots;
684 $slots =~ tr/ //d;
686 # print "Define: $component\n";
688 def_component();
690 elsif ( $line =~ /CONVERT/ )
692 $convert += 1;
693 def_component();
695 else
697 $line = <LIBRARY>;
700 close(LIBRARY);
704 # main
707 # pin types for Orcad to gEDA
708 $pintype_assoc{'PWR'} = "pwr";
709 $pintype_assoc{'IN'} = "in";
710 $pintype_assoc{'I/O'} = "io";
711 $pintype_assoc{'OUT'} = "out";
712 $pintype_assoc{'hiZ'} = "tri";
713 $pintype_assoc{'PAS'} = "pas";
714 $pintype_assoc{'OC'} = "oc";
715 $pintype_assoc{'OE'} = "oe";
717 $argc = @ARGV;
719 for ($argn = 0; $argn < @ARGV; ++$argn)
721 $arg = $ARGV[$argn];
722 if ($arg =~ /^-([A-Za-z?])(.*)$/ ) {
723 if ($1 eq "s") {
724 $scale = $2;
725 } elsif ($1 eq "v") {
726 print "sarlacc_sym ver $version\n";
727 } else {
728 print "Convert Oracd symbol library (text format) to gEDA\n";
729 print "\nUsage: sarlacc_sym [options] library",
730 "\nOptions:",
731 # "\n -d<dir> directory for symbols",
732 "\n -h help",
733 "\n -s<n> scale <n>%, default is $scale",
734 "\n -v version",
735 "\n\n";
736 die;
738 } else {
739 main_loop($arg);