gsch2pcb: Make --m4-file and -m4-pcbdir arguments work again.
[geda-gaf/peter-b.git] / utils / scripts / convert_sym.awk
blob1877f6aa26036c0e4c301459a138653496affb05
1 #!/usr/bin/awk -f
2 # $Id$
3 # $Author$
4 # awk script to convert viewlogic symbol files to geda files
7 # Copyright (C) 1998 Mike Jarabek
9 # This program is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 2 of the License, or
12 # (at your option) any later version.
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with this program; if not, write to the Free Software
21 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 BEGIN {
25 print "v 19981025";
27 reset_attributes();
29 reading_net = 0; # used to keep track of when we are reading a net
30 segment_count = 1; # the number of net segments read for a net
34 # bounding box
35 $1 == "D" {
37 # just fetch the values and store
39 minx = $2 * 10;
40 miny = $3 * 10;
41 maxx = $4 * 10;
42 maxy = $5 * 10;
46 # unattached attribute
47 $1 == "U" {
49 # if we are inside of a pin definition, terminate
50 reset_attributes();
52 # for the moment just represent as text
54 # viewlogic unnatached attributes have this format:
55 # U #X #Y #SIZE #ROTATION #origin #Visibility ATTR_TEXT
57 x = ($2) * 10;
58 y = ($3) * 10;
59 color = 1;
60 size = $4;
61 angle = $5;
62 text = $8;
63 # if there are more fields on the line, they must be text
64 # this works, but some spacing may be lost
65 if (NF > 8) {
66 for(i = 9; i <= NF; i++) {
67 text = text " " $i;
69 } origin = $6;
71 # evaluate visibility for attributes
72 viewvis = $7;
73 if( viewvis == 0 ) { # not at all visibile
74 visibility = 0;
75 show_name_value = 0;
76 } else if (viewvis == 1) { # attribute and name visible
77 visibility = 1;
78 show_name_value = 0;
79 } else if (viewvis == 2) { # only name visible
80 visibility = 2;
81 show_name_value = 1;
82 } else if (viewvis == 3) { # only value visible
83 visibility = 1;
84 show_name_value = 1;
88 text_object( x, y, color, size, visibility, show_name_value, angle, text, \
89 origin);
93 # attached attribute
94 $1 == "A" {
96 # attached attributes have the following format:
97 # A #X #Y #SIZE #ROTATION #ORIGIN #VISIBILITY ATTR_TEXT
99 # extract interesting bits:
101 x = ($2) * 10;
102 y = ($3) * 10;
103 color = 1;
104 size = $4;
105 angle = $5;
106 text = $8;
107 # if there are more fields on the line, they must be text
108 # this works, but some spacing may be lost
109 if (NF > 8) {
110 for(i = 9; i <= NF; i++) {
111 text = text " " $i;
114 origin = $6;
116 # evaluate visibility for attributes
117 viewvis = $7;
118 if( viewvis == 0 ) { # not at all visibile
119 visibility = 0;
120 show_name_value = 0;
121 } else if (viewvis == 1) { # attribute and name visible
122 visibility = 1;
123 show_name_value = 0;
124 } else if (viewvis == 2) { # only name visible
125 visibility = 2;
126 show_name_value = 1;
127 } else if (viewvis == 3) { # only value visible
128 visibility = 1;
129 show_name_value = 1;
132 # output the attachment magic if needed.
133 begin_attach();
134 text_object( x, y, color, size, visibility, show_name_value, angle, text, \
135 origin);
139 # text primitive
140 $1 == "T" {
142 # if we are inside of a pin definition, terminate
143 reset_attributes();
145 # viewlogic text have the following format:
146 # T #X #Y #SIZE #ROTATION #ORIGIN TEXT
148 x = $2 * 10;
149 y = $3 * 10;
150 color = 3;
151 size = $4;
152 visibility = 1;
153 show_name_value = 0;
154 angle = $5;
155 text = $7;
156 # if there are more fields on the line, they must be text
157 # this works, but some spacing may be lost
158 if (NF > 7) {
159 for(i = 8; i <= NF; i++) {
160 text = text " " $i;
163 origin = $6
165 text_object(x, y, color, size, visibility, show_name_value, angle, text, \
166 origin);
170 # line primitive
171 $1 == "l" {
173 # if we are inside of a pin definition, terminate
174 reset_attributes();
177 # the viewlogic line primitive is composed of
178 # l #PAIRS #X1 #Y1 #X2 #Y2 ... - Line
180 pairs = $2;
181 color = 3;
183 # represent this as a series of simple geda lines
184 for (i=0; i < (pairs-1); i++) {
185 x1 = $((i*2)+3) * 10;
186 y1 = $((i*2)+4) * 10;
187 x2 = $((i*2)+5) * 10;
188 y2 = $((i*2)+6) * 10;
190 line_object(x1,y1,x2,y2,color);
194 # pin primitive
195 $1 == "P" {
197 # if we are inside of a pin definition, terminate
198 reset_attributes();
200 # viewlogic pin primitives have the following format:
201 # P #PININSTANCE #X1 #Y1 #X2 #Y2 # #PINDIRECTION #PINSENSE
203 pinsense = $9;
204 pindir = $8;
207 x1 = $3 * 10;
208 y1 = $4 * 10;
209 x2 = $5 * 10;
210 y2 = $6 * 10;
211 color = 1;
215 # if this pin has to be of negative polarity, add a bitty bubble
216 # and adjust the size of the pin
217 radius = 25;
218 radius2 = 2*radius;
219 bcolor = 6;
221 if(pinsense == 1) {
223 #print "pindir:" pindir
224 # get the bubble on the right end
226 # one of the coordinates will match up with the bounding box
227 # then just choose the other end for the bubble
229 if(x1 == minx) { # left hand side of pin touches bounding box
230 bx = x2-radius;
231 by = y2;
232 x2 -= radius2;
234 } else if (x1 == maxx) { # left end touches right side
235 bx = x2+radius;
236 by = y2;
237 x2 += radius2;
239 } else if (x2 == minx) { # right end touches left side
240 bx = x1-radius;
241 by = y1;
242 x1 -= radius2;
244 } else if (x2 == maxx) { # right end touches right side
245 bx = x1+radius;
246 by = y1;
247 x1 += radius2;
249 } else if (y1 == miny) { # left end touches bottom
250 bx = x2;
251 by = y2-radius;
252 y2 -= radius2;
254 } else if (y1 == maxy) { # left end touches top
255 bx = x2;
256 by = y2+radius;
257 y2 += radius2;
259 } else if (y2 == miny) { # right end touches bottom
260 bx = x1;
261 by = y1-radius;
262 y1 -= radius2;
264 } else if (y2 == maxy) { # right end touches top
265 bx = x1;
266 by = y1+radius;
267 y1 += radius2;
268 } else {
269 print "Pinsense error!";
270 exit;
275 circle_object(bx,by,radius,bcolor);
278 pin_object(x1,y1,x2,y2,color);
281 add_attributes = 1; # add attributes
282 attach_pending = 1; # signal that an attachment could be coming
283 pin_attributes = 1; # and that they are pin attributes
284 pin_count++; # bump the number of pins
287 # box primitive
288 $1 == "b" {
290 # if we are inside of a pin definition, terminate
291 reset_attributes();
293 # a viewlogic box has the following format:
294 # b #X1 #Y1 #X2 #Y2
295 # geda view of a box has the corner, width and height
297 x1 = $2 * 10;
298 y1 = $3 * 10;
299 x2 = $4 * 10;
300 y2 = $5 * 10;
302 width = x2-x1;
303 height = y2-y1;
304 color = 3;
306 box_object(x1,y1,width,height,color);
310 # circle primitive
311 $1 == "c" {
313 # if we are inside of a pin definition, terminate
314 reset_attributes();
316 # a circle has the following format:
317 # c #x #y #radius
319 x = $2 * 10;
320 y = $3 * 10;
321 radius = $4 * 10;
322 color = 3;
324 circle_object(x,y,radius,color);
327 # arc primitive
328 $1 == "a" {
330 # if we are inside of a pin definition, terminate
331 reset_attributes()
333 # arcs have the following format:
334 # a #X1 #Y1 #X2 #Y2 #X3 #Y3
335 # we need to transform this into the geda convention of
336 # center, radius, start angle, stop angle.
338 x1 = $2*10.0;
339 y1 = $3*10.0;
340 x2 = $4*10.0;
341 y2 = $5*10.0;
342 x3 = $6*10.0;
343 y3 = $7*10.0;
345 x2p = x2 - x1;
346 y2p = y2 - y1;
348 x3p = x3 - x1;
349 y3p = y3 - y1;
351 yop = (x2p * ( x3p^2 + y3p^2 ) - x3p * ( x2p^2 + y2p^2 )) / \
352 (2 * (x2p * y3p - y2p * x3p));
354 xop = (x2p^2 - 2*y2p*yop) / (2 * x2p);
356 xo = xop + x1;
357 yo = yop + y1;
360 radius = int(sqrt(xop^2 + yop^2));
362 # calculate start and end angles
363 to_rad = 180.0/atan2(0,-1);
364 start_angle = int(atan2(y1-yo, x1-xo) * to_rad);
365 end_angle = int(atan2(y3-yo, x3-xo) * to_rad);
367 if(start_angle > end_angle) {
368 gstart = end_angle;
369 sweep_angle = start_angle - end_angle;
370 } else {
371 gstart = start_angle;
372 sweep_angle = end_angle - start_angle;
375 #end_angle =
376 #end_angle = int(atan2(y1-yo, x1-xo) * to_rad) % 360;
377 #start_angle = int(atan2(y3-yo, x3-xo) * to_rad) % 360;
380 color = 1;
382 arc_object(int(xo),int(yo), radius, gstart, sweep_angle, color);
386 # label primitive
387 $1 == "L" {
389 # labels have the following format:
390 # L #X #Y #SIZE #ROTATION #ORIGIN #GLOBAL #VISIBILITY #OVERBAR TEXT
392 # reproduce as simple text
394 x = $2 * 10;
395 y = $3 * 10;
396 color = 5;
397 size = $4;
398 visibility = 1;
399 show_name_value = 0;
401 # Note from Ales, some ViewDraw symbols of mine had text labels which
402 # had an angle of 3 which is wrong, so I just changed the next line to:
403 # angle = 0
405 angle = $5;
406 text = $10;
407 # if there are more fields on the line, they must be text
408 # this works, but some spacing may be lost
409 if (NF > 10) {
410 for(i = 11; i <= NF; i++) {
411 text = text " " $i;
414 origin = $6;
417 # if we are inside a pin definition, mangle the pin name
418 if(pin_attributes == 1) {
419 text = "pin" pin_count "=" text;
420 show_name_value = 1; # and show just the name
421 } else if(net_attributes == 1) {
422 text = "net=" text; # a label on a net is the net name
423 show_name_value = 1;
424 } else if(complex_attributes == 1) {
425 text = "refdes=" text; # a label on a complex is its designator
426 show_name_value = 1;
429 begin_attach();
430 text_object(x, y, color, size, visibility, show_name_value, angle, text, \
431 origin);
434 # nets
435 $1 == "N" {
437 reset_attributes();
440 reading_net = 1;
441 segment_count = 1;
442 delete net_nodes_x; # zap the array
443 delete net_nodes_y;
446 $1 == "J" {
448 # in geda nets are composed of a number of segments, gschem connects
449 # them together on the screen, since viewlogic stores a net as a series
450 # of nodes we need to tabulate them and only output segments when we
451 # get connectivity information
453 # net segments have the following format:
454 # J #X #Y #SEGNUM - Net segment
456 # get the current info
457 x = $2*10;
458 y = $3*10;
460 net_nodes_x[segment_count] = x;
461 net_nodes_y[segment_count] = y;
463 segment_count++;
466 $1 == "S" {
468 reset_attributes();
470 # net segment connectivity records have the following format:
471 # S #N1 #N2 - Net connectivity, Node N1 is connected to N2
473 n1 = int($2);
474 n2 = int($3);
475 color = 4;
477 # output a geda net segment
478 net_segment(net_nodes_x[n1], net_nodes_y[n1], \
479 net_nodes_x[n2], net_nodes_y[n2], color);
481 # there could be attributes to follow
482 add_attributes = 1; # add attributes
483 attach_pending = 1; # signal that an attachment could be coming
484 net_attributes = 1; # and that they are net attributes
488 $1 == "B" {
490 reset_attributes();
492 # bus segment connectivity records have the following format:
493 # B #N1 #N2 - Bus connectivity, Node N1 is connected to N2
495 n1 = int($2);
496 n2 = int($3);
497 color = 4;
499 # output a geda net segment -- since geda does not know about busses -- yet
500 net_segment(net_nodes_x[n1], net_nodes_y[n1], \
501 net_nodes_x[n2], net_nodes_y[n2], color);
503 # there could be attributes to follow
504 add_attributes = 1; # add attributes
505 attach_pending = 1; # signal that an attachment could be coming
506 net_attributes = 1; # and that they are net attributes
510 # component instance
511 $1 == "I" {
513 reset_attributes();
514 # a component instance has the following format
515 # I #instance LIB:NAME #PAGE #X #Y #ROTATION #MAGNIFICATION
517 x = $5*10;
518 y = $6*10;
519 selectable = 1;
520 angle = 0;
521 mirror = 0; # need to add logic to decode rotation and mirror
523 # get name
524 fullname = $3;
525 split(fullname, names, ":");
527 # get extension
528 extension = $4;
530 # produce proper file name:
531 name = tolower(names[2]) "." extension ".sym";
533 complex_object(x, y, selectable, angle, mirror, name);
535 # there could be attributes to follow
536 add_attributes = 1; # add attributes
537 attach_pending = 1; # signal that an attachment could be coming
538 complex_attributes = 1; # and that they are complex attributes
541 # just junk any records we do not deal with
544 # utility functions
545 function text_object( x, y, color, size, visibility, show_name_value, \
546 angle, text, origin) {
548 # fudge the text size, in viewdraw it is actually the height
549 # in geda it is the point size
551 text_size = int(size * 0.72);
553 # emulate the viewdraw text origin by shifting the text around
555 # if the origin is one of the ones that are along the center line,
556 # adjust y
558 if ( (origin == 2) || (origin == 5) || (origin == 8) ) {
559 y -= (size*10) / 2;
562 if( (origin == 1) || (origin == 4) || (origin == 7) ) {
563 y -= size * 10;
566 # approximate the length of the text
567 if(show_name_value == 0) {
568 text_to_measure = text;
569 } else if(show_name_value == 1) {
570 split(text,a,"=");
571 text_to_measure = a[2]; # measure just the value part
572 } else if(show_name_value == 2) {
573 split(text,a,"=");
574 text_to_measure = a[1]; # measure just the textual part
577 textlen = length(text_to_measure) * size * 10;
578 # if the origin is one of the middle ones
579 # fix the x coordinate
580 if( (origin == 4) || (origin == 5) || (origin == 6) ) {
581 x -= textlen / 2;
584 if( (origin == 7) || (origin == 8) || (origin == 9) ) {
585 x -= textlen;
589 print "T", x, y, color, text_size, visibility, show_name_value, angle;
590 print text;
593 function line_object( x1,y1,x2,y2,color ) {
595 print "L",x1,y1,x2,y2,color;
598 function circle_object( bx,by,radius,bcolor ) {
600 print "V",bx,by,radius,bcolor;
603 function pin_object( x1,y1,x2,y2,color ) {
605 print "P",x1,y1,x2,y2,color;
608 function box_object( x1,y1,width,height,color ) {
610 print "B",x1,y1,width,height,color;
613 function arc_object( x1, y1, radius, start_angle, sweep_angle, color) {
615 print "A",x1, y1, radius, start_angle, sweep_angle, color;
619 function net_segment( x1, y1, x2, y2, color ) {
621 print "N", x1, y1, x2, y2, color;
625 function complex_object(x, y, selectable, angle, mirror, name) {
627 print "C", x, y, selectable, angle, mirror, name;
630 function begin_attach() {
632 if(attach_pending == 1) { # begin an attachment if one is pending
633 print "{";
634 attach_pending = 0;
638 function end_attach() {
640 print "}";
643 function reset_attributes() {
645 # if we are inside of some kind of attribute attachment
646 # terminate it, but only if we output the begin_attach.
647 if((add_attributes == 1) && (attach_pending == 0)) {
648 end_attach();
651 attach_pending = 0; # keep track of whether the last object
652 # read may have attachments pending.
654 add_attributes = 0; # keep track of whether we are adding attributes
655 # to some previous object
656 pin_attributes = 0; # when true, we are adding attributes to a pin
657 net_attributes = 0; # when true, we are adding atrributes to a net
658 complex_attributes = 0; # when true, we are addint attibutes to a complex
659 pin_count = 0; # to keep track of the number of pins