Index: trunk/src/file.c =================================================================== --- trunk/src/file.c (revision 855) +++ trunk/src/file.c (revision 856) @@ -1176,7 +1176,7 @@ } list_st_t; -static int list_cb(void *cookie, const char *subdir, const char *name, pcb_fp_type_t type) +static int list_cb(void *cookie, const char *subdir, const char *name, pcb_fp_type_t type, void *tags[]) { list_st_t *l = (list_st_t *)cookie; LibraryEntryTypePtr entry; /* Pointer to individual menu entry */ @@ -1246,7 +1246,7 @@ l.subdirs = NULL; l.children = 0; - pcb_fp_list(working, 0, list_cb, &l, is_root); + pcb_fp_list(working, 0, list_cb, &l, is_root, 1); /* now recurse to each subdirectory mapped in the previous call; by now we don't care if menu is ruined by the realloc() in GetLibraryMenuMemory() */ Index: trunk/src/libpcb_fp.c =================================================================== --- trunk/src/libpcb_fp.c (revision 855) +++ trunk/src/libpcb_fp.c (revision 856) @@ -102,11 +102,11 @@ if (pcb_fp_tags == NULL) pcb_fp_tags = htsp_alloc(strhash, keyeq); - e = htsp_getentry(pcb_fp_tags, tag); + e = htsp_getentry(pcb_fp_tags, (char *)tag); if ((e == NULL) && alloc) { - htsp_set(pcb_fp_tags, strdup(tag), counter); + htsp_set(pcb_fp_tags, strdup(tag), (void *)counter); counter++; - e = htsp_getentry(pcb_fp_tags, tag); + e = htsp_getentry(pcb_fp_tags, (char *)tag); } return e; } @@ -117,8 +117,9 @@ "@@" "purpose" - else it's not an element. - if a line of a file element starts with ## and doesn't contain @, it's a tag + - if tags is not NULL, it's a pointer to a void *tags[] - an array of tag IDs */ -pcb_fp_type_t pcb_fp_file_type(const char *fn) +pcb_fp_type_t pcb_fp_file_type(const char *fn, void ***tags) { int c, comment_len; int first_element = 1; @@ -131,8 +132,12 @@ } state = ST_WS; char *tag = NULL; int talloced = 0, tused = 0; + int Talloced = 0, Tused = 0; pcb_fp_type_t ret = PCB_FP_INVALID; + if (tags != NULL) + *tags = NULL; + f = fopen(fn, "r"); if (f == NULL) return PCB_FP_INVALID; @@ -188,9 +193,17 @@ break; case ST_TAG: if ((c == '\r') || (c == '\n')) { /* end of a tag */ - tag[tused] = '\0'; -/* printf("TAG: '%s' '%s'\n", fn, tag);*/ - pcb_fp_tag(tag, 1); + if (tags != NULL) { + tag[tused] = '\0'; + if (Tused >= Talloced) { + Talloced += 8; + *tags = realloc(*tags, (Talloced+1) * sizeof(void *)); + } + (*tags)[Tused] = (void *)pcb_fp_tag(tag, 1); + Tused++; + (*tags)[Tused] = NULL; + } + tused = 0; state = ST_WS; break; @@ -213,7 +226,7 @@ return ret; } -int pcb_fp_list(const char *subdir, int recurse, int (*cb) (void *cookie, const char *subdir, const char *name, pcb_fp_type_t type), void *cookie, int subdir_may_not_exist) +int pcb_fp_list(const char *subdir, int recurse, int (*cb) (void *cookie, const char *subdir, const char *name, pcb_fp_type_t type, void *tags[]), void *cookie, int subdir_may_not_exist, int need_tags) { char olddir[MAXPATHLEN + 1]; /* The directory we start out in (cwd) */ char new_subdir[MAXPATHLEN + 1]; @@ -291,10 +304,11 @@ strcpy(fn_end, subdirentry->d_name); if ((S_ISREG(buffer.st_mode)) || (WRAP_S_ISLNK(buffer.st_mode))) { pcb_fp_type_t ty; - ty = pcb_fp_file_type(subdirentry->d_name); + void **tags = NULL; + ty = pcb_fp_file_type(subdirentry->d_name, (need_tags ? &tags : NULL)); if ((ty == PCB_FP_FILE) || (ty == PCB_FP_PARAMETRIC)) { n_footprints++; - if (cb(cookie, new_subdir, subdirentry->d_name, ty)) + if (cb(cookie, new_subdir, subdirentry->d_name, ty, tags)) break; continue; } @@ -301,9 +315,9 @@ } if ((S_ISDIR(buffer.st_mode)) || (WRAP_S_ISLNK(buffer.st_mode))) { - cb(cookie, new_subdir, subdirentry->d_name, PCB_FP_DIR); + cb(cookie, new_subdir, subdirentry->d_name, PCB_FP_DIR, NULL); if (recurse) { - n_footprints += pcb_fp_list(fn, recurse, cb, cookie, 0); + n_footprints += pcb_fp_list(fn, recurse, cb, cookie, 0, need_tags); } continue; } @@ -348,7 +362,7 @@ char *real_name; } pcb_fp_search_t; -static int pcb_fp_search_cb(void *cookie, const char *subdir, const char *name, pcb_fp_type_t type) +static int pcb_fp_search_cb(void *cookie, const char *subdir, const char *name, pcb_fp_type_t type, void *tags[]) { pcb_fp_search_t *ctx = (pcb_fp_search_t *)cookie; if ((strncmp(ctx->target, name, ctx->target_len) == 0) && ((!!ctx->parametric) == (type == PCB_FP_PARAMETRIC))) { @@ -388,7 +402,7 @@ resolve_path(path, &fpath); /* fprintf(stderr, " in '%s'\n", fpath);*/ - pcb_fp_list(fpath, 1, pcb_fp_search_cb, &ctx, 1); + pcb_fp_list(fpath, 1, pcb_fp_search_cb, &ctx, 1, 0); if (ctx.path != NULL) { sprintf(path, "%s%c%s", ctx.path, PCB_DIR_SEPARATOR_C, ctx.real_name); free(ctx.path); Index: trunk/src/libpcb_fp.h =================================================================== --- trunk/src/libpcb_fp.h (revision 855) +++ trunk/src/libpcb_fp.h (revision 856) @@ -9,11 +9,13 @@ /* List all symbols, optionally recursively, from CWD/subdir. For each symbol or subdir, call the callback. Ignore file names starting with - If subdir_may_not_exist is non-zero, don't complain if the top subdir does not exist .*/ -int pcb_fp_list(const char *subdir, int recurse, int (*cb)(void *cookie, const char *subdir, const char *name, pcb_fp_type_t type), void *cookie, int subdir_may_not_exist); + If subdir_may_not_exist is non-zero, don't complain if the top subdir does not exist. +*/ +int pcb_fp_list(const char *subdir, int recurse, int (*cb) (void *cookie, const char *subdir, const char *name, pcb_fp_type_t type, void *tags[]), void *cookie, int subdir_may_not_exist, int need_tags); -/* Decide about the type of a footprint file by reading the content*/ -pcb_fp_type_t pcb_fp_file_type(const char *fn); +/* Decide about the type of a footprint file by reading the content and + optionally extract tag IDs into a void *tags[] */ +pcb_fp_type_t pcb_fp_file_type(const char *fn, void ***tags); /* 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)