4 olib.lex - Orcad to gEDA lib converter
5 Copyright (C) 2002 Mario Pascucci <m.pas@libero.it>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 visit the URL http://www.fsf.org/
33 /* gEDA file version: change NEW version as soon as available */
34 #define EDA_VERSION_OLD "20020209"
35 #define EDA_VERSION_NEW "20020825"
38 /* defines for flags and types */
39 #define PIN_DOTFLAG 0x0001
40 #define PIN_SHORTFLAG 0x0002
41 #define PIN_CLKFLAG 0x0004
45 #define PIN_TYPE_OUT 3
46 #define PIN_TYPE_PWR 4
47 #define PIN_TYPE_PAS 5
49 #define PIN_TYPE_HIZ 7
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
63 static const ATTRIBUTE_UNUSED char *mp_name = "OrCAD to gEDA lib converter";
64 static const ATTRIBUTE_UNUSED char *mp_license = "Copyright (c) 2002 Mario Pascucci <m.pas@libero.it>";
66 static char fnsym[512]; /* gEDA symbol file name */
67 static FILE *fsym; /* FILE* to gEDA symbol file */
68 static int aliascount = 0; /* alias count */
69 static char part_aliases[200][50]; /* store for aliases of part */
70 static char sym_prefix[50]; /* prefix for .sym file */
72 /* gEDA symbol file version */
73 static char sym_version[10];
74 static int use_old_version; /* flag for old format */
76 /* pin name options */
77 static int pin_name_hidden;
79 static char buff[512];
81 static int sizex,sizey,partspp; /* size and number of part per package */
83 static int pincount; /* pin definitions found until now */
85 struct pin_def { /* pin definition struct */
86 char pos; /* position: L,T,R,B */
87 short num; /* number in side, 0 mean virtual pin */
88 short pin; /* real pin number */
89 short flags; /* DOT, CLK and SHORT flags */
90 short type; /* I/O, IN, OUT, PWR, PASS, OC */
91 char name[50]; /* simbolic name of pin */
95 /* REFERENCE handling */
96 static char ref_str[20];
100 static int vector_count; /* number of vector found */
103 char type; /* line, arc, circle, box */
104 float p[12]; /* parameters for element drawing */
105 char *str; /* string for "TEXT" statement */
108 static int paramcount; /* vector param number count */
110 static struct vector_def part_vectors[100]; /* draw list */
112 static int vector_found;
116 static char *pintypestr[] = {
129 static char *edapintype[] = {
142 /* pin definition database */
143 static struct pin_def pinlist[200];
146 /* generic counter */
151 /* strip filename-aware chars from part name,
152 leave only '.' '-' or '_' and changes space
154 char *strip_invalid(char *str)
161 if (isalnum((int) *str) || strchr("-_. ",*str))
176 /* trim leading and trailing ' in ident */
177 char *strip_quotes(char *str)
195 /* symbol write function in gEDA .sym format */
196 #include "geda_sym_format.h"
203 /* decimal integer */
206 /* floating point decimal, like 123.234 */
207 DECIMAL [+-]?[0-9]*[\.][0-9]*
209 /* string name, like 'abcd' */
212 /* comment, like { comment } */
215 /* pin identifier, example T3 L12 R3 .... */
216 PIN_ID [TBLR][0-9]{1,4}
220 %s wait_END wait_sizex wait_sizey wait_parts pin_list pinrealnum pindata
221 %s waitnamestart in_name waitnameend waitpinend vector_list vector_ignore
222 %s param_list convert convert_ignore_pin reference
228 /*******************************************
236 *******************************************/
240 /* ignore comments */
241 fprintf(stderr,"Ignore comment: %s\n",yytext);
246 /* shortcuts for parts name: ignored */
247 fprintf(stderr,"Found PREFIX\n");
252 <wait_END>^{IDENT}.*\n {
253 fprintf(stderr,"Shorthand found, ignored\n");
254 /* ignore shortcut list */
259 /* founds shortcut list end */
260 fprintf(stderr,"Found END for shorthands\n");
266 /*******************************************
271 *******************************************/
275 /* founds first part identifier */
276 strcpy(part_aliases[0],strip_invalid(yytext));
277 snprintf(fnsym,511,"%s-%s-1.sym",sym_prefix,part_aliases[0]);
278 fprintf(stderr,"New part name: %s (%s)\n",part_aliases[0],yytext);
279 fprintf(stderr,"New .sym name: %s\n",fnsym);
289 <wait_sizex>^REFERENCE {
290 /* REFERENCE statement found */
296 /* get an IDENT, i.e. reference id */
297 strcpy(ref_str,strip_quotes(yytext));
298 fprintf(stderr,"REFERENCE: %s\n",yytext);
303 <wait_sizex>^{IDENT} {
304 /* found an alias for the part name
305 store alias for future use */
306 fprintf(stderr,"Found an alias: %s\n",yytext);
307 strcpy(part_aliases[aliascount], strip_invalid(yytext));
313 /*******************************************
315 {X Size =} x {Y Size =} y {Parts per Package =} n
316 *******************************************/
319 <wait_sizex>{INTEGER} {
320 /* trovata la dimansione X */
321 sizex = atoi(yytext);
322 fprintf(stderr,"Found X size: %d (%s)\n",sizex,yytext);
327 <wait_sizey>{INTEGER} {
328 /* trovata la dimansione y */
329 sizey = atoi(yytext);
330 fprintf(stderr,"Found Y size: %d (%s)\n",sizey,yytext);
335 <wait_parts>GRIDARRAY {
336 /* found a PGA component, unsupported */
337 fprintf(stderr,"Found a GRIDARRAY: unsupported\n");
342 <wait_parts>{INTEGER} {
343 /* trovato il parts-per-package */
344 /* per ora supportato solo 1 part-per-package */
345 partspp = atoi(yytext);
348 fprintf(stderr,"Found parts per package > 1\n");
353 fprintf(stderr,"Found parts per package: %d (%s)\n",partspp,yytext);
355 /* size of symbol body */
356 sizex = sizex * PIN_SPACE;
357 sizey = sizey * PIN_SPACE;
362 <INITIAL>^{PIN_ID}.+\n |
363 <INITIAL>^VECTOR.*\n |
364 <INITIAL>^CONVERT.*\n |
369 <INITIAL>^CIRCLE.*\n |
372 fprintf(stderr,"Ignored: %s",yytext);
377 /*******************************************
379 VECTOR 'IDENT' (unsupported)
383 ARC x y dxs dys dxe dye r
385 FILL x y (unsupported)
386 TEXT x y size 'text' (partially supported)
388 *******************************************/
392 /* components isn't a simple "box", but it's drawed */
396 fprintf(stderr,"Found: VECTOR\n");
400 <vector_list,vector_ignore>{IDENT} {
401 /* the component shape is identical to a previous one
402 unsupported at the moment */
404 fprintf(stderr,"Found unsupported: VECTOR 'IDENT'\n");
409 /* found LINE vector statement */
410 part_vectors[vector_count].type = 'L';
413 fprintf(stderr,"Found: LINE params:");
417 <vector_list>CIRCLE {
418 /* found CIRCLE vector statement */
419 part_vectors[vector_count].type = 'V';
422 fprintf(stderr,"Found: CIRCLE params:");
427 /* found ARC vector statement */
428 part_vectors[vector_count].type = 'A';
431 fprintf(stderr,"Found: ARC params:");
436 /* found FILL vector statement */
437 /* no counterpart in gEDA */
438 part_vectors[vector_count].type = 'f';
441 fprintf(stderr,"Found unsupported: FILL params:");
446 /* found ARC vector statement */
447 part_vectors[vector_count].type = 'T';
450 fprintf(stderr,"Found: TEXT params:");
454 <param_list>{INTEGER} {
456 part_vectors[vector_count].p[paramcount] = (float) atof(yytext);
459 fprintf(stderr," %s",yytext);
463 <param_list>{DECIMAL} {
465 part_vectors[vector_count].p[paramcount] = (float) atof(yytext);
468 fprintf(stderr," %s",yytext);
472 <param_list>{IDENT} {
474 if (part_vectors[vector_count].type == 'T')
475 part_vectors[vector_count].str = strdup(strip_quotes(yytext));
477 fprintf(stderr,"Text param found in non text VECTOR instr: %s\n",yytext);
480 fprintf(stderr," %s",yytext);
486 fprintf(stderr,"\n");
487 switch (part_vectors[vector_count].type)
493 fprintf(stderr,"LINE: wrong parameters number: %d\n",paramcount);
501 fprintf(stderr,"CIRCLE: wrong parameters number: %d\n",paramcount);
509 fprintf(stderr,"ARC: wrong parameters number: %d\n",paramcount);
517 fprintf(stderr,"FILL: wrong parameters number: %d\n",paramcount);
525 fprintf(stderr,"TEXT: wrong parameters number: %d\n",paramcount);
536 /* end of vector list */
538 fprintf(stderr,"Found: END of VECTOR list\n");
543 /*******************************************
551 *******************************************/
554 <pin_list,convert>^CONVERT {
555 /* alternate part drawing */
562 /* CONVERT 'part' unsupported */
568 /* ignore PIN list in CONVERT */
569 BEGIN(convert_ignore_pin);
573 <convert_ignore_pin>.*\n {
580 /* found VECTOR list in CONVERT */
582 BEGIN(vector_ignore);
592 <vector_ignore>^END.*\n {
596 <vector_ignore>^VECTOR.*\n |
597 <vector_ignore>^CONVERT.*\n |
598 <vector_ignore>^TEXT.*\n |
599 <vector_ignore>^LINE.*\n |
600 <vector_ignore>^ARC.*\n |
601 <vector_ignore>^FILL.*\n |
602 <vector_ignore>^CIRCLE.*\n {
604 fprintf(stderr,"Ignored VECTOR: %s",yytext);
609 /*******************************************
614 *******************************************/
617 <pin_list>^{PIN_ID} {
619 pinlist[pincount].pos = yytext[0]; /* pin side */
620 pinlist[pincount].num = atoi(yytext+1); /* gets pin number */
621 pinlist[pincount].flags = 0;
622 pinlist[pincount].type = 0;
623 fprintf(stderr,"Found pin ID: %c-%d (%s)\n",pinlist[pincount].pos,pinlist[pincount].num,yytext);
624 if (partspp == 0) /* handling of parts without pin number */
626 /* assign number to a unnumbered pin from the pin count */
627 pinlist[pincount].pin = pincount + 1;
636 /* found a part name after pinlist, this mean that part definition ends,
637 and starts a new part definition */
638 fprintf(stderr,"Writing down new symbol: %s pin: %d vectors: %d\n",part_aliases[0],pincount,vector_count);
639 write_sym(); /* write the .sym gEDA symbol definition */
640 /* restore initial condition */
647 strcpy(part_aliases[0],strip_invalid(yytext));
648 snprintf(fnsym,511,"%s-%s-1.sym",sym_prefix,part_aliases[0]);
649 fprintf(stderr,"New part name: %s (%s)\n",part_aliases[0],yytext);
650 fprintf(stderr,"New .sym name: %s\n",fnsym);
656 <pinrealnum>{INTEGER} {
657 /* reads real pin number */
658 pinlist[pincount].pin = atoi(yytext);
659 fprintf(stderr,"Found pin num: %d (%s)\n",pinlist[pincount].pin,yytext);
665 /* DOT flag found, boolean negate */
666 pinlist[pincount].flags |= PIN_DOTFLAG;
667 fprintf(stderr,"Found DOT flag\n");
672 /* CLK flag found, clock input */
673 pinlist[pincount].flags |= PIN_CLKFLAG;
674 fprintf(stderr,"Found CLK flag\n");
679 /* SHORT flag found, short terminal */
680 pinlist[pincount].flags |= PIN_SHORTFLAG;
681 fprintf(stderr,"Found SHORT flag\n");
687 pinlist[pincount].type = PIN_TYPE_IN;
688 BEGIN(waitnamestart);
689 fprintf(stderr,"Pin type IN\n");
695 pinlist[pincount].type = PIN_TYPE_OUT;
696 BEGIN(waitnamestart);
697 fprintf(stderr,"Pin type OUT\n");
703 pinlist[pincount].type = PIN_TYPE_PWR;
704 BEGIN(waitnamestart);
705 fprintf(stderr,"Pin type PWR\n");
711 pinlist[pincount].type = PIN_TYPE_OC;
712 BEGIN(waitnamestart);
713 fprintf(stderr,"Pin type OC\n");
719 pinlist[pincount].type = PIN_TYPE_OE;
720 BEGIN(waitnamestart);
721 fprintf(stderr,"Pin type OE\n");
727 pinlist[pincount].type = PIN_TYPE_PAS;
728 BEGIN(waitnamestart);
729 fprintf(stderr,"Pin type PAS\n");
735 pinlist[pincount].type = PIN_TYPE_HIZ;
736 BEGIN(waitnamestart);
737 fprintf(stderr,"Pin type hiZ\n");
743 pinlist[pincount].type = PIN_TYPE_IO;
744 BEGIN(waitnamestart);
745 fprintf(stderr,"Pin type I/O\n");
750 /* found initial quote */
757 /* found a ' in pin name */
758 pinlist[pincount].name[ii++] = '\'';
763 /* get a char from the pin symbolic name */
764 pinlist[pincount].name[ii++] = *yytext;
769 /* all ok, waiting for new pin definition */
770 pinlist[pincount].name[ii] = 0;
771 fprintf(stderr,"Pin label: %s\n",pinlist[pincount].name);
777 /* ok, found a newline, pin definition ends */
778 fprintf(stderr,"Pin: %c%d %d %x %s %s\n",pinlist[pincount].pos,pinlist[pincount].num,
779 pinlist[pincount].pin, pinlist[pincount].flags, pintypestr[pinlist[pincount].type],
780 pinlist[pincount].name);
788 * we don't need to use <*> to match any state, we just don't
793 ^\n { /* empty lines ignored */ }
796 [ \t\n\r] { /* ignored, the \r char is for "DOS" ASCII files */ }
807 fprintf(stderr,"Usage:\n");
808 fprintf(stderr,"\tolib [options] libname prefix\n");
809 fprintf(stderr,"\nWhere:\n\tlibname is the path to OrCAD(TM) library to convert\n");
810 fprintf(stderr,"\tprefix is the prefix for the .sym files extracted\n");
811 fprintf(stderr,"Options are:\n\t-h\tprint this help and exit\n");
812 fprintf(stderr,"\t-o\tuse old format (v 20020209) for .sym file\n");
813 fprintf(stderr,"\t\telse use 'v 20020825' as version string in .sym file\n");
814 fprintf(stderr,"\t-n\thides pin name if symbol is VECTOR drawed\n");
819 /* found a part name after pinlist, this mean that part definition ends,
820 and starts a new part definition */
821 fprintf(stderr,"Writing down new symbol: %s pin: %d vectors: %d\n",part_aliases[0],pincount,vector_count);
822 write_sym(); /* write the .sym gEDA symbol definition */
823 /* restore initial condition */
824 fprintf(stderr,"End of lib file\n");
830 int main (int argc, char *argv[])
834 char fnlib[PATH_MAX];
837 strcpy(sym_version,EDA_VERSION_NEW); /* handle new gEDA version by default */
838 use_old_version = 0; /* old version flag */
839 pin_name_hidden = 0; /* hides pin name on VECTOR drawed symbols */
840 opterr = 0; /* do NOT print default error message for getopt */
843 i = getopt(argc,argv,"hon");
850 strcpy(sym_version,EDA_VERSION_OLD);
851 fprintf(stderr,"Use old (%s) format.\n",sym_version);
852 use_old_version = -1;
855 pin_name_hidden = -1;
858 fprintf(stderr,"Unknown or illegal option :%c\n",(char)optopt);
862 fprintf(stderr,"Parameter wrong for option: %c\n",(char)optopt);
868 if ((argc - optind) != 2)
870 fprintf(stderr,"Library name and prefix are mandatory.\n");
874 strcpy(fnlib,argv[optind]);
875 if (!(flib = fopen(fnlib,"r")))
880 strcpy(sym_prefix,argv[optind+1]);