Index: trunk/config.auto.h.in =================================================================== --- trunk/config.auto.h.in (revision 289) +++ trunk/config.auto.h.in (revision 290) @@ -289,6 +289,17 @@ ":"\ PCB_PREFIX "/share/pcb/pcblib-newlib" +#define PCB_FP_PATH \ + "." \ + ":" \ + "./pcblib"\ + ":" \ + "./footprints"\ + ":" \ + PCB_PREFIX "/share/pcb/pcblib-file"\ + ":"\ + PCB_PREFIX "/share/pcb/pcblib-param" + #define BINDIR PCB_PREFIX "/bin" /* Relative path from bindir to exec_prefix */ Index: trunk/doc-rnd/TODO =================================================================== --- trunk/doc-rnd/TODO (revision 289) +++ trunk/doc-rnd/TODO (revision 290) @@ -1,3 +1,5 @@ +- check S_ISLNK() from config and fix the code! + - distorted square pin bugs: - rtree assert failure when NDEBUG is turned off - large clearance with octagon Index: trunk/src/buffer.c =================================================================== --- trunk/src/buffer.c (revision 289) +++ trunk/src/buffer.c (revision 290) @@ -499,7 +499,7 @@ ClearBuffer (Buffer); if (FromFile) { - if (!ParseElementFile (Buffer->Data, Name)) + if (!ParseElement (Buffer->Data, Name)) { if (Settings.ShowSolderSide) SwapBuffer (Buffer); @@ -520,7 +520,7 @@ } else { - if (!ParseLibraryEntry (Buffer->Data, Name) + if (!ParseElement(Buffer->Data, Name) && Buffer->Data->ElementN != 0) { element = Buffer->Data->Element->data; Index: trunk/src/libpcb_fp.c =================================================================== --- trunk/src/libpcb_fp.c (revision 289) +++ trunk/src/libpcb_fp.c (revision 290) @@ -258,3 +258,76 @@ ChdirErrorMessage(olddir); return n_footprints; } + +int pcb_fp_dupname(const char *name, char **basename, char **params) +{ + char *newname, *s; + + *basename = newname = strdup(name); + s = strchr(newname, '('); + if (s == NULL) { + *params = NULL; + return 0; + } + + /* split at '(' */ + *s = '\0'; + *params = s+1; + s = *params + strlen(*params)-1; + + /* strip ')' */ + if (*s == ')') + *s = '\0'; + + return 1; +} + +char *pcb_fp_search(const char *search_path, const char *basename, int parametric) +{ + if ((*basename == '/') || (*basename == PCB_DIR_SEPARATOR_C)) + return strdup(basename); +#warning TODO + abort(); +} + +FILE *pcb_fp_fopen(const char *libshell, const char *path, const char *name, int *is_parametric) +{ + char *basename, *params, *fullname; + FILE *f = NULL; + + *is_parametric = pcb_fp_dupname(name, &basename, ¶ms); + if (basename == NULL) + return NULL; + + fullname = pcb_fp_search(path, basename, *is_parametric); + + printf("pcb_fp_fopen: %d '%s' '%s' fullname='%s'\n", *is_parametric, basename, params, fullname); + + if (fullname != NULL) { + if (*is_parametric) { + char *cmd, *sep = " "; + if (libshell == NULL) { + libshell = ""; + sep = ""; + } + cmd = malloc(strlen(libshell) + strlen(fullname) + strlen(params) + 16); + sprintf(cmd, "%s%s%s %s", libshell, sep, fullname, params); + f = popen(cmd, "r"); + free(cmd); + } + else + f = fopen(fullname, "r"); + free(fullname); + } + + free(basename); + return f; +} + +void pcb_fp_fclose(FILE *f, int *is_parametric) +{ + if (*is_parametric) + pclose(f); + else + fclose(f); +} Index: trunk/src/libpcb_fp.h =================================================================== --- trunk/src/libpcb_fp.h (revision 289) +++ trunk/src/libpcb_fp.h (revision 290) @@ -14,4 +14,25 @@ /* Decide about the type of a footprint file by reading the content*/ pcb_fp_type_t pcb_fp_file_type(const char *fn); +/* duplicates the name and splits it into a basename and params; + params is NULL if the name is not parametric (and "" if parameter list is empty) + returns 1 if name is parametric, 0 if file element. + The caller shall free only *basename at the end. + */ +int pcb_fp_dupname(const char *name, char **basename, char **params); + + +/* walk the search_path for finding the first footprint for basename (shall not contain "(") */ +char *pcb_fp_search(const char *search_path, const char *basename, int parametric); + +/* Open a footprint for reading; if the footprint is parametric, it's run + prefixed with libshell (or executed directly, if libshell is NULL). + If name is not an absolute path, search_path is searched for the first match. + The user has to supply a state integer that will be used by pcb_fp_fclose(). + */ +FILE *pcb_fp_fopen(const char *libshell, const char *search_path, const char *name, int *state); + +/* Close the footprint file opened by pcb_fp_fopen(). */ +void pcb_fp_fclose(FILE *f, int *st); + #endif Index: trunk/src/parse_l.c =================================================================== --- trunk/src/parse_l.c (revision 289) +++ trunk/src/parse_l.c (revision 290) @@ -687,7 +687,7 @@ /* --------------------------------------------------------------------------- * some local prototypes */ -static int Parse(char *, char *, char *, char *); +static int Parse(FILE *, char *, char *, char *, char *); #line 693 "lex.yy.c" @@ -2287,7 +2287,7 @@ /* --------------------------------------------------------------------------- * sets up the preprocessor command */ -static int Parse(char *Executable, char *Path, char *Filename, char *Parameter) +static int Parse(FILE *Pipe, char *Executable, char *Path, char *Filename, char *Parameter) { static char *command = NULL; int returncode; @@ -2298,6 +2298,7 @@ static bool firsttime = true; #endif + if (Pipe == NULL) { if (EMPTY_STRING_P (Executable)) { l = 2; @@ -2341,6 +2342,10 @@ return(1); } } + } + else { + yyin = Pipe; + } #ifdef FLEX_SCANNER /* reset parser if not called the first time */ @@ -2374,6 +2379,9 @@ CreateBeLenient (false); + if (Pipe != NULL) + return returncode; + if (used_popen) return(pclose(yyin) ? 1 : returncode); return(fclose(yyin) ? 1 : returncode); @@ -2382,26 +2390,27 @@ /* --------------------------------------------------------------------------- * initializes LEX and calls parser for a single element file */ -int ParseElementFile(DataTypePtr Ptr, char *Filename) +int ParseElement(DataTypePtr Ptr, char *name) { + FILE *f; + int ret; + int st; + yyPCB = NULL; yyData = Ptr; yyFont = &PCB->Font; yyElement = NULL; - return(Parse(NULL,NULL,Filename,NULL)); -} -/* --------------------------------------------------------------------------- - * initializes LEX and calls parser for a single library entry - */ -int ParseLibraryEntry(DataTypePtr Ptr, char *Template) -{ - yyPCB = NULL; - yyData = Ptr; - yyFont = &PCB->Font; - yyElement = NULL; - return(Parse(Settings.LibraryCommand, Settings.LibraryPath, - Settings.LibraryFilename, Template)); + f = pcb_fp_fopen(Settings.LibraryCommand, Settings.LibraryPath, name, &st); + + if (f == NULL) + return -1; + + ret = Parse(f, NULL,NULL,NULL,NULL); + + pcb_fp_fclose(f, &st); + + return(ret); } /* --------------------------------------------------------------------------- @@ -2413,7 +2422,7 @@ yyData = NULL; yyFont = NULL; yyElement = NULL; - return(Parse(Settings.FileCommand, Settings.FilePath, Filename, NULL)); + return(Parse(NULL, Settings.FileCommand, Settings.FilePath, Filename, NULL)); } /* --------------------------------------------------------------------------- @@ -2436,7 +2445,7 @@ #ifdef DEBUG Message ("Looking for %s in %s\n", Filename, p); #endif - r = Parse(Settings.FontCommand, p, Filename, NULL); + r = Parse(NULL, Settings.FontCommand, p, Filename, NULL); if (r == 0) { #ifdef DEBUG Index: trunk/src/parse_l.h =================================================================== --- trunk/src/parse_l.h (revision 289) +++ trunk/src/parse_l.h (revision 290) @@ -34,8 +34,7 @@ #include "global.h" int ParsePCB (PCBTypePtr, char *); -int ParseElementFile (DataTypePtr, char *); -int ParseLibraryEntry (DataTypePtr, char *); +int ParseElement (DataTypePtr, char *); int ParseFont (FontTypePtr, char *); #endif Index: trunk/src/parse_l.l =================================================================== --- trunk/src/parse_l.l (revision 289) +++ trunk/src/parse_l.l (revision 290) @@ -89,7 +89,7 @@ /* --------------------------------------------------------------------------- * some local prototypes */ -static int Parse(char *, char *, char *, char *); +static int Parse(FILE *, char *, char *, char *, char *); %} @@ -203,7 +203,7 @@ /* --------------------------------------------------------------------------- * sets up the preprocessor command */ -static int Parse(char *Executable, char *Path, char *Filename, char *Parameter) +static int Parse(FILE *Pipe, char *Executable, char *Path, char *Filename, char *Parameter) { static char *command = NULL; int returncode; @@ -214,6 +214,7 @@ static bool firsttime = true; #endif + if (Pipe == NULL) { if (EMPTY_STRING_P (Executable)) { l = 2; @@ -257,6 +258,10 @@ return(1); } } + } + else { + yyin = Pipe; + } #ifdef FLEX_SCANNER /* reset parser if not called the first time */ @@ -290,6 +295,9 @@ CreateBeLenient (false); + if (Pipe != NULL) + return returncode; + if (used_popen) return(pclose(yyin) ? 1 : returncode); return(fclose(yyin) ? 1 : returncode); @@ -298,26 +306,27 @@ /* --------------------------------------------------------------------------- * initializes LEX and calls parser for a single element file */ -int ParseElementFile(DataTypePtr Ptr, char *Filename) +int ParseElement(DataTypePtr Ptr, char *name) { + FILE *f; + int ret; + int st; + yyPCB = NULL; yyData = Ptr; yyFont = &PCB->Font; yyElement = NULL; - return(Parse(NULL,NULL,Filename,NULL)); -} -/* --------------------------------------------------------------------------- - * initializes LEX and calls parser for a single library entry - */ -int ParseLibraryEntry(DataTypePtr Ptr, char *Template) -{ - yyPCB = NULL; - yyData = Ptr; - yyFont = &PCB->Font; - yyElement = NULL; - return(Parse(Settings.LibraryCommand, Settings.LibraryPath, - Settings.LibraryFilename, Template)); + f = pcb_fp_fopen(Settings.LibraryCommand, Settings.LibraryPath, name, &st); + + if (f == NULL) + return -1; + + ret = Parse(f, NULL,NULL,NULL,NULL); + + pcb_fp_fclose(f, &st); + + return(ret); } /* --------------------------------------------------------------------------- @@ -329,7 +338,7 @@ yyData = NULL; yyFont = NULL; yyElement = NULL; - return(Parse(Settings.FileCommand, Settings.FilePath, Filename, NULL)); + return(Parse(NULL, Settings.FileCommand, Settings.FilePath, Filename, NULL)); } /* --------------------------------------------------------------------------- @@ -352,7 +361,7 @@ #ifdef DEBUG Message ("Looking for %s in %s\n", Filename, p); #endif - r = Parse(Settings.FontCommand, p, Filename, NULL); + r = Parse(NULL, Settings.FontCommand, p, Filename, NULL); if (r == 0) { #ifdef DEBUG