3 * Convert a Viewlogic symbol/schematic to gEDA gschem format
5 * accept one argument, the name of the file to
6 * convert, converted output is displayed on stdout.
8 * Copyright (C) 1999-2010 Mike Jarabek
12 * Updated 8/16/2005 by Jeff McLamb (mclamb AT bustech.com)
13 * - Updated to support gEDA file format version 1
14 * - Added capability to import more graphic styles from ViewDraw
15 * - Corrected bug associated with absense of library reference in
16 * local ViewDraw symbols
17 * - Removed command-line option -s; no longer necessary
18 * - Mapped ViewDraw "SIGNAL" attribute to gEDA "net" attribute
19 * - Mapped ViewDraw "HETERO" attribute to a new "split" attribute
20 * - Mapped ViewDraw "PINTYPE" attributes to correct gEDA pintypes
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * as published by the Free Software Foundation; either version 2
25 * of the License, or (at your option) any later version.
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
47 #include <libgeda/colors.h>
50 * make it so we can use __attribute__((unused)) on gcc without
54 #define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
55 #endif /* GCC_VERSION */
57 #if GCC_VERSION > 2007
58 #define ATTRIBUTE_UNUSED __attribute__((unused))
60 #define ATTRIBUTE_UNUSED
64 static char vcid
[] ATTRIBUTE_UNUSED
= "$Id$";
67 #ifndef OPTARG_IN_UNISTD
73 #define MAX_TEXTLEN 1024
74 #define MAX_NODES 1024
75 #define MAX_POINTS 1024
77 /* gEDA style enumerators */
78 typedef enum {END_NONE
, END_SQUARE
, END_ROUND
} OBJECT_END
;
79 typedef enum {TYPE_SOLID
, TYPE_DOTTED
, TYPE_DASHED
, TYPE_CENTER
,
80 TYPE_PHANTOM
} OBJECT_TYPE
;
81 typedef enum {FILLING_HOLLOW
, FILLING_FILL
, FILLING_MESH
, FILLING_HATCH
}
83 typedef enum {NORMAL_PIN
, BUS_PIN
} OBJECT_PINTYPE
;
87 * 0 Black | 4 Red | 8 Gray | 12 Lt. Red
88 * 1 Blue | 5 Magenta | 9 Lt. Blue | 13 Lt. Magenta
89 * 2 Green | 6 Brown | 10 Lt. Green | 14 Yellow
90 * 3 Cyan | 7 Lt. Gray | 11 Lt. Cyan | 15 White
94 * 0 BLACK | 1 WHITE | 2 RED | 3 GREEN
95 * 4 BLUE | 5 YELLOW | 6 CYAN | 7 GREY
99 /* ViewDraw fill styles:
100 * 0 = Hollow, no fill
101 * 1 = Solid, full fill
102 * 2 = Grey92, mostly fill, thick array of empty space
103 * 4 = Grey50, 50% dot fill
104 * 6 = Grey08, thicker array of dots
105 * 7 = Grey04, thin array of dots
106 * 8 = Diagdn2, widely-spaced diagonals from top left to bottom right
107 * 11 = Diagdn1, narrowly-spaced diagonals from top left to bottom right
108 * 13 = Diagup2, widely-spaced diagonals from bottom left to top right
109 * 16 = Diagup1, narrowly-spaced diagonals from bottom left to top right
110 * 19 = Horiz, narrowly-spaced horizontal lines
111 * 21 = Vert, narrowly-spaced vertical lines
112 * 22 = Grid2, widely-spaced square grid
113 * 23 = Grid1, narrowly-spaced square grid
114 * 24 = X2, widely-spaced diagonal crosshatch
115 * 25 = X1, narrowly-spaced diagonal crosshatch
118 /* ViewDraw line styles:
121 * 2 = Center, alternating short and long dashes
122 * 3 = Phantom, alternating dash and two dots
125 * 6 = Dash-dot, alternating dashes and dots
130 int colormap
[16] = /* index is viewlogic colour, entry is geda color */
150 /* Fill style structure */
152 OBJECT_FILLING fill_type
; /* gEDA object fill type */
153 int fill_width
; /* width of the fill lines */
154 int fill_angle1
; /* first angle of fill lines */
155 int fill_pitch1
; /* first pitch/spacing of fill lines */
156 int fill_angle2
; /* second angle of fill lines */
157 int fill_pitch2
; /* second pitch/spacing of fill lines */
160 /* index is ViewDraw fill style, entry is above gEDA FillStyle struct */
161 struct FillStyle fillmap
[26] =
163 /* 0 = Hollow, no fill */
164 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
165 /* 1 = Solid, full fill */
166 {FILLING_FILL
, -1, -1, -1, -1, -1},
167 /* 2 = Grey92, mostly fill, thick array of empty space */
168 {FILLING_MESH
, 20, 45, 30, 135, 30},
169 /* 3 = Undefined; assume hollow, no fill */
170 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
171 /* 4 = Grey50, 50% dot fill */
172 {FILLING_MESH
, 10, 45, 20, 135, 20},
173 /* 5 = Undefined; assume hollow, no fill */
174 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
175 /* 6 = Grey08, thicker array of dots */
176 {FILLING_MESH
, 0, 45, 40, 135, 40}, /* Can't do dots; use mesh */
177 /* 7 = Grey04, sparse array of dots */
178 {FILLING_MESH
, 0, 45, 80, 135, 80}, /* Can't do dots; use mesh */
179 /* 8 = Diagdn2, widely-spaced diagonals from top left to bottom right */
180 {FILLING_HATCH
, 0, 135, 80, -1, -1},
181 /* 9 = Undefined; assume hollow, no fill */
182 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
183 /* 10 = Undefined; assume hollow, no fill */
184 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
185 /* 11 = Diagdn1, narrowly-spaced diagonals from top left to bottom right */
186 {FILLING_HATCH
, 0, 135, 40, -1, -1},
187 /* 12 = Undefined; assume hollow, no fill */
188 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
189 /* 13 = Diagup2, widely-spaced diagonals from bottom left to top right */
190 {FILLING_HATCH
, 0, 45, 80, -1, -1},
191 /* 14 = Undefined; assume hollow, no fill */
192 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
193 /* 15 = Undefined; assume hollow, no fill */
194 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
195 /* 16 = Diagup1, narrowly-spaced diagonals from bottom left to top right */
196 {FILLING_HATCH
, 0, 45, 40, -1, -1},
197 /* 17 = Undefined; assume hollow, no fill */
198 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
199 /* 18 = Undefined; assume hollow, no fill */
200 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
201 /* 19 = Horiz, narrowly-spaced horizontal lines */
202 {FILLING_HATCH
, 10, 0, 40, -1, -1},
203 /* 20 = Undefined; assume hollow, no fill */
204 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
205 /* 21 = Vert, narrowly-spaced vertical lines */
206 {FILLING_HATCH
, 10, 90, 40, -1, -1},
207 /* 22 = Grid2, widely-spaced square grid */
208 {FILLING_MESH
, 0, 0, 80, 90, 80},
209 /* 23 = Grid1, narrowly-spaced square grid */
210 {FILLING_MESH
, 0, 0, 40, 90, 40},
211 /* 24 = X2, widely-spaced diagonal crosshatch */
212 {FILLING_MESH
, 0, 45, 80, 135, 80},
213 /* 25 = X1, narrowly-spaced diagonal crosshatch */
214 {FILLING_MESH
, 0, 45, 40, 135, 40},
217 #define FILL_DEFAULT (struct FillStyle){FILLING_HOLLOW, -1, -1, -1, -1, -1}
219 /* Line style structure */
221 int line_width
; /* width of line */
222 OBJECT_END line_capstyle
; /* gEDA line cap style (end style) */
223 OBJECT_TYPE line_dashstyle
; /* gEDA line dash style */
224 int line_dashlength
; /* length of line dashes */
225 int line_dashspace
; /* space between line dashes */
228 struct LineStyle linemap
[8] =
231 {0, END_NONE
, TYPE_SOLID
, -1, -1},
233 {0, END_NONE
, TYPE_DASHED
, 100, 100},
234 /* 2 = Center, alternating short and long dashes */
235 {0, END_NONE
, TYPE_CENTER
, 100, 100},
236 /* 3 = Phantom, alternating dash and two dots */
237 {0, END_NONE
, TYPE_PHANTOM
, 100, 100},
239 {0, END_NONE
, TYPE_DASHED
, 400, 100},
241 {0, END_NONE
, TYPE_DOTTED
, -1, 100},
242 /* 6 = Dash-dot, alternating dashes and dots */
243 {0, END_NONE
, TYPE_CENTER
, 100, 100},
244 /* 7 = Medium dash */
245 {0, END_NONE
, TYPE_DASHED
, 200, 100},
248 #define LINE_DEFAULT (struct LineStyle){0, END_NONE, TYPE_SOLID, -1, -1}
250 /* attribute translation table */
252 char *origName
; /* name as it appears on a viewlogic schematic */
253 char *newName
; /* name as it should appear in gEDA */
254 unsigned int action
; /* what to do with this name */
257 /* action codes for translation action */
258 #define REPLACE_NAME 1
262 struct Translation translations
[] =
264 {"PKG_TYPE", "footprint", REPLACE_NAME
},
266 /* {"NC", "", KILL}, */
269 {"SIGNAL", "net", REPLACE_NAME
},
270 {"HETERO", "split", REPLACE_NAME
},
273 unsigned int nTranslations
= sizeof(translations
)/sizeof(struct Translation
);
275 /* local function prototypes */
276 int convert_file(FILE *fp
);
277 unsigned int strindex(char *s
, char c
);
278 unsigned int strrindex(char *s
, char c
);
279 void strtolower(char *s
);
280 int get_continued_string(char *buf
, size_t buffer_size
, FILE *fp
);
281 int get_style(FILE *fp
, unsigned int *colour
,
282 struct LineStyle
*linestyle
,
283 struct FillStyle
*fillstyle
);
284 void set_orientation(int *angle
, int *mirror
, int orientation
);
286 /* conversion readers */
287 void do_nop(FILE *fp
);
288 void do_bounding_box(FILE *fp
);
289 void do_unattached_attribute(FILE *fp
);
290 void do_attached_attribute(FILE *fp
);
291 void do_text(FILE *fp
);
292 void do_line(FILE *fp
);
293 void do_pin(FILE *fp
);
294 void do_box(FILE *fp
);
295 void do_circle(FILE *fp
);
296 void do_arc(FILE *fp
);
297 void do_label(FILE *fp
);
298 void do_net_start(FILE *fp
);
299 void do_net_node(FILE *fp
);
300 void do_net_segment(FILE *fp
);
301 void do_net_segment_bus(FILE *fp
);
302 void do_instance(FILE *fp
);
305 void text_object(int x
, int y
, unsigned int color
, unsigned int size
,
306 unsigned int visibility
, unsigned int show_name_value
,
307 int angle
, char *text
, unsigned int origin
);
308 void attribute_object(int x
, int y
, unsigned int color
, unsigned int size
,
309 unsigned int visibility
, unsigned int show_name_value
,
310 int angle
, char *name
, char *value
, unsigned int origin
);
311 void line_object(int x1
, int y1
, int x2
, int y2
, unsigned int color
,
312 struct LineStyle
*linestyle
);
313 void circle_object(int bx
, int by
, unsigned int radius
, unsigned int bcolor
,
314 struct LineStyle
*linestyle
, struct FillStyle
*fillstyle
);
315 void pin_object(int x1
, int y1
, int x2
, int y2
, unsigned int color
,
316 OBJECT_PINTYPE pintype
, unsigned int whichend
);
317 void box_object(int x1
, int y1
, unsigned int width
, unsigned int height
,
318 unsigned int color
, struct LineStyle
*linestyle
,
319 struct FillStyle
*fillstyle
);
320 void arc_object(int x1
, int y1
, unsigned int radius
,
321 int start_angle
, int sweep_angle
, unsigned int color
,
322 struct LineStyle
*linestyle
);
323 void net_segment(int x1
, int y1
, int x2
, int y2
, unsigned int color
);
324 void bus_segment(int x1
, int y1
, int x2
, int y2
, unsigned int color
,
326 void complex_object(int x
, int y
, unsigned int selectable
,
327 int angle
, unsigned int mirror
, char *name
);
328 void begin_attach(void);
329 void end_attach(void);
330 void reset_attributes(void);
333 int GetStringDisplayLength(char *str
,int font_size
);
338 int attach_pending
= 0; /* keep track of whether the last object */
339 /* read may have attachments pending. */
340 int add_attributes
= 0; /* keep track of whether we are adding attributes */
341 /* to some previous object */
342 int pin_attributes
= 0; /* when true, we are adding attributes to a pin */
343 int net_attributes
= 0; /* when true, we are adding atrributes to a net */
344 int complex_attributes
= 0;/* when true, we are adding attibutes to a complex*/
345 int pin_count
= 0; /* to keep track of the number of pins */
346 int reading_net
= 0; /* used to keep track of when we are reading a net*/
347 int segment_count
= 0; /* the number of net segments read for a net */
348 int net_nodes_x
[MAX_NODES
];
349 int net_nodes_y
[MAX_NODES
];
350 int scale
= 10; /* scale factor for viewlogic-geda conversion */
351 /* int symbol_mode = 0; */
352 int records_processed
= 0; /* used to keep track of the number of viewlogic
353 * records processed for diagnostics
356 int minx
= 0; /* bounding box for symbol */
365 "Usage:\n\t%s <viewlogic_filename>\n"
367 "\t<viewlogic_filename> is the name of the file you\n"
368 "\t\t\t want to convert to gEDA format\n", cmd
);
373 main(int argc
, char **argv
)
381 while ((ch
= getopt (argc
, argv
, "?h")) != -1) {
400 /* 'parse' arguments */
401 infileName
= argv
[optind
];
403 infile
=fopen(infileName
,"r");
406 fprintf(stderr
,"Error: Unable to open file `%s' in %s()\n",
407 infileName
,__func__
);
411 convert_file(infile
);
418 /* convert the given file to geda */
420 convert_file(FILE *fp
)
425 char buf
[MAX_TEXTLEN
];
427 /* output pre-amble */
428 printf("v 20050313 1\n"); /* Version timestamp 20050313, file version 1 */
432 while((c
=fgetc(fp
)) != EOF
) /* fetch record type */
434 switch(c
) /* branch to appropriate handler */
441 do_unattached_attribute(fp
);
445 do_attached_attribute(fp
);
487 do_net_segment_bus(fp
);
495 case 'V': case 'K': case 'Y': case 'i': case 'E':
501 fprintf(stderr
,"Warning 'Q' record found and not handled at"
502 "record %d, contact maintainer\n",records_processed
);
506 case 'C': /* connected pin record */
510 case 'X': /* unconnected pin record */
513 case '|': /* some kind of timestamp */
516 default: /* just read in the record and trash it */
517 fgets(buf
, MAX_TEXTLEN
, fp
);
518 /* nuke trailing CR, if there */
519 text_len
=strlen(buf
);
520 if(buf
[text_len
-1] == '\n')
524 fprintf(stderr
,"Warning: Unrecognized record #%d:\n'%c%s'\n",
525 records_processed
, c
, buf
);
530 /* output post-amble */
540 char text
[MAX_TEXTLEN
];
542 fgets(text
,MAX_TEXTLEN
,fp
);
546 do_bounding_box(FILE *fp
)
550 struct LineStyle linestyle
;
551 struct FillStyle fillstyle
;
554 /* just fetch the values and store */
555 if(fscanf(fp
,"%d %d %d %d\n", &minx
, &miny
, &maxx
, &maxy
) != 4)
557 fprintf(stderr
,"Error: Invalid bounding box record #%d in %s()\n",
558 records_processed
, __func__
);
567 /* Do not draw the bounding box, only retrieve the min and max values */
569 if (symbol_mode
== 0)
571 color
= GRAPHIC_COLOR
;
572 linestyle
= LINE_DEFAULT
;
573 fillstyle
= FILL_DEFAULT
;
574 box_object(minx
, miny
, maxx
-minx
, maxy
-miny
, color
, &linestyle
,
582 do_unattached_attribute(FILE *fp
)
585 unsigned int dummy
, color
, size
, origin
, viewvis
;
587 unsigned int visibility
, show_name_value
;
588 char text
[MAX_TEXTLEN
], *name
, *value
;
589 struct LineStyle linestyle
;
590 struct FillStyle fillstyle
;
592 /* if we are inside of a pin definition, terminate */
595 /* for the moment just represent as text */
597 /* viewlogic unnatached attributes have this format:
598 * U #X #Y #SIZE #ROTATION #origin #Visibility ATTR_TEXT
600 if(fscanf(fp
,"%d %d %u %d %u %u", &x
, &y
, &size
, &angle
, &origin
,
603 fprintf(stderr
,"Error: Invalid Unattached attribute record #%d "
605 records_processed
, __func__
);
609 /* read in the text */
610 get_continued_string(text
, MAX_TEXTLEN
, fp
);
613 x
*= scale
; /* correct coordinates */
615 color
= DETACHED_ATTRIBUTE_COLOR
;
617 linestyle
= LINE_DEFAULT
;
618 fillstyle
= FILL_DEFAULT
;
619 get_style(fp
, &dummy
, &linestyle
, &fillstyle
);
621 /* evaluate visibility for attributes */
624 case 0: /* not at all visibile */
629 case 1: /* attribute and name visible */
634 case 2: /* only name visible */
639 case 3: /* only value visible */
645 fprintf(stderr
,"Error: Invalid visibility value %d in "
646 "viewlogic file at record #%d in function %s()\n",
647 viewvis
, records_processed
, __func__
);
651 /* find name and value pair */
653 index
= strindex(text
,'=');
654 if (text
[index
] == '=')
657 value
= &text
[index
+1];
664 attribute_object( x
, y
, color
, size
, visibility
, show_name_value
, angle
,
665 name
, value
, origin
);
670 do_attached_attribute(FILE *fp
)
673 unsigned int color
, dummy
, size
, origin
, viewvis
;
674 unsigned int visibility
, show_name_value
;
676 char text
[MAX_TEXTLEN
],text2
[MAX_TEXTLEN
],*name
,*value
;
677 struct LineStyle linestyle
;
678 struct FillStyle fillstyle
;
680 /* for the moment just represent as text */
682 /* attached attributes have the following format:
683 * A #X #Y #SIZE #ROTATION #ORIGIN #VISIBILITY ATTR_TEXT
685 if(fscanf(fp
,"%d %d %u %d %u %u", &x
, &y
, &size
, &angle
, &origin
,
688 fprintf(stderr
,"Error: Invalid attached attribute record #%d"
689 " in %s()\n", records_processed
, __func__
);
693 x
*= scale
; /* correct coordinates */
696 /* read in the text */
697 get_continued_string(text
, MAX_TEXTLEN
, fp
);
699 color
= ATTRIBUTE_COLOR
;
700 linestyle
= LINE_DEFAULT
;
701 fillstyle
= FILL_DEFAULT
;
702 get_style(fp
, &dummy
, &linestyle
, &fillstyle
);
704 /* evaluate visibility for attributes */
707 case 0: /* not at all visibile */
712 case 1: /* attribute and name visible */
717 case 2: /* only name visible */
722 case 3: /* only value visible */
728 fprintf(stderr
,"Error: Invalid visibility value %d in "
729 "viewlogic file at record #%d, in function %s()\n",
730 viewvis
, records_processed
, __func__
);
735 if(pin_attributes
) /* are we adding to a pin ? */
737 /* translate pintype attribute */
738 if (strncmp(text
, "PINTYPE=", 8) == 0)
740 value
= &text
[strindex(text
,'=')+1];
741 if (strcmp(value
, "ANALOG") == 0)
744 snprintf(text
, MAX_TEXTLEN
, "pintype=pas");
746 sprintf(text
, "pintype=pas");
749 else if (strcmp(value
, "BI") == 0)
752 snprintf(text
, MAX_TEXTLEN
, "pintype=io");
754 sprintf(text
, "pintype=io");
757 else if (strcmp(value
, "IN") == 0)
760 snprintf(text
, MAX_TEXTLEN
, "pintype=in");
762 sprintf(text
, "pintype=in");
765 else if (strcmp(value
, "OCL") == 0)
768 snprintf(text
, MAX_TEXTLEN
, "pintype=oc");
770 sprintf(text
, "pintype=oc");
773 else if (strcmp(value
, "OEM") == 0)
776 snprintf(text
, MAX_TEXTLEN
, "pintype=oe");
778 sprintf(text
, "pintype=oe");
781 else if (strcmp(value
, "OUT") == 0)
784 snprintf(text
, MAX_TEXTLEN
, "pintype=out");
786 sprintf(text
, "pintype=out");
789 else if (strcmp(value
, "TRI") == 0)
792 snprintf(text
, MAX_TEXTLEN
, "pintype=tri");
794 sprintf(text
, "pintype=tri");
797 else if (strcmp(value
, "PWR") == 0)
800 snprintf(text
, MAX_TEXTLEN
, "pintype=pwr");
802 sprintf(text
, "pintype=pwr");
807 fprintf(stderr
,"Error: Invalid or unknown pin type \"%s\" for record "
808 "#%d in %s()\n", value
, records_processed
, __func__
);
812 /* find name and value pair */
814 index
= strindex(text
,'=');
816 value
= &text
[index
+1];
817 attribute_object( x
, y
, color
, size
, visibility
, show_name_value
,
818 angle
, name
, value
, origin
);
820 /* done attaching pin attributes */
823 /* attach the pinseq and pinnumber attributes */
826 strncpy(text2
, text
, MAX_TEXTLEN
);
828 snprintf(text
, MAX_TEXTLEN
, "pinseq=%d",pin_count
);
830 sprintf(text
, "pinseq=%d",pin_count
);
832 /* pinseq is invisible */
833 visibility
= 0; /* overide any previous settings */
836 /* find name and value pair */
838 index
= strindex(text
,'=');
840 value
= &text
[index
+1];
841 attribute_object( x
, y
, color
, size
, visibility
, show_name_value
,
842 angle
, name
, value
, origin
);
845 snprintf(text
, MAX_TEXTLEN
, "pinnumber=%s", &text2
[2]);
847 sprintf(text
, "pinnumber=%s", &text2
[2]);
849 /* pinnumber is visible */
850 visibility
= 1; /* overide any previous settings */
854 index
= strindex(text
,'=');
856 value
= &text
[index
+1];
857 attribute_object( x
, y
, color
, size
, visibility
, show_name_value
,
858 angle
, name
, value
, origin
);
860 /* done attaching pin attributes */
866 index
= strindex(text
,'=');
867 if (text
[index
] == '=')
870 value
= &text
[index
+1];
877 attribute_object( x
, y
, color
, size
, visibility
, show_name_value
, angle
,
878 name
, value
, origin
);
885 unsigned int size
, origin
;
886 unsigned int color
, show_name_value
;
887 unsigned int visibility
;
888 char text
[MAX_TEXTLEN
];
889 struct LineStyle linestyle
;
890 struct FillStyle fillstyle
;
893 /* if we are inside of a pin definition, terminate */
896 /* viewlogic text have the following format:
897 * T #X #Y #SIZE #ROTATION #ORIGIN TEXT
899 if(fscanf(fp
,"%d %d %u %d %u",&x
, &y
, &size
, &angle
,
902 fprintf(stderr
,"Error: Invalid text record #%d in %s()\n",
903 records_processed
, __func__
);
908 /* read in the text */
909 get_continued_string(text
, MAX_TEXTLEN
, fp
);
911 x
*= scale
; /* correct coordinates */
917 /* get possible colour change */
918 linestyle
= LINE_DEFAULT
;
919 fillstyle
= FILL_DEFAULT
;
920 get_style(fp
, &color
, &linestyle
, &fillstyle
);
922 text_object(x
, y
, color
, size
, visibility
, show_name_value
, angle
, text
, \
930 int x
[MAX_POINTS
],y
[MAX_POINTS
];
931 unsigned int pairs
,color
,i
;
932 struct LineStyle linestyle
;
933 struct FillStyle fillstyle
;
936 /* if we are inside of a pin definition, terminate */
940 /* the viewlogic line primitive is composed of
941 * l #PAIRS #X1 #Y1 #X2 #Y2 ... - Line
944 if(fscanf(fp
,"%d",&pairs
) != 1)
946 fprintf(stderr
,"Error: Unable to read number of line pairs "
947 "for record #%d, in %s()\n",
948 records_processed
, __func__
);
952 /* scan in all the co-ordinate pairs and pop them into our array */
953 for (i
=0; i
< pairs
; i
++)
955 if(fscanf(fp
,"%d %d", &x
[i
], &y
[i
]) != 2)
957 fprintf(stderr
,"Error: unable to read %dth coodinate pair "
958 "for record #%d, in %s()\n",
959 i
+1, records_processed
, __func__
);
967 /* slurp up trailing CR/NL */
968 if (getc(fp
) == '\r')
971 color
= GRAPHIC_COLOR
;
972 linestyle
= LINE_DEFAULT
;
973 fillstyle
= FILL_DEFAULT
;
974 /* now check for an optional style record */
975 get_style(fp
, &color
, &linestyle
, &fillstyle
);
977 /* now, output the line as a series of geda lines */
978 for(i
=1; i
<pairs
; i
++)
979 line_object(x
[i
-1],y
[i
-1],x
[i
],y
[i
],color
,&linestyle
);
987 unsigned int pindir
, pinsense
, color
;
988 unsigned int bradius
= 25;
989 unsigned int bdiameter
= 2*bradius
;
990 unsigned int bcolor
= LOGIC_BUBBLE_COLOR
;
991 int x1
, y1
, x2
, y2
, bx
, by
, bx1
, by1
, bx2
, by2
;
992 OBJECT_PINTYPE pintype
;
993 unsigned int whichend
;
994 struct LineStyle linestyle
;
995 struct FillStyle fillstyle
;
997 /* if we are inside of a pin definition, terminate */
1000 /* viewlogic pin primitives have the following format:
1001 * P #PININSTANCE #X1 #Y1 #X2 #Y2 # #PINDIRECTION #PINSENSE
1004 if(fscanf(fp
,"%*d %d %d %d %d %*d %u %u\n",&x1
, &y1
, &x2
, &y2
,
1005 &pindir
, &pinsense
) != 6)
1007 fprintf(stderr
,"Error:Invalid pin record #%d in %s()\n",
1008 records_processed
, __func__
);
1023 /* Determine the 'whichend' parameter and the coordinates for the "bubble" */
1024 /* if we need to use one. We need a "bubble" when pinsense=1. */
1027 case 0: /* Pin on top */
1043 case 1: /* Pin on bottom */
1059 case 2: /* Pin on left */
1075 case 3: /* Pin on right */
1092 /* Invalid pin direction */
1093 fprintf(stderr
,"Error: Invalid pin direction %d in "
1094 "ViewLogic file at record #%d, in function %s()\n",
1095 pindir
, records_processed
, __func__
);
1099 /* if this pin has to be of negative polarity, add a bitty bubble
1100 * and adjust the size of the pin
1109 linestyle
= LINE_DEFAULT
;
1110 fillstyle
= FILL_DEFAULT
;
1112 circle_object(bx
,by
,bradius
,bcolor
,&linestyle
,&fillstyle
);
1115 /* For now, only normal pins are supported */
1116 pintype
= NORMAL_PIN
;
1118 pin_object(x1
,y1
,x2
,y2
,color
,pintype
,whichend
);
1121 add_attributes
= 1; /* add attributes */
1122 attach_pending
= 1; /* signal that an attachment could be coming */
1123 pin_attributes
= 1; /* and that they are pin attributes */
1124 pin_count
++; /* bump the number of pins */
1131 int x1
, y1
, x2
, y2
, width
, height
;
1133 struct LineStyle linestyle
;
1134 struct FillStyle fillstyle
;
1137 /* if we are inside of a pin definition, terminate */
1140 /* a viewlogic box has the following format:
1142 * geda view of a box has the corner, width and height
1144 if(fscanf(fp
, "%d %d %d %d\n", &x1
, &y1
, &x2
, &y2
) != 4)
1146 fprintf(stderr
, "Error: Invalid box record #%d in %s()\n",
1147 records_processed
, __func__
);
1158 color
= GRAPHIC_COLOR
;
1160 linestyle
= LINE_DEFAULT
;
1161 fillstyle
= FILL_DEFAULT
;
1162 get_style(fp
, &color
, &linestyle
, &fillstyle
);
1164 box_object(x1
,y1
,width
,height
,color
,&linestyle
,&fillstyle
);
1171 unsigned int radius
, color
;
1172 struct LineStyle linestyle
;
1173 struct FillStyle fillstyle
;
1175 /* if we are inside of a pin definition, terminate */
1178 /* a circle has the following format:
1181 if(fscanf(fp
,"%d %d %u\n",&x
, &y
, &radius
) != 3)
1183 fprintf(stderr
,"Error: Invalid circle record #%d in %s()\n",
1184 records_processed
, __func__
);
1191 color
= GRAPHIC_COLOR
;
1193 linestyle
= LINE_DEFAULT
;
1194 fillstyle
= FILL_DEFAULT
;
1195 get_style(fp
, &color
, &linestyle
, &fillstyle
);
1197 circle_object(x
,y
,radius
,color
,&linestyle
,&fillstyle
);
1203 int x1
, y1
, x2
, y2
, x3
, y3
;
1205 double x2p
, y2p
, x3p
, y3p
, yop
, xop
, xo
, yo
;
1207 double gstart
, sweep_angle
, start_angle
, end_angle
;
1209 struct LineStyle linestyle
;
1210 struct FillStyle fillstyle
;
1212 /* if we are inside of a pin definition, terminate */
1215 /* arcs have the following format:
1216 * a #X1 #Y1 #X2 #Y2 #X3 #Y3
1217 * we need to transform this into the geda convention of
1218 * center, radius, start angle, stop angle.
1221 if(fscanf(fp
,"%d %d %d %d %d %d\n",
1222 &x1
, &y1
, &x2
, &y2
, &x3
, &y3
) != 6)
1224 fprintf(stderr
,"Error: Invalid arc record #%d, in %s()\n",
1225 records_processed
, __func__
);
1235 color
= GRAPHIC_COLOR
;
1236 linestyle
= LINE_DEFAULT
;
1237 fillstyle
= FILL_DEFAULT
;
1238 get_style(fp
, &color
, &linestyle
, &fillstyle
);
1246 /* printf("Buffer: `%s'\n",buf);
1247 * printf("Values: x2p: %f, y2p: %f, x3p: %f, y3p: %f\n",x2p, y2p, x3p, y3p);
1249 if(fabs(x2p
* y3p
- y2p
* x3p
) < 0.00001)
1251 /* some miscreant entered a degenerate arc, just output lines */
1252 line_object(x1
,y1
,x2
,y2
,color
,&linestyle
);
1253 line_object(x2
,y2
,x3
,y3
,color
,&linestyle
);
1257 yop
= ((x2p
* ( x3p
*x3p
+ y3p
*y3p
) - x3p
* ( x2p
*x2p
+ y2p
*y2p
)) /
1258 (2 * (x2p
* y3p
- y2p
* x3p
)));
1260 xop
= (x2p
*x2p
- 2*y2p
*yop
) / (2 * x2p
);
1266 radius
= hypot(xop
, yop
);
1268 /* calculate start and end angles */
1269 to_rad
= 180.0/atan2(0,-1);
1270 start_angle
= atan2(y1
-yo
, x1
-xo
) * to_rad
;
1271 end_angle
= atan2(y3
-yo
, x3
-xo
) * to_rad
;
1273 if(start_angle
> end_angle
)
1276 sweep_angle
= start_angle
- end_angle
;
1280 gstart
= start_angle
;
1281 sweep_angle
= end_angle
- start_angle
;
1285 * end_angle = int(atan2(y1-yo, x1-xo) * to_rad) % 360;
1286 * start_angle = int(atan2(y3-yo, x3-xo) * to_rad) % 360;
1290 arc_object((int)xo
,(int)yo
, (unsigned int)radius
,
1291 (int)gstart
,(int)sweep_angle
, color
, &linestyle
);
1298 int x
, y
, angle
, global
, overbar
;
1299 unsigned int color
, size
, origin
, visibility
, show_name_value
;
1300 char text
[MAX_TEXTLEN
];
1301 char text2
[MAX_TEXTLEN
];
1302 struct LineStyle linestyle
;
1303 struct FillStyle fillstyle
;
1306 /* labels have the following format:
1307 * L #X #Y #SIZE #ROTATION #ORIGIN #GLOBAL #VISIBILITY #OVERBAR TEXT
1310 /* reproduce as simple text, unless it is a label for an object */
1312 if(fscanf(fp
, "%d %d %u %d %d %d %d %d", &x
, &y
, &size
, &angle
, &origin
,
1313 &global
, &visibility
, &overbar
) != 8)
1315 fprintf(stderr
,"Error: Invalid label record #%d in %s()\n",
1316 records_processed
, __func__
);
1322 color
= ATTRIBUTE_COLOR
;
1323 show_name_value
= 0;
1325 /* read in the text */
1326 get_continued_string(text2
, MAX_TEXTLEN
, fp
);
1328 /* if ViewDraw showed the label with an overbar, append a '~' to the */
1329 /* beginning of the name. gEDA does not support overbars, so the '~' lets */
1330 /* the designer know he's dealing with an active low signal */
1333 length
= strlen(text2
);
1334 text2
[length
+ 1] = 0;
1335 for (i
= length
; i
> 0; i
--)
1336 text2
[i
] = text2
[i
- 1];
1340 linestyle
= LINE_DEFAULT
;
1341 fillstyle
= FILL_DEFAULT
;
1342 get_style(fp
, &color
, &linestyle
, &fillstyle
);
1344 /* if we are inside a pin definition, mangle the pin name */
1345 if(net_attributes
== 1) /* a netname on a net is its netname */
1347 #ifdef HAVE_SNPRINTF
1348 snprintf(text
, MAX_TEXTLEN
, "netname=%s", text2
);
1350 sprintf(text
, "netname=%s", text2
);
1352 show_name_value
= 1;
1355 else if(complex_attributes
== 1) /* a label on a complex is its designator */
1357 #ifdef HAVE_SNPRINTF
1358 snprintf(text
, MAX_TEXTLEN
, "refdes=%s", text2
);
1360 sprintf(text
, "refdes=%s", text2
);
1362 show_name_value
= 1;
1364 else if(pin_attributes
== 1) /* a label on a pin is it's pinname */
1366 #ifdef HAVE_SNPRINTF
1367 snprintf(text
, MAX_TEXTLEN
, "pinlabel=%s", text2
);
1369 sprintf(text
, "pinlabel=%s", text2
);
1371 show_name_value
= 1;
1374 strcpy(text
,text2
); /* don't need to do anything, just copy */
1377 text_object(x
, y
, color
, size
, visibility
, show_name_value
, angle
, text
, \
1381 /* four functions for doing net stuff */
1383 do_net_start(FILE *fp
)
1387 fscanf(fp
,"%*d\n"); /* just dispose of the net instance number */
1394 do_net_node(FILE *fp
)
1398 /* in geda nets are composed of a number of segments, gschem connects
1399 * them together on the screen, since viewlogic stores a net as a series
1400 * of nodes we need to tabulate them and only output segments when we
1401 * get connectivity information
1403 * net segments have the following format:
1404 * J #X #Y #SEGNUM - Net segment
1407 if(segment_count
> MAX_NODES
)
1409 fprintf(stderr
,"Error: too many nodes on a net at record #%d, "
1410 "in %s(), try increasing\n"
1411 "\tMAX_NODES\n", records_processed
, __func__
);
1412 exit(1); /* this is fatal */
1415 /* get the current info */
1416 if(fscanf(fp
,"%d %d %d\n",&x
, &y
, &type
) < 2)
1418 fprintf(stderr
,"Error: Invalid net node record #%d in %s()\n",
1419 records_processed
, __func__
);
1426 net_nodes_x
[segment_count
] = x
;
1427 net_nodes_y
[segment_count
] = y
;
1434 do_net_segment(FILE *fp
)
1436 unsigned int n1
, n2
, color
;
1440 /* net segment connectivity records have the following format:
1441 * S #N1 #N2 - Net connectivity, Node N1 is connected to N2
1444 if(fscanf(fp
,"%u %u\n",&n1
, &n2
) != 2)
1446 fprintf(stderr
,"Error: Invalid net segment record #%d in %s()\n",
1447 records_processed
, __func__
);
1453 /* output a geda net segment */
1454 net_segment(net_nodes_x
[n1
], net_nodes_y
[n1
],
1455 net_nodes_x
[n2
], net_nodes_y
[n2
], color
);
1457 /* there could be attributes to follow */
1458 add_attributes
= 1; /* add attributes */
1459 attach_pending
= 1; /* signal that an attachment could be coming */
1460 net_attributes
= 1; /* and that they are net attributes */
1464 do_net_segment_bus(FILE *fp
)
1466 unsigned int n1
, n2
, color
;
1471 /* bus net segment connectivity records have the following format:
1472 * B #N1 #N2 - Net connectivity, Node N1 is bussed to N2
1475 if(fscanf(fp
,"%u %u\n",&n1
, &n2
) != 2)
1477 fprintf(stderr
,"Error: Invalid bus segment record #%d in %s()\n",
1478 records_processed
, __func__
);
1484 /* For now, we'll use ripperdir=0 (no nets connected to bus yet) */
1487 /* output a geda bus segment */
1488 bus_segment(net_nodes_x
[n1
], net_nodes_y
[n1
],
1489 net_nodes_x
[n2
], net_nodes_y
[n2
], color
, ripperdir
);
1491 /* there could be attributes to follow */
1492 add_attributes
= 1; /* add attributes */
1493 attach_pending
= 1; /* signal that an attachment could be coming */
1494 net_attributes
= 1; /* and that they are net attributes */
1498 do_instance(FILE *fp
)
1500 char text
[MAX_TEXTLEN
];
1501 char lib
[MAX_TEXTLEN
], name
[MAX_TEXTLEN
], symName
[MAX_TEXTLEN
];
1502 unsigned int extension
, selectable
;
1503 int x
, y
, angle
, orientation
, mirror
;
1505 int result
, index
, i
;
1509 /* a component instance has the following format
1510 * I #instance LIB:NAME #PAGE #X #Y #ROTATION #MAGNIFICATION '
1523 /* Instance doesn't necessarily have to have the LIB:NAME convention, so */
1524 /* read this in as a full string and parse later */
1525 /* if(fscanf(fp,"%*d %[a-zA-Z0-9]:%[a-zA-Z0-9] %u %d %d %d %g %*s\n", */
1526 result
= fscanf(fp
,"%*d %s %u %d %d %d %g %*s\n",
1527 text
, &extension
, &x
, &y
, &orientation
, &scale_factor
);
1528 /* find library and symbol name */
1529 index
= strindex(text
, ':');
1530 if (index
> 0 || text
[0] == ':')
1534 strcpy(name
, &text
[index
+1]);
1538 /* Check for input errors */
1541 fprintf(stderr
,"Error: Invalid instance record #%d in %s()\n"
1542 "lib:'%s', name:'%s'\n"
1543 "extension:%d, x:%d, y:%d\n",
1544 records_processed
, __func__
, lib
,name
,extension
, x
, y
);
1551 /* ViewDraw components are always selectable */
1554 /* Correct orientation */
1555 set_orientation(&angle
, &mirror
, orientation
);
1560 /* replace dashes in the name with underscores */
1561 for (i
= strlen(name
) - 1; i
>= 0; i
--)
1565 /* produce proper file name: */
1566 #ifdef HAVE_SNPRINTF
1567 snprintf(symName
, MAX_TEXTLEN
, "%s-%d.sym",name
,extension
);
1569 sprintf(symName
, "%s-%d.sym",name
,extension
);
1572 complex_object(x
, y
, selectable
, angle
, mirror
, symName
);
1574 /* there could be attributes to follow */
1575 add_attributes
= 1; /* add attributes */
1576 attach_pending
= 1; /* signal that an attachment could be coming */
1577 complex_attributes
= 1; /* and that they are complex attributes */
1581 /* ViewDraw mirrors components over the x-axis, but gSchem mirrors over the */
1583 /* This makes (270, 1) viewlogic -> (90, 1) gschem */
1584 /* and (90, 1) viewlogic -> (270, 1) gschem */
1585 /* and (180, 1) viewlogic -> (0, 1) gschem */
1586 /* and (0, 1) viewlogic -> (180, 1) gschem */
1588 set_orientation(int *angle
, int *mirror
, int orientation
)
1590 switch (orientation
) {
1591 case 0: /* 0 rotation, 0 mirror */
1595 case 1: /* 90 rotation, 0 mirror */
1599 case 2: /* 180 rotation, 0 mirror */
1603 case 3: /* 270 rotation, 0 mirror */
1607 case 4: /* 180 rotation, 1 mirror */
1611 case 5: /* 90 rotation, 1 mirror */
1615 case 6: /* 0 rotation, 1 mirror */
1619 case 7: /* 270 rotation, 1 mirror */
1624 fprintf(stderr
,"Error: Invalid orientation value %d at record %d\n",
1625 orientation
, records_processed
);
1631 /* output a geda text object */
1633 text_object(int x
, int y
, unsigned int color
, unsigned int size
,
1634 unsigned int visibility
, unsigned int show_name_value
,
1635 int angle
, char *text
, unsigned int origin
)
1637 unsigned int text_size
;
1639 unsigned int textlen
;
1641 unsigned int numlines
;
1643 /* fudge the text size, in viewdraw it is actually the height
1644 * in geda it is the point size. The Variable text_size contains
1645 * the height of the text in points, size contains the height of
1646 * the text in viewlogic units.
1648 text_size
= (int)(size
* 0.72);
1650 /* Translate ViewDraw text origin to gEDA
1651 * ViewDraw's text origin is specified like this:
1655 * where 1 is the top left corner of the text and 9 is the bottom right,
1657 * gEDA's text origin is specified like this:
1661 * so, the below conversion is necessary
1663 origin
= (((origin
- 1) / 3) * 6) + 3 - origin
;
1665 /* No longer necessary to emulate ViewDraw text origin, it is now supported */
1668 /* emulate the viewdraw text origin by shifting the text around */
1670 /* if the origin is one of the ones that are along the center line,
1673 if ( (origin
== 2) || (origin
== 5) || (origin
== 8) )
1675 y
-= (size
* scale
) / 2;
1678 if( (origin
== 1) || (origin
== 4) || (origin
== 7) )
1683 /* approximate the length of the text */
1685 switch(show_name_value
)
1687 case 0: /* measure whole text length */
1688 textlen
= GetStringDisplayLength(text
,text_size
);
1691 case 1: /* measure just the value part */
1692 textlen
= GetStringDisplayLength(&text
[strindex(text
,'=') + 1],
1696 case 2: /* measure just the name part */
1697 textlen
= GetStringDisplayLength(text
, text_size
)
1698 - GetStringDisplayLength(&text
[strindex(text
,'=')],text_size
);
1702 fprintf(stderr
,"Error: invalid show_name_value: %d at record #%d, "
1704 show_name_value
, records_processed
, __func__
);
1708 /* if the origin is one of the middle ones
1709 * fix the x coordinate
1711 if( (origin
== 4) || (origin
== 5) || (origin
== 6) )
1716 if( (origin
== 7) || (origin
== 8) || (origin
== 9) )
1722 /* Translate ViewDraw text rotation to gEDA text angle
1723 * ViewDraw's text rotation is specified like this:
1724 * 0 = 0 degrees, no rotation
1728 * gEDA's text angle is specified in degrees, so the below conversion is
1733 /* gEDA now supports rotated text, so we no longer need to force angle to */
1736 /* currently angled/rotated text is not supported, print a
1737 * warning, and force the orientation
1742 fprintf(stderr
,"Warning: Forcing text '%s' into standard alignment "
1744 text
,records_processed
);
1748 /* Since x and y are automatically multiplied by 10 (the scale factor), */
1749 /* the below operation is not necessary */
1751 /* force text to start on a 10 unit boundary */
1755 x
= x
+ (10 - (x
% 10));
1760 y
= y
+ (10 - (x
% 10));
1763 /* Only one line of text per statement allowed in ViewDraw, so this is */
1767 printf( "T %d %d %u %u %u %u %d %u %u\n%s\n", x
, y
, color
, text_size
,
1768 visibility
, show_name_value
, angle
, origin
, numlines
, text
);
1774 attribute_object(int x
, int y
, unsigned int color
, unsigned int size
,
1775 unsigned int visibility
, unsigned int show_name_value
,
1776 int angle
, char *name
, char *value
, unsigned int origin
)
1779 char text
[MAX_TEXTLEN
], text2
[MAX_TEXTLEN
];
1780 char tmpName
[MAX_TEXTLEN
], tmpValue
[MAX_TEXTLEN
];
1781 unsigned int i
, j
, done
, length
;
1783 /* make a copy of the attribute to work with */
1784 strncpy(tmpName
, name
, MAX_TEXTLEN
-1);
1785 tmpName
[MAX_TEXTLEN
-1] = 0; /* terminate in case strncpy doesnt */
1787 tmpValue
[0] = 0; /* no value with ViewDraw attribute */
1790 strncpy(tmpValue
, value
, MAX_TEXTLEN
-1);
1791 tmpValue
[MAX_TEXTLEN
-1] = 0; /* terminate in case strncpy doesnt */
1794 /* look up attribute name in translation attribute list
1795 * and translate or print approprate message
1798 for(i
=0; (i
<nTranslations
) && !done
; i
++)
1802 printf("Comparing `%s' to `%s' in %s()\n",tmpName
,
1803 translations
[i
].origName
,__func__
);
1806 if(strcmp(tmpName
,translations
[i
].origName
) == 0) /* match? */
1807 switch(translations
[i
].action
)
1810 strncpy(tmpName
, translations
[i
].newName
, MAX_TEXTLEN
-1);
1815 fprintf(stderr
,"Warning: Killing attribute `%s=%s' at (%d,%d)"
1816 " from record #%d\n",
1817 tmpName
, tmpValue
,x
,y
,records_processed
);
1822 fprintf(stderr
,"Warning: attribute name `%s=%s' at (%d,%d) "
1823 "at record #%d, found during conversion\n"
1824 "\tpassing it through unchanged\n",
1825 tmpName
,tmpValue
,x
,y
,records_processed
);
1829 fprintf(stderr
,"Error: Unknown action code for attribute\n"
1830 "`%s=%s' at record #%d in %s()\n",
1831 tmpName
,tmpValue
,records_processed
,__func__
);
1836 /* if attribute name was not replaced/dropped, convert to lowercase */
1839 strtolower(tmpName
);
1841 /* If we are changing a ViewDraw SIGNAL attribute to a net attribute, */
1842 /* replace the ';' delimiter with a ':' */
1843 if (strcmp(tmpName
, "net") == 0)
1844 tmpValue
[strindex(tmpValue
, ';')] = ':';
1846 /* If we are changing a ViewDraw HETERO attribute to a split attribute, */
1847 /* format the new value correctly */
1848 if (strcmp(tmpName
, "split") == 0)
1850 strcpy(text2
, tmpValue
);
1853 length
= strlen(text2
);
1854 for (i
= 0; i
< length
; i
++)
1856 /* Drop parentheses */
1857 if (text2
[i
] != '(' && text2
[i
] != ')')
1859 /* Convert dashes to underscores */
1860 if (text2
[i
] == '-')
1861 tmpValue
[j
++] = '_';
1862 /* insert gEDA symbol file extension before comma */
1863 else if (text2
[i
] == ',')
1865 #ifdef HAVE_SNPRINTF
1866 snprintf(&tmpValue
[j
], MAX_TEXTLEN
, "-1.sch,");
1868 sprintf(&tmpValue
[j
], "-1.sch,");
1873 tmpValue
[j
++] = text2
[i
];
1876 /* append gEDA symbol file extension to the end */
1877 #ifdef HAVE_SNPRINTF
1878 snprintf(&tmpValue
[j
], MAX_TEXTLEN
, "-1.sch");
1880 sprintf(&tmpValue
[j
], "-1.sch");
1884 /* If we have an NC attribute with no value, convert to netname=NC */
1885 if (strcmp(tmpName
, "nc") == 0 && tmpValue
[0] == 0)
1887 #ifdef HAVE_SNPRINTF
1888 snprintf(tmpName
, MAX_TEXTLEN
, "netname");
1889 snprintf(tmpValue
, MAX_TEXTLEN
, "NC");
1891 sprintf(tmpName
, "netname");
1892 sprintf(tmpValue
, "NC");
1894 show_name_value
= 1;
1897 /* just add an = into the middle */
1898 #ifdef HAVE_SNPRINTF
1899 snprintf(text
, MAX_TEXTLEN
, "%s=%s", tmpName
, tmpValue
);
1901 sprintf(text
, "%s=%s", tmpName
, tmpValue
);
1904 text_object( x
, y
, color
, size
, visibility
, show_name_value
, \
1905 angle
, text
, origin
);
1911 line_object(int x1
, int y1
, int x2
, int y2
, unsigned int color
,
1912 struct LineStyle
*linestyle
)
1914 printf("L %d %d %d %d %u %i %i %i %i %i\n", x1
, y1
, x2
, y2
, color
,
1915 linestyle
->line_width
, linestyle
->line_capstyle
,
1916 linestyle
->line_dashstyle
,linestyle
->line_dashlength
,
1917 linestyle
->line_dashspace
);
1921 circle_object(int bx
, int by
, unsigned int radius
, unsigned int bcolor
,
1922 struct LineStyle
*linestyle
, struct FillStyle
*fillstyle
)
1924 printf("V %d %d %u %u %i %i %i %i %i %i %i %i %i %i %i\n",
1925 bx
, by
, radius
, bcolor
,
1926 linestyle
->line_width
, linestyle
->line_capstyle
,
1927 linestyle
->line_dashstyle
,linestyle
->line_dashlength
,
1928 linestyle
->line_dashspace
,
1929 fillstyle
->fill_type
, fillstyle
->fill_width
,
1930 fillstyle
->fill_angle1
, fillstyle
->fill_pitch1
,
1931 fillstyle
->fill_angle2
, fillstyle
->fill_pitch2
);
1935 pin_object(int x1
, int y1
, int x2
, int y2
, unsigned int color
,
1936 OBJECT_PINTYPE pintype
, unsigned int whichend
)
1938 printf("P %d %d %d %d %u %u %u\n", x1
, y1
, x2
, y2
, color
,
1943 box_object(int x1
, int y1
, unsigned int width
, unsigned int height
,
1944 unsigned int color
, struct LineStyle
*linestyle
,
1945 struct FillStyle
*fillstyle
)
1947 printf("B %d %d %u %u %u %i %i %i %i %i %i %i %i %i %i %i\n", x1
, y1
,
1948 width
, height
, color
,
1949 linestyle
->line_width
, linestyle
->line_capstyle
,
1950 linestyle
->line_dashstyle
,linestyle
->line_dashlength
,
1951 linestyle
->line_dashspace
,
1952 fillstyle
->fill_type
, fillstyle
->fill_width
,
1953 fillstyle
->fill_angle1
, fillstyle
->fill_pitch1
,
1954 fillstyle
->fill_angle2
, fillstyle
->fill_pitch2
);
1958 arc_object(int x1
, int y1
, unsigned int radius
,
1959 int start_angle
, int sweep_angle
, unsigned int color
,
1960 struct LineStyle
*linestyle
)
1962 printf("A %d %d %u %d %d %u %i %i %i %i %i\n", x1
, y1
, radius
,
1963 start_angle
, sweep_angle
, color
,
1964 linestyle
->line_width
, linestyle
->line_capstyle
,
1965 linestyle
->line_dashstyle
, linestyle
->line_dashlength
,
1966 linestyle
->line_dashspace
);
1970 net_segment(int x1
, int y1
, int x2
, int y2
, unsigned int color
)
1972 printf("N %d %d %d %d %u\n", x1
, y1
, x2
, y2
, color
);
1976 bus_segment(int x1
, int y1
, int x2
, int y2
, unsigned int color
, int ripperdir
)
1978 printf("U %d %d %d %d %u %i\n", x1
, y1
, x2
, y2
, color
, ripperdir
);
1982 complex_object(int x
, int y
, unsigned int selectable
,
1983 int angle
, unsigned int mirror
, char *name
)
1985 printf("C %d %d %u %d %u %s\n", x
, y
, selectable
, angle
, mirror
, name
);
1992 if(attach_pending
== 1) /* begin an attachment if one is pending*/
2006 reset_attributes(void)
2009 /* if we are inside of some kind of attribute attachment
2010 * terminate it, but only if we output the begin_attach.
2012 if((add_attributes
== 1) && (attach_pending
== 0))
2017 attach_pending
= 0; /* keep track of whether the last object */
2018 /* read may have attachments pending. */
2020 add_attributes
= 0; /* keep track of whether we are adding attributes */
2021 /* to some previous object */
2022 pin_attributes
= 0; /* when true, we are adding attributes to a pin */
2023 net_attributes
= 0; /* when true, we are adding atrributes to a net */
2024 complex_attributes
= 0;/* when true, we are addint attibutes to a complex */
2027 /* read a string possibly containing continuation characters
2028 * from the given stream
2031 get_continued_string(char *buf
, size_t buffer_size
, FILE *fp
)
2036 /* skip leading whitespace */
2037 while(isspace((c
=fgetc(fp
))));
2038 ungetc(c
,fp
); /* push back last char, cause it's not whitespace */
2040 /* read in the text */
2041 fgets(buf
, buffer_size
, fp
);
2042 records_processed
++;
2043 /* nuke trailing CR/NL, if there */
2044 text_len
=strlen(buf
);
2045 while (buf
[text_len
-1] == '\n' || buf
[text_len
-1] == '\r')
2047 buf
[text_len
-1] = 0;
2051 /* check for continuation chars */
2052 while((c
= getc(fp
)) == '+')
2054 c
= getc(fp
); /* suck in space */
2055 fgets(&buf
[text_len
], MAX_TEXTLEN
-text_len
,fp
); /* read in next chunk */
2056 records_processed
++;
2057 text_len
=strlen(buf
); /* update text length */
2058 /* nuke trailing CR/NL, if there */
2059 while (buf
[text_len
-1] == '\n' || buf
[text_len
-1] == '\r')
2061 buf
[text_len
-1] = 0;
2065 ungetc(c
,fp
); /* push back last char, obviously wasn't a + */
2068 printf("Buffer:'%s' in %s()\n",buf
,__func__
);
2074 /* read in a possible style record to modify the current style */
2075 int get_style(FILE *fp
, unsigned int *colour
,
2076 struct LineStyle
*linestyle
,
2077 struct FillStyle
*fillstyle
)
2080 unsigned int vdfillstyle
, vdlinestyle
;
2083 if(c
== 'Q') /* do we have a modifier? */
2085 if(fscanf(fp
,"%u %u %u\n", colour
, &vdfillstyle
, &vdlinestyle
) != 3)
2087 fprintf(stderr
,"Error: Invalid modifier record #%d in %s()\n",
2088 records_processed
, __func__
);
2092 /* re-map colour into a geda colour */
2095 fprintf(stderr
,"Error: Invalid colour number %u in record #%d, "
2097 *colour
,records_processed
, __func__
);
2100 *colour
= colormap
[*colour
];
2102 /* re-map vdfillstyle to gEDA FillStyle */
2103 if (vdfillstyle
> 25)
2105 fprintf(stderr
,"Warning: Invalid fill style %u in record #%d, "
2106 "in %s(). Assuming \"Hollow\" fill style.\n",
2107 vdfillstyle
,records_processed
, __func__
);
2110 memcpy(fillstyle
, &fillmap
[vdfillstyle
], sizeof(struct FillStyle
));
2112 /* re-map vdlinestyle to gEDA LineStyle */
2113 if (vdlinestyle
> 7)
2115 fprintf(stderr
,"Warning: Invalid line style %u in record #%d, "
2116 "in %s(). Assuming \"Solid\" line style.\n",
2117 vdlinestyle
,records_processed
, __func__
);
2120 memcpy(linestyle
, &linemap
[vdlinestyle
], sizeof(struct LineStyle
));
2122 records_processed
++;
2125 ungetc(c
,fp
); /* false alarm */
2132 /* return the index of character c in the string pointed to by s
2135 strindex(char *s
, char c
)
2140 for(p
=s
, i
=0; *p
; p
++,i
++)
2147 /* return the index of the last occurance of character c in
2148 * the string pointed to by s
2151 strrindex(char *s
, char c
)
2154 unsigned int i
, loc
;
2157 for(p
=s
, i
=0; *p
; p
++, i
++)
2164 /* convert a string to lower case */
2171 *p
= tolower((int) *p
);