5 * PCB, interactive printed circuit board design
6 * Copyright (C) 1994,1995,1996,2006 Thomas Nau
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * Contact addresses for paper mail and Email:
23 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
24 * Thomas.Nau@rz.uni-ulm.de
28 /* lexical definitions to parse ASCII input of PCB and Element description
39 #if defined(_POSIX_SOURCE) || defined(_HPUX_SOURCE)
45 #ifdef HAVE_LIBDMALLOC
46 # include <dmalloc.h> /* see http://dmalloc.com */
50 #include "crosshair.h"
63 /* ---------------------------------------------------------------------------
64 * some shared parser identifiers
68 #define yyunput ATTRIBUTE_UNUSED yyunput
71 char *yyfilename; /* in this file */
72 PCBType *yyPCB; /* used by parser */
74 ElementType *yyElement;
77 static int parse_number (void);
79 /* ---------------------------------------------------------------------------
80 * an external prototypes
84 /* ---------------------------------------------------------------------------
85 * some local prototypes
87 static int Parse(char *, char *, char *, char *);
92 INTEGER [+-]?([1-9][0-9]*|0)
93 FLOATING {INTEGER}?"."[0-9]*
94 STRINGCHAR ([^"\n\r\\]|\\.)
100 FileVersion { return(T_FILEVERSION); }
101 PCB { return(T_PCB); }
102 Grid { return(T_GRID); }
103 Cursor { return(T_CURSOR); }
104 Thermal { return(T_THERMAL); }
105 PolyArea { return(T_AREA); }
106 DRC { return(T_DRC); }
107 Flags { return(T_FLAGS); }
108 Layer { return(T_LAYER); }
109 Pin { return(T_PIN); }
110 Pad { return(T_PAD); }
111 Via { return(T_VIA); }
112 Line { return(T_LINE); }
113 Rat { return(T_RAT); }
114 Rectangle { return(T_RECTANGLE); }
115 Text { return(T_TEXT); }
116 ElementLine { return(T_ELEMENTLINE); }
117 ElementArc { return(T_ELEMENTARC); }
118 Element { return(T_ELEMENT); }
119 SymbolLine { return(T_SYMBOLLINE); }
120 Symbol { return(T_SYMBOL); }
121 Mark { return(T_MARK); }
122 Groups { return(T_GROUPS); }
123 Styles { return(T_STYLES); }
124 Polygon { return(T_POLYGON); }
125 Hole { return(T_POLYGON_HOLE); }
126 Arc { return(T_ARC); }
127 NetList { return(T_NETLIST); }
128 Net { return(T_NET); }
129 Connect { return(T_CONN); }
130 Attribute { return(T_ATTRIBUTE); }
137 umil { return T_UMIL; }
138 cmil { return T_CMIL; }
139 mil { return T_MIL; }
144 yylval.integer = (unsigned) *(yytext+1);
147 {FLOATING} { return parse_number(); }
148 {INTEGER} { yylval.integer = round (g_ascii_strtod (yytext, NULL)); return INTEGER; }
151 sscanf((char *) yytext, "%x", &n);
158 /* return NULL on empty string */
161 yylval.string = NULL;
165 /* allocate memory and copy string;
166 * stringlength is counted and copied without
167 * leading and trailing '"'
170 yylval.string = (char *)calloc (yyleng+1, sizeof (char));
171 p1 = (char *) (yytext +1);
175 /* check for special character */
195 . { return(*yytext); }
199 /* ---------------------------------------------------------------------------
200 * sets up the preprocessor command
202 static int Parse(char *Executable, char *Path, char *Filename, char *Parameter)
204 static char *command = NULL;
210 static bool firsttime = true;
213 if (EMPTY_STRING_P (Executable))
219 l += strlen (Filename);
221 if ( (tmps = (char *) malloc ( l * sizeof (char))) == NULL)
223 fprintf (stderr, "Parse(): malloc failed\n");
227 if ( Path != NULL && *Path != '\0')
228 sprintf (tmps, "%s%s%s", Path, PCB_DIR_SEPARATOR_S, Filename);
230 sprintf (tmps, "%s", Filename);
232 yyin = fopen (tmps, "r");
235 /* Special case this one, we get it all the time... */
236 if (strcmp (tmps, "./default_font"))
237 Message("Can't open %s for reading\n", tmps);
245 /* release old command and create new from template */
247 command = EvaluateFilename(Executable, Path, Filename, Parameter);
249 /* open pipe to stdout of command */
250 if (*command == '\0' || (yyin = popen(command, "r")) == NULL)
252 PopenErrorMessage(command);
258 /* reset parser if not called the first time */
264 /* init linenumber and filename for yyerror() */
266 yyfilename = Filename;
268 /* We need to save the data temporarily because lex-yacc are able
269 * to break the application if the input file has an illegal format.
270 * It's not necessary if the system supports the call of functions
274 CreateBeLenient (true);
276 #if !defined(HAS_ATEXIT) && !defined(HAS_ON_EXIT)
277 if (PCB && PCB->Data)
279 returncode = yyparse();
282 returncode = yyparse();
284 /* clean up parse buffer */
285 yy_delete_buffer(YY_CURRENT_BUFFER);
287 CreateBeLenient (false);
290 return(pclose(yyin) ? 1 : returncode);
291 return(fclose(yyin) ? 1 : returncode);
294 /* ---------------------------------------------------------------------------
295 * initializes LEX and calls parser for a single element file
298 ParseElementFile (DataType *Ptr, char *Filename)
304 return(Parse(NULL,NULL,Filename,NULL));
307 /* ---------------------------------------------------------------------------
308 * initializes LEX and calls parser for a single library entry
311 ParseLibraryEntry (DataType *Ptr, char *Template)
317 return(Parse(Settings.LibraryCommand, Settings.LibraryPath,
318 Settings.LibraryFilename, Template));
321 /* ---------------------------------------------------------------------------
322 * initializes LEX and calls parser for a complete board
325 ParsePCB (PCBType *Ptr, char *Filename)
331 return(Parse(Settings.FileCommand, Settings.FilePath, Filename, NULL));
334 /* ---------------------------------------------------------------------------
335 * initializes LEX and calls parser for a font
338 ParseFont (FontType *Ptr, char *Filename)
346 path = strdup (Settings.FontPath);
348 /* search through the font path for a font file */
349 for (p = strtok (path, PCB_PATH_DELIMETER); p && *p;
350 p = strtok (NULL, PCB_PATH_DELIMETER))
353 Message ("Looking for %s in %s\n", Filename, p);
355 r = Parse(Settings.FontCommand, p, Filename, NULL);
359 Message ("Found %s in %s\n", Filename, p);
372 yylval.number = g_ascii_strtod ((gchar *) yytext, NULL);