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-2002 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., 59 Temple Place, Suite 330, Boston, MA 02111 USA
46 #include <config.h> /* added by AVH for integration into the gEDA tarball */
47 #include <libgeda/colors.h>
49 #ifdef HAVE_LIBDMALLOC
54 * make it so we can use __attribute__((unused)) on gcc without
58 #define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
59 #endif /* GCC_VERSION */
61 #if GCC_VERSION > 2007
62 #define ATTRIBUTE_UNUSED __attribute__((unused))
64 #define ATTRIBUTE_UNUSED
68 static char vcid
[] ATTRIBUTE_UNUSED
= "$Id$";
71 #ifndef OPTARG_IN_UNISTD
77 #define MAX_TEXTLEN 1024
78 #define MAX_NODES 1024
79 #define MAX_POINTS 1024
81 /* gEDA style enumerators */
82 typedef enum {END_NONE
, END_SQUARE
, END_ROUND
} OBJECT_END
;
83 typedef enum {TYPE_SOLID
, TYPE_DOTTED
, TYPE_DASHED
, TYPE_CENTER
,
84 TYPE_PHANTOM
, TYPE_ERASE
} OBJECT_TYPE
;
85 typedef enum {FILLING_HOLLOW
, FILLING_FILL
, FILLING_MESH
, FILLING_HATCH
,
86 FILLING_VOID
} OBJECT_FILLING
;
87 typedef enum {NORMAL_PIN
, BUS_PIN
} OBJECT_PINTYPE
;
91 * 0 Black | 4 Red | 8 Gray | 12 Lt. Red
92 * 1 Blue | 5 Magenta | 9 Lt. Blue | 13 Lt. Magenta
93 * 2 Green | 6 Brown | 10 Lt. Green | 14 Yellow
94 * 3 Cyan | 7 Lt. Gray | 11 Lt. Cyan | 15 White
98 * 0 BLACK | 1 WHITE | 2 RED | 3 GREEN
99 * 4 BLUE | 5 YELLOW | 6 CYAN | 7 GREY
103 /* ViewDraw fill styles:
104 * 0 = Hollow, no fill
105 * 1 = Solid, full fill
106 * 2 = Grey92, mostly fill, thick array of empty space
107 * 4 = Grey50, 50% dot fill
108 * 6 = Grey08, thicker array of dots
109 * 7 = Grey04, thin array of dots
110 * 8 = Diagdn2, widely-spaced diagonals from top left to bottom right
111 * 11 = Diagdn1, narrowly-spaced diagonals from top left to bottom right
112 * 13 = Diagup2, widely-spaced diagonals from bottom left to top right
113 * 16 = Diagup1, narrowly-spaced diagonals from bottom left to top right
114 * 19 = Horiz, narrowly-spaced horizontal lines
115 * 21 = Vert, narrowly-spaced vertical lines
116 * 22 = Grid2, widely-spaced square grid
117 * 23 = Grid1, narrowly-spaced square grid
118 * 24 = X2, widely-spaced diagonal crosshatch
119 * 25 = X1, narrowly-spaced diagonal crosshatch
122 /* ViewDraw line styles:
125 * 2 = Center, alternating short and long dashes
126 * 3 = Phantom, alternating dash and two dots
129 * 6 = Dash-dot, alternating dashes and dots
134 int colormap
[16] = /* index is viewlogic colour, entry is geda color */
154 /* Fill style structure */
156 OBJECT_FILLING fill_type
; /* gEDA object fill type */
157 int fill_width
; /* width of the fill lines */
158 int fill_angle1
; /* first angle of fill lines */
159 int fill_pitch1
; /* first pitch/spacing of fill lines */
160 int fill_angle2
; /* second angle of fill lines */
161 int fill_pitch2
; /* second pitch/spacing of fill lines */
164 /* index is ViewDraw fill style, entry is above gEDA FillStyle struct */
165 struct FillStyle fillmap
[26] =
167 /* 0 = Hollow, no fill */
168 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
169 /* 1 = Solid, full fill */
170 {FILLING_FILL
, -1, -1, -1, -1, -1},
171 /* 2 = Grey92, mostly fill, thick array of empty space */
172 {FILLING_MESH
, 20, 45, 30, 135, 30},
173 /* 3 = Undefined; assume hollow, no fill */
174 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
175 /* 4 = Grey50, 50% dot fill */
176 {FILLING_MESH
, 10, 45, 20, 135, 20},
177 /* 5 = Undefined; assume hollow, no fill */
178 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
179 /* 6 = Grey08, thicker array of dots */
180 {FILLING_MESH
, 0, 45, 40, 135, 40}, /* Can't do dots; use mesh */
181 /* 7 = Grey04, sparse array of dots */
182 {FILLING_MESH
, 0, 45, 80, 135, 80}, /* Can't do dots; use mesh */
183 /* 8 = Diagdn2, widely-spaced diagonals from top left to bottom right */
184 {FILLING_HATCH
, 0, 135, 80, -1, -1},
185 /* 9 = Undefined; assume hollow, no fill */
186 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
187 /* 10 = Undefined; assume hollow, no fill */
188 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
189 /* 11 = Diagdn1, narrowly-spaced diagonals from top left to bottom right */
190 {FILLING_HATCH
, 0, 135, 40, -1, -1},
191 /* 12 = Undefined; assume hollow, no fill */
192 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
193 /* 13 = Diagup2, widely-spaced diagonals from bottom left to top right */
194 {FILLING_HATCH
, 0, 45, 80, -1, -1},
195 /* 14 = Undefined; assume hollow, no fill */
196 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
197 /* 15 = Undefined; assume hollow, no fill */
198 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
199 /* 16 = Diagup1, narrowly-spaced diagonals from bottom left to top right */
200 {FILLING_HATCH
, 0, 45, 40, -1, -1},
201 /* 17 = Undefined; assume hollow, no fill */
202 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
203 /* 18 = Undefined; assume hollow, no fill */
204 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
205 /* 19 = Horiz, narrowly-spaced horizontal lines */
206 {FILLING_HATCH
, 10, 0, 40, -1, -1},
207 /* 20 = Undefined; assume hollow, no fill */
208 {FILLING_HOLLOW
, -1, -1, -1, -1, -1},
209 /* 21 = Vert, narrowly-spaced vertical lines */
210 {FILLING_HATCH
, 10, 90, 40, -1, -1},
211 /* 22 = Grid2, widely-spaced square grid */
212 {FILLING_MESH
, 0, 0, 80, 90, 80},
213 /* 23 = Grid1, narrowly-spaced square grid */
214 {FILLING_MESH
, 0, 0, 40, 90, 40},
215 /* 24 = X2, widely-spaced diagonal crosshatch */
216 {FILLING_MESH
, 0, 45, 80, 135, 80},
217 /* 25 = X1, narrowly-spaced diagonal crosshatch */
218 {FILLING_MESH
, 0, 45, 40, 135, 40},
221 #define FILL_DEFAULT (struct FillStyle){FILLING_HOLLOW, -1, -1, -1, -1, -1}
223 /* Line style structure */
225 int line_width
; /* width of line */
226 OBJECT_END line_capstyle
; /* gEDA line cap style (end style) */
227 OBJECT_TYPE line_dashstyle
; /* gEDA line dash style */
228 int line_dashlength
; /* length of line dashes */
229 int line_dashspace
; /* space between line dashes */
232 struct LineStyle linemap
[8] =
235 {0, END_NONE
, TYPE_SOLID
, -1, -1},
237 {0, END_NONE
, TYPE_DASHED
, 100, 100},
238 /* 2 = Center, alternating short and long dashes */
239 {0, END_NONE
, TYPE_CENTER
, 100, 100},
240 /* 3 = Phantom, alternating dash and two dots */
241 {0, END_NONE
, TYPE_PHANTOM
, 100, 100},
243 {0, END_NONE
, TYPE_DASHED
, 400, 100},
245 {0, END_NONE
, TYPE_DOTTED
, -1, 100},
246 /* 6 = Dash-dot, alternating dashes and dots */
247 {0, END_NONE
, TYPE_CENTER
, 100, 100},
248 /* 7 = Medium dash */
249 {0, END_NONE
, TYPE_DASHED
, 200, 100},
252 #define LINE_DEFAULT (struct LineStyle){0, END_NONE, TYPE_SOLID, -1, -1}
254 /* attribute translation table */
256 char *origName
; /* name as it appears on a viewlogic schematic */
257 char *newName
; /* name as it should appear in gEDA */
258 unsigned int action
; /* what to do with this name */
261 /* action codes for translation action */
262 #define REPLACE_NAME 1
266 struct Translation translations
[] =
268 {"PKG_TYPE", "footprint", REPLACE_NAME
},
270 /* {"NC", "", KILL}, */
273 {"SIGNAL", "net", REPLACE_NAME
},
274 {"HETERO", "split", REPLACE_NAME
},
277 unsigned int nTranslations
= sizeof(translations
)/sizeof(struct Translation
);
279 /* local function prototypes */
280 int convert_file(FILE *fp
);
281 unsigned int strindex(char *s
, char c
);
282 unsigned int strrindex(char *s
, char c
);
283 void strtolower(char *s
);
284 int get_continued_string(char *buf
, size_t buffer_size
, FILE *fp
);
285 int get_style(FILE *fp
, unsigned int *colour
,
286 struct LineStyle
*linestyle
,
287 struct FillStyle
*fillstyle
);
288 void set_orientation(int *angle
, int *mirror
, int orientation
);
290 /* conversion readers */
291 void do_nop(FILE *fp
);
292 void do_bounding_box(FILE *fp
);
293 void do_unattached_attribute(FILE *fp
);
294 void do_attached_attribute(FILE *fp
);
295 void do_text(FILE *fp
);
296 void do_line(FILE *fp
);
297 void do_pin(FILE *fp
);
298 void do_box(FILE *fp
);
299 void do_circle(FILE *fp
);
300 void do_arc(FILE *fp
);
301 void do_label(FILE *fp
);
302 void do_net_start(FILE *fp
);
303 void do_net_node(FILE *fp
);
304 void do_net_segment(FILE *fp
);
305 void do_net_segment_bus(FILE *fp
);
306 void do_instance(FILE *fp
);
309 void text_object(int x
, int y
, unsigned int color
, unsigned int size
,
310 unsigned int visibility
, unsigned int show_name_value
,
311 int angle
, char *text
, unsigned int origin
);
312 void attribute_object(int x
, int y
, unsigned int color
, unsigned int size
,
313 unsigned int visibility
, unsigned int show_name_value
,
314 int angle
, char *name
, char *value
, unsigned int origin
);
315 void line_object(int x1
, int y1
, int x2
, int y2
, unsigned int color
,
316 struct LineStyle
*linestyle
);
317 void circle_object(int bx
, int by
, unsigned int radius
, unsigned int bcolor
,
318 struct LineStyle
*linestyle
, struct FillStyle
*fillstyle
);
319 void pin_object(int x1
, int y1
, int x2
, int y2
, unsigned int color
,
320 OBJECT_PINTYPE pintype
, unsigned int whichend
);
321 void box_object(int x1
, int y1
, unsigned int width
, unsigned int height
,
322 unsigned int color
, struct LineStyle
*linestyle
,
323 struct FillStyle
*fillstyle
);
324 void arc_object(int x1
, int y1
, unsigned int radius
,
325 int start_angle
, int sweep_angle
, unsigned int color
,
326 struct LineStyle
*linestyle
);
327 void net_segment(int x1
, int y1
, int x2
, int y2
, unsigned int color
);
328 void bus_segment(int x1
, int y1
, int x2
, int y2
, unsigned int color
,
330 void complex_object(int x
, int y
, unsigned int selectable
,
331 int angle
, unsigned int mirror
, char *name
);
332 void begin_attach(void);
333 void end_attach(void);
334 void reset_attributes(void);
337 int GetStringDisplayLength(char *str
,int font_size
);
342 int attach_pending
= 0; /* keep track of whether the last object */
343 /* read may have attachments pending. */
344 int add_attributes
= 0; /* keep track of whether we are adding attributes */
345 /* to some previous object */
346 int pin_attributes
= 0; /* when true, we are adding attributes to a pin */
347 int net_attributes
= 0; /* when true, we are adding atrributes to a net */
348 int complex_attributes
= 0;/* when true, we are adding attibutes to a complex*/
349 int pin_count
= 0; /* to keep track of the number of pins */
350 int reading_net
= 0; /* used to keep track of when we are reading a net*/
351 int segment_count
= 0; /* the number of net segments read for a net */
352 int net_nodes_x
[MAX_NODES
];
353 int net_nodes_y
[MAX_NODES
];
354 int scale
= 10; /* scale factor for viewlogic-geda conversion */
355 /* int symbol_mode = 0; */
356 int records_processed
= 0; /* used to keep track of the number of viewlogic
357 * records processed for diagnostics
360 int minx
= 0; /* bounding box for symbol */
369 "Usage:\n\t%s <viewlogic_filename>\n"
371 "\t<viewlogic_filename> is the name of the file you\n"
372 "\t\t\t want to convert to gEDA format\n", cmd
);
377 main(int argc
, char **argv
)
385 while ((ch
= getopt (argc
, argv
, "?h")) != -1) {
404 /* 'parse' arguments */
405 infileName
= argv
[optind
];
407 infile
=fopen(infileName
,"r");
410 fprintf(stderr
,"Error: Unable to open file `%s' in %s()\n",
411 infileName
,__func__
);
415 convert_file(infile
);
422 /* convert the given file to geda */
424 convert_file(FILE *fp
)
429 char buf
[MAX_TEXTLEN
];
431 /* output pre-amble */
432 printf("v 20050313 1\n"); /* Version timestamp 20050313, file version 1 */
436 while((c
=fgetc(fp
)) != EOF
) /* fetch record type */
438 switch(c
) /* branch to appropriate handler */
445 do_unattached_attribute(fp
);
449 do_attached_attribute(fp
);
491 do_net_segment_bus(fp
);
499 case 'V': case 'K': case 'Y': case 'i': case 'E':
505 fprintf(stderr
,"Warning 'Q' record found and not handled at"
506 "record %d, contact maintainer\n",records_processed
);
510 case 'C': /* connected pin record */
514 case 'X': /* unconnected pin record */
517 case '|': /* some kind of timestamp */
520 default: /* just read in the record and trash it */
521 fgets(buf
, MAX_TEXTLEN
, fp
);
522 /* nuke trailing CR, if there */
523 text_len
=strlen(buf
);
524 if(buf
[text_len
-1] == '\n')
528 fprintf(stderr
,"Warning: Unrecognized record #%d:\n'%c%s'\n",
529 records_processed
, c
, buf
);
534 /* output post-amble */
544 char text
[MAX_TEXTLEN
];
546 fgets(text
,MAX_TEXTLEN
,fp
);
550 do_bounding_box(FILE *fp
)
554 struct LineStyle linestyle
;
555 struct FillStyle fillstyle
;
558 /* just fetch the values and store */
559 if(fscanf(fp
,"%d %d %d %d\n", &minx
, &miny
, &maxx
, &maxy
) != 4)
561 fprintf(stderr
,"Error: Invalid bounding box record #%d in %s()\n",
562 records_processed
, __func__
);
571 /* Do not draw the bounding box, only retrieve the min and max values */
573 if (symbol_mode
== 0)
575 color
= GRAPHIC_COLOR
;
576 linestyle
= LINE_DEFAULT
;
577 fillstyle
= FILL_DEFAULT
;
578 box_object(minx
, miny
, maxx
-minx
, maxy
-miny
, color
, &linestyle
,
586 do_unattached_attribute(FILE *fp
)
589 unsigned int dummy
, color
, size
, origin
, viewvis
;
591 unsigned int visibility
, show_name_value
;
592 char text
[MAX_TEXTLEN
], *name
, *value
;
593 struct LineStyle linestyle
;
594 struct FillStyle fillstyle
;
596 /* if we are inside of a pin definition, terminate */
599 /* for the moment just represent as text */
601 /* viewlogic unnatached attributes have this format:
602 * U #X #Y #SIZE #ROTATION #origin #Visibility ATTR_TEXT
604 if(fscanf(fp
,"%d %d %u %d %u %u", &x
, &y
, &size
, &angle
, &origin
,
607 fprintf(stderr
,"Error: Invalid Unattached attribute record #%d "
609 records_processed
, __func__
);
613 /* read in the text */
614 get_continued_string(text
, MAX_TEXTLEN
, fp
);
617 x
*= scale
; /* correct coordinates */
619 color
= DETACHED_ATTRIBUTE_COLOR
;
621 linestyle
= LINE_DEFAULT
;
622 fillstyle
= FILL_DEFAULT
;
623 get_style(fp
, &dummy
, &linestyle
, &fillstyle
);
625 /* evaluate visibility for attributes */
628 case 0: /* not at all visibile */
633 case 1: /* attribute and name visible */
638 case 2: /* only name visible */
643 case 3: /* only value visible */
649 fprintf(stderr
,"Error: Invalid visibility value %d in "
650 "viewlogic file at record #%d in function %s()\n",
651 viewvis
, records_processed
, __func__
);
655 /* find name and value pair */
657 index
= strindex(text
,'=');
658 if (text
[index
] == '=')
661 value
= &text
[index
+1];
668 attribute_object( x
, y
, color
, size
, visibility
, show_name_value
, angle
,
669 name
, value
, origin
);
674 do_attached_attribute(FILE *fp
)
677 unsigned int color
, dummy
, size
, origin
, viewvis
;
678 unsigned int visibility
, show_name_value
;
680 char text
[MAX_TEXTLEN
],text2
[MAX_TEXTLEN
],*name
,*value
;
681 struct LineStyle linestyle
;
682 struct FillStyle fillstyle
;
684 /* for the moment just represent as text */
686 /* attached attributes have the following format:
687 * A #X #Y #SIZE #ROTATION #ORIGIN #VISIBILITY ATTR_TEXT
689 if(fscanf(fp
,"%d %d %u %d %u %u", &x
, &y
, &size
, &angle
, &origin
,
692 fprintf(stderr
,"Error: Invalid attached attribute record #%d"
693 " in %s()\n", records_processed
, __func__
);
697 x
*= scale
; /* correct coordinates */
700 /* read in the text */
701 get_continued_string(text
, MAX_TEXTLEN
, fp
);
703 color
= ATTRIBUTE_COLOR
;
704 linestyle
= LINE_DEFAULT
;
705 fillstyle
= FILL_DEFAULT
;
706 get_style(fp
, &dummy
, &linestyle
, &fillstyle
);
708 /* evaluate visibility for attributes */
711 case 0: /* not at all visibile */
716 case 1: /* attribute and name visible */
721 case 2: /* only name visible */
726 case 3: /* only value visible */
732 fprintf(stderr
,"Error: Invalid visibility value %d in "
733 "viewlogic file at record #%d, in function %s()\n",
734 viewvis
, records_processed
, __func__
);
739 if(pin_attributes
) /* are we adding to a pin ? */
741 /* translate pintype attribute */
742 if (strncmp(text
, "PINTYPE=", 8) == 0)
744 value
= &text
[strindex(text
,'=')+1];
745 if (strcmp(value
, "ANALOG") == 0)
748 snprintf(text
, MAX_TEXTLEN
, "pintype=pas");
750 sprintf(text
, "pintype=pas");
753 else if (strcmp(value
, "BI") == 0)
756 snprintf(text
, MAX_TEXTLEN
, "pintype=io");
758 sprintf(text
, "pintype=io");
761 else if (strcmp(value
, "IN") == 0)
764 snprintf(text
, MAX_TEXTLEN
, "pintype=in");
766 sprintf(text
, "pintype=in");
769 else if (strcmp(value
, "OCL") == 0)
772 snprintf(text
, MAX_TEXTLEN
, "pintype=oc");
774 sprintf(text
, "pintype=oc");
777 else if (strcmp(value
, "OEM") == 0)
780 snprintf(text
, MAX_TEXTLEN
, "pintype=oe");
782 sprintf(text
, "pintype=oe");
785 else if (strcmp(value
, "OUT") == 0)
788 snprintf(text
, MAX_TEXTLEN
, "pintype=out");
790 sprintf(text
, "pintype=out");
793 else if (strcmp(value
, "TRI") == 0)
796 snprintf(text
, MAX_TEXTLEN
, "pintype=tri");
798 sprintf(text
, "pintype=tri");
801 else if (strcmp(value
, "PWR") == 0)
804 snprintf(text
, MAX_TEXTLEN
, "pintype=pwr");
806 sprintf(text
, "pintype=pwr");
811 fprintf(stderr
,"Error: Invalid or unknown pin type \"%s\" for record "
812 "#%d in %s()\n", value
, records_processed
, __func__
);
816 /* find name and value pair */
818 index
= strindex(text
,'=');
820 value
= &text
[index
+1];
821 attribute_object( x
, y
, color
, size
, visibility
, show_name_value
,
822 angle
, name
, value
, origin
);
824 /* done attaching pin attributes */
827 /* attach the pinseq and pinnumber attributes */
830 strncpy(text2
, text
, MAX_TEXTLEN
);
832 snprintf(text
, MAX_TEXTLEN
, "pinseq=%d",pin_count
);
834 sprintf(text
, "pinseq=%d",pin_count
);
836 /* pinseq is invisible */
837 visibility
= 0; /* overide any previous settings */
840 /* find name and value pair */
842 index
= strindex(text
,'=');
844 value
= &text
[index
+1];
845 attribute_object( x
, y
, color
, size
, visibility
, show_name_value
,
846 angle
, name
, value
, origin
);
849 snprintf(text
, MAX_TEXTLEN
, "pinnumber=%s", &text2
[2]);
851 sprintf(text
, "pinnumber=%s", &text2
[2]);
853 /* pinnumber is visible */
854 visibility
= 1; /* overide any previous settings */
858 index
= strindex(text
,'=');
860 value
= &text
[index
+1];
861 attribute_object( x
, y
, color
, size
, visibility
, show_name_value
,
862 angle
, name
, value
, origin
);
864 /* done attaching pin attributes */
870 index
= strindex(text
,'=');
871 if (text
[index
] == '=')
874 value
= &text
[index
+1];
881 attribute_object( x
, y
, color
, size
, visibility
, show_name_value
, angle
,
882 name
, value
, origin
);
889 unsigned int size
, origin
;
890 unsigned int color
, show_name_value
;
891 unsigned int visibility
;
892 char text
[MAX_TEXTLEN
];
893 struct LineStyle linestyle
;
894 struct FillStyle fillstyle
;
897 /* if we are inside of a pin definition, terminate */
900 /* viewlogic text have the following format:
901 * T #X #Y #SIZE #ROTATION #ORIGIN TEXT
903 if(fscanf(fp
,"%d %d %u %d %u",&x
, &y
, &size
, &angle
,
906 fprintf(stderr
,"Error: Invalid text record #%d in %s()\n",
907 records_processed
, __func__
);
912 /* read in the text */
913 get_continued_string(text
, MAX_TEXTLEN
, fp
);
915 x
*= scale
; /* correct coordinates */
921 /* get possible colour change */
922 linestyle
= LINE_DEFAULT
;
923 fillstyle
= FILL_DEFAULT
;
924 get_style(fp
, &color
, &linestyle
, &fillstyle
);
926 text_object(x
, y
, color
, size
, visibility
, show_name_value
, angle
, text
, \
934 int x
[MAX_POINTS
],y
[MAX_POINTS
];
935 unsigned int pairs
,color
,i
;
936 struct LineStyle linestyle
;
937 struct FillStyle fillstyle
;
940 /* if we are inside of a pin definition, terminate */
944 /* the viewlogic line primitive is composed of
945 * l #PAIRS #X1 #Y1 #X2 #Y2 ... - Line
948 if(fscanf(fp
,"%d",&pairs
) != 1)
950 fprintf(stderr
,"Error: Unable to read number of line pairs "
951 "for record #%d, in %s()\n",
952 records_processed
, __func__
);
956 /* scan in all the co-ordinate pairs and pop them into our array */
957 for (i
=0; i
< pairs
; i
++)
959 if(fscanf(fp
,"%d %d", &x
[i
], &y
[i
]) != 2)
961 fprintf(stderr
,"Error: unable to read %dth coodinate pair "
962 "for record #%d, in %s()\n",
963 i
+1, records_processed
, __func__
);
971 /* slurp up trailing CR/NL */
972 if (getc(fp
) == '\r')
975 color
= GRAPHIC_COLOR
;
976 linestyle
= LINE_DEFAULT
;
977 fillstyle
= FILL_DEFAULT
;
978 /* now check for an optional style record */
979 get_style(fp
, &color
, &linestyle
, &fillstyle
);
981 /* now, output the line as a series of geda lines */
982 for(i
=1; i
<pairs
; i
++)
983 line_object(x
[i
-1],y
[i
-1],x
[i
],y
[i
],color
,&linestyle
);
991 unsigned int pindir
, pinsense
, color
;
992 unsigned int bradius
= 25;
993 unsigned int bdiameter
= 2*bradius
;
994 unsigned int bcolor
= LOGIC_BUBBLE_COLOR
;
995 int x1
, y1
, x2
, y2
, bx
, by
, bx1
, by1
, bx2
, by2
;
996 OBJECT_PINTYPE pintype
;
997 unsigned int whichend
;
998 struct LineStyle linestyle
;
999 struct FillStyle fillstyle
;
1001 /* if we are inside of a pin definition, terminate */
1004 /* viewlogic pin primitives have the following format:
1005 * P #PININSTANCE #X1 #Y1 #X2 #Y2 # #PINDIRECTION #PINSENSE
1008 if(fscanf(fp
,"%*d %d %d %d %d %*d %u %u\n",&x1
, &y1
, &x2
, &y2
,
1009 &pindir
, &pinsense
) != 6)
1011 fprintf(stderr
,"Error:Invalid pin record #%d in %s()\n",
1012 records_processed
, __func__
);
1027 /* Determine the 'whichend' parameter and the coordinates for the "bubble" */
1028 /* if we need to use one. We need a "bubble" when pinsense=1. */
1031 case 0: /* Pin on top */
1047 case 1: /* Pin on bottom */
1063 case 2: /* Pin on left */
1079 case 3: /* Pin on right */
1096 /* Invalid pin direction */
1097 fprintf(stderr
,"Error: Invalid pin direction %d in "
1098 "ViewLogic file at record #%d, in function %s()\n",
1099 pindir
, records_processed
, __func__
);
1103 /* if this pin has to be of negative polarity, add a bitty bubble
1104 * and adjust the size of the pin
1113 linestyle
= LINE_DEFAULT
;
1114 fillstyle
= FILL_DEFAULT
;
1116 circle_object(bx
,by
,bradius
,bcolor
,&linestyle
,&fillstyle
);
1119 /* For now, only normal pins are supported */
1120 pintype
= NORMAL_PIN
;
1122 pin_object(x1
,y1
,x2
,y2
,color
,pintype
,whichend
);
1125 add_attributes
= 1; /* add attributes */
1126 attach_pending
= 1; /* signal that an attachment could be coming */
1127 pin_attributes
= 1; /* and that they are pin attributes */
1128 pin_count
++; /* bump the number of pins */
1135 int x1
, y1
, x2
, y2
, width
, height
;
1137 struct LineStyle linestyle
;
1138 struct FillStyle fillstyle
;
1141 /* if we are inside of a pin definition, terminate */
1144 /* a viewlogic box has the following format:
1146 * geda view of a box has the corner, width and height
1148 if(fscanf(fp
, "%d %d %d %d\n", &x1
, &y1
, &x2
, &y2
) != 4)
1150 fprintf(stderr
, "Error: Invalid box record #%d in %s()\n",
1151 records_processed
, __func__
);
1162 color
= GRAPHIC_COLOR
;
1164 linestyle
= LINE_DEFAULT
;
1165 fillstyle
= FILL_DEFAULT
;
1166 get_style(fp
, &color
, &linestyle
, &fillstyle
);
1168 box_object(x1
,y1
,width
,height
,color
,&linestyle
,&fillstyle
);
1175 unsigned int radius
, color
;
1176 struct LineStyle linestyle
;
1177 struct FillStyle fillstyle
;
1179 /* if we are inside of a pin definition, terminate */
1182 /* a circle has the following format:
1185 if(fscanf(fp
,"%d %d %u\n",&x
, &y
, &radius
) != 3)
1187 fprintf(stderr
,"Error: Invalid circle record #%d in %s()\n",
1188 records_processed
, __func__
);
1195 color
= GRAPHIC_COLOR
;
1197 linestyle
= LINE_DEFAULT
;
1198 fillstyle
= FILL_DEFAULT
;
1199 get_style(fp
, &color
, &linestyle
, &fillstyle
);
1201 circle_object(x
,y
,radius
,color
,&linestyle
,&fillstyle
);
1207 int x1
, y1
, x2
, y2
, x3
, y3
;
1209 double x2p
, y2p
, x3p
, y3p
, yop
, xop
, xo
, yo
;
1211 double gstart
, sweep_angle
, start_angle
, end_angle
;
1213 struct LineStyle linestyle
;
1214 struct FillStyle fillstyle
;
1216 /* if we are inside of a pin definition, terminate */
1219 /* arcs have the following format:
1220 * a #X1 #Y1 #X2 #Y2 #X3 #Y3
1221 * we need to transform this into the geda convention of
1222 * center, radius, start angle, stop angle.
1225 if(fscanf(fp
,"%d %d %d %d %d %d\n",
1226 &x1
, &y1
, &x2
, &y2
, &x3
, &y3
) != 6)
1228 fprintf(stderr
,"Error: Invalid arc record #%d, in %s()\n",
1229 records_processed
, __func__
);
1239 color
= GRAPHIC_COLOR
;
1240 linestyle
= LINE_DEFAULT
;
1241 fillstyle
= FILL_DEFAULT
;
1242 get_style(fp
, &color
, &linestyle
, &fillstyle
);
1250 /* printf("Buffer: `%s'\n",buf);
1251 * printf("Values: x2p: %f, y2p: %f, x3p: %f, y3p: %f\n",x2p, y2p, x3p, y3p);
1253 if(fabs(x2p
* y3p
- y2p
* x3p
) < 0.00001)
1255 /* some miscreant entered a degenerate arc, just output lines */
1256 line_object(x1
,y1
,x2
,y2
,color
,&linestyle
);
1257 line_object(x2
,y2
,x3
,y3
,color
,&linestyle
);
1261 yop
= ((x2p
* ( x3p
*x3p
+ y3p
*y3p
) - x3p
* ( x2p
*x2p
+ y2p
*y2p
)) /
1262 (2 * (x2p
* y3p
- y2p
* x3p
)));
1264 xop
= (x2p
*x2p
- 2*y2p
*yop
) / (2 * x2p
);
1270 radius
= sqrt(xop
*xop
+ yop
*yop
);
1272 /* calculate start and end angles */
1273 to_rad
= 180.0/atan2(0,-1);
1274 start_angle
= atan2(y1
-yo
, x1
-xo
) * to_rad
;
1275 end_angle
= atan2(y3
-yo
, x3
-xo
) * to_rad
;
1277 if(start_angle
> end_angle
)
1280 sweep_angle
= start_angle
- end_angle
;
1284 gstart
= start_angle
;
1285 sweep_angle
= end_angle
- start_angle
;
1289 * end_angle = int(atan2(y1-yo, x1-xo) * to_rad) % 360;
1290 * start_angle = int(atan2(y3-yo, x3-xo) * to_rad) % 360;
1294 arc_object((int)xo
,(int)yo
, (unsigned int)radius
,
1295 (int)gstart
,(int)sweep_angle
, color
, &linestyle
);
1302 int x
, y
, angle
, global
, overbar
;
1303 unsigned int color
, size
, origin
, visibility
, show_name_value
;
1304 char text
[MAX_TEXTLEN
];
1305 char text2
[MAX_TEXTLEN
];
1306 struct LineStyle linestyle
;
1307 struct FillStyle fillstyle
;
1310 /* labels have the following format:
1311 * L #X #Y #SIZE #ROTATION #ORIGIN #GLOBAL #VISIBILITY #OVERBAR TEXT
1314 /* reproduce as simple text, unless it is a label for an object */
1316 if(fscanf(fp
, "%d %d %u %d %d %d %d %d", &x
, &y
, &size
, &angle
, &origin
,
1317 &global
, &visibility
, &overbar
) != 8)
1319 fprintf(stderr
,"Error: Invalid label record #%d in %s()\n",
1320 records_processed
, __func__
);
1326 color
= ATTRIBUTE_COLOR
;
1327 show_name_value
= 0;
1329 /* read in the text */
1330 get_continued_string(text2
, MAX_TEXTLEN
, fp
);
1332 /* if ViewDraw showed the label with an overbar, append a '~' to the */
1333 /* beginning of the name. gEDA does not support overbars, so the '~' lets */
1334 /* the designer know he's dealing with an active low signal */
1337 length
= strlen(text2
);
1338 text2
[length
+ 1] = 0;
1339 for (i
= length
; i
> 0; i
--)
1340 text2
[i
] = text2
[i
- 1];
1344 linestyle
= LINE_DEFAULT
;
1345 fillstyle
= FILL_DEFAULT
;
1346 get_style(fp
, &color
, &linestyle
, &fillstyle
);
1348 /* if we are inside a pin definition, mangle the pin name */
1349 if(net_attributes
== 1) /* a netname on a net is its netname */
1351 #ifdef HAVE_SNPRINTF
1352 snprintf(text
, MAX_TEXTLEN
, "netname=%s", text2
);
1354 sprintf(text
, "netname=%s", text2
);
1356 show_name_value
= 1;
1359 else if(complex_attributes
== 1) /* a label on a complex is its designator */
1361 #ifdef HAVE_SNPRINTF
1362 snprintf(text
, MAX_TEXTLEN
, "refdes=%s", text2
);
1364 sprintf(text
, "refdes=%s", text2
);
1366 show_name_value
= 1;
1368 else if(pin_attributes
== 1) /* a label on a pin is it's pinname */
1370 #ifdef HAVE_SNPRINTF
1371 snprintf(text
, MAX_TEXTLEN
, "pinlabel=%s", text2
);
1373 sprintf(text
, "pinlabel=%s", text2
);
1375 show_name_value
= 1;
1378 strcpy(text
,text2
); /* don't need to do anything, just copy */
1381 text_object(x
, y
, color
, size
, visibility
, show_name_value
, angle
, text
, \
1385 /* four functions for doing net stuff */
1387 do_net_start(FILE *fp
)
1391 fscanf(fp
,"%*d\n"); /* just dispose of the net instance number */
1398 do_net_node(FILE *fp
)
1402 /* in geda nets are composed of a number of segments, gschem connects
1403 * them together on the screen, since viewlogic stores a net as a series
1404 * of nodes we need to tabulate them and only output segments when we
1405 * get connectivity information
1407 * net segments have the following format:
1408 * J #X #Y #SEGNUM - Net segment
1411 if(segment_count
> MAX_NODES
)
1413 fprintf(stderr
,"Error: too many nodes on a net at record #%d, "
1414 "in %s(), try increasing\n"
1415 "\tMAX_NODES\n", records_processed
, __func__
);
1416 exit(1); /* this is fatal */
1419 /* get the current info */
1420 if(fscanf(fp
,"%d %d %d\n",&x
, &y
, &type
) < 2)
1422 fprintf(stderr
,"Error: Invalid net node record #%d in %s()\n",
1423 records_processed
, __func__
);
1430 net_nodes_x
[segment_count
] = x
;
1431 net_nodes_y
[segment_count
] = y
;
1438 do_net_segment(FILE *fp
)
1440 unsigned int n1
, n2
, color
;
1444 /* net segment connectivity records have the following format:
1445 * S #N1 #N2 - Net connectivity, Node N1 is connected to N2
1448 if(fscanf(fp
,"%u %u\n",&n1
, &n2
) != 2)
1450 fprintf(stderr
,"Error: Invalid net segment record #%d in %s()\n",
1451 records_processed
, __func__
);
1457 /* output a geda net segment */
1458 net_segment(net_nodes_x
[n1
], net_nodes_y
[n1
],
1459 net_nodes_x
[n2
], net_nodes_y
[n2
], color
);
1461 /* there could be attributes to follow */
1462 add_attributes
= 1; /* add attributes */
1463 attach_pending
= 1; /* signal that an attachment could be coming */
1464 net_attributes
= 1; /* and that they are net attributes */
1468 do_net_segment_bus(FILE *fp
)
1470 unsigned int n1
, n2
, color
;
1475 /* bus net segment connectivity records have the following format:
1476 * B #N1 #N2 - Net connectivity, Node N1 is bussed to N2
1479 if(fscanf(fp
,"%u %u\n",&n1
, &n2
) != 2)
1481 fprintf(stderr
,"Error: Invalid bus segment record #%d in %s()\n",
1482 records_processed
, __func__
);
1488 /* For now, we'll use ripperdir=0 (no nets connected to bus yet) */
1491 /* output a geda bus segment */
1492 bus_segment(net_nodes_x
[n1
], net_nodes_y
[n1
],
1493 net_nodes_x
[n2
], net_nodes_y
[n2
], color
, ripperdir
);
1495 /* there could be attributes to follow */
1496 add_attributes
= 1; /* add attributes */
1497 attach_pending
= 1; /* signal that an attachment could be coming */
1498 net_attributes
= 1; /* and that they are net attributes */
1502 do_instance(FILE *fp
)
1504 char text
[MAX_TEXTLEN
];
1505 char lib
[MAX_TEXTLEN
], name
[MAX_TEXTLEN
], symName
[MAX_TEXTLEN
];
1506 unsigned int extension
, selectable
;
1507 int x
, y
, angle
, orientation
, mirror
;
1509 int result
, index
, i
;
1513 /* a component instance has the following format
1514 * I #instance LIB:NAME #PAGE #X #Y #ROTATION #MAGNIFICATION '
1524 /* Instance doesn't necessarily have to have the LIB:NAME convention, so */
1525 /* read this in as a full string and parse later */
1526 /* if(fscanf(fp,"%*d %[a-zA-Z0-9]:%[a-zA-Z0-9] %u %d %d %d %g %*s\n", */
1527 result
= fscanf(fp
,"%*d %s %u %d %d %d %g %*s\n",
1528 text
, &extension
, &x
, &y
, &orientation
, &scale_factor
);
1529 /* find library and symbol name */
1530 index
= strindex(text
, ':');
1531 if (index
> 0 || text
[0] == ':')
1535 strcpy(name
, &text
[index
+1]);
1539 /* Check for input errors */
1542 fprintf(stderr
,"Error: Invalid instance record #%d in %s()\n"
1543 "lib:'%s', name:'%s'\n"
1544 "extension:%d, x:%d, y:%d\n",
1545 records_processed
, __func__
, lib
,name
,extension
, x
, y
);
1552 /* ViewDraw components are always selectable */
1555 /* Correct orientation */
1556 set_orientation(&angle
, &mirror
, orientation
);
1561 /* replace dashes in the name with underscores */
1562 for (i
= strlen(name
) - 1; i
>= 0; i
--)
1566 /* produce proper file name: */
1567 #ifdef HAVE_SNPRINTF
1568 snprintf(symName
, MAX_TEXTLEN
, "%s-%d.sym",name
,extension
);
1570 sprintf(symName
, "%s-%d.sym",name
,extension
);
1573 complex_object(x
, y
, selectable
, angle
, mirror
, symName
);
1575 /* there could be attributes to follow */
1576 add_attributes
= 1; /* add attributes */
1577 attach_pending
= 1; /* signal that an attachment could be coming */
1578 complex_attributes
= 1; /* and that they are complex attributes */
1582 /* ViewDraw mirrors components over the x-axis, but gSchem mirrors over the */
1584 /* This makes (270, 1) viewlogic -> (90, 1) gschem */
1585 /* and (90, 1) viewlogic -> (270, 1) gschem */
1586 /* and (180, 1) viewlogic -> (0, 1) gschem */
1587 /* and (0, 1) viewlogic -> (180, 1) gschem */
1589 set_orientation(int *angle
, int *mirror
, int orientation
)
1591 switch (orientation
) {
1592 case 0: /* 0 rotation, 0 mirror */
1596 case 1: /* 90 rotation, 0 mirror */
1600 case 2: /* 180 rotation, 0 mirror */
1604 case 3: /* 270 rotation, 0 mirror */
1608 case 4: /* 180 rotation, 1 mirror */
1612 case 5: /* 90 rotation, 1 mirror */
1616 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 snprintf(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 */