Index: trunk/src_plugins/io_lihata/io_lihata.c =================================================================== --- trunk/src_plugins/io_lihata/io_lihata.c (revision 30792) +++ trunk/src_plugins/io_lihata/io_lihata.c (revision 30793) @@ -208,6 +208,7 @@ plug_io_lihata_v1.test_parse = io_lihata_test_parse; plug_io_lihata_v1.parse_pcb = io_lihata_parse_pcb; plug_io_lihata_v1.parse_footprint = NULL; + plug_io_lihata_v1.map_footprint = io_lihata_map_footprint; /* it is enough to have this for one version so the check is done only once */ plug_io_lihata_v1.parse_font = io_lihata_parse_font; plug_io_lihata_v1.parse_font = NULL; plug_io_lihata_v1.write_font = io_lihata_write_font; Index: trunk/src_plugins/io_lihata/read.c =================================================================== --- trunk/src_plugins/io_lihata/read.c (revision 30792) +++ trunk/src_plugins/io_lihata/read.c (revision 30793) @@ -2571,3 +2571,97 @@ return res; } +/* Decide about the type of a footprint file: + - if root is li:pcb-rnd-subcircuit, it is a static footprint file + - else it is a parametric element (footprint generator) if it contains + "@@" "purpose" + - if a line of a file element starts with ## and doesn't contain @, it's a tag + - if need_tags is set, tags are saved +*/ +pcb_plug_fp_map_t *io_lihata_map_footprint(pcb_plug_io_t *ctx, FILE *f, const char *fn, pcb_plug_fp_map_t *head, int need_tags) +{ + int c, comment_len; + int first_subc = 1; + long pos = -1; + enum { + ST_WS, + ST_COMMENT, + ST_SUBC, + ST_TAG + } state = ST_WS; + gds_t tag; + + gds_init(&tag); + head->type = PCB_FP_INVALID; + while ((c = fgetc(f)) != EOF) { + pos++; + switch (state) { + case ST_WS: + if (isspace(c)) + break; + if (c == '#') { + comment_len = 0; + state = ST_COMMENT; + break; + } + else if ((first_subc) && (c == 'l')) { + char s[23]; + /* li:pcb-rnd-subcircuit */ + fgets(s, 21, f); + s[20] = '\0'; + if (strcmp(s, "i:pcb-rnd-subcircuit") == 0) { + head->type = PCB_FP_FILE; + goto out; + } + } + else if ((first_subc) && (c == 'E')) { + char s[8]; + /* Element */ + fgets(s, 7, f); + s[6] = '\0'; + if (strcmp(s, "lement") == 0) { + state = ST_SUBC; + break; + } + } + first_subc = 0; + /* fall-thru for detecting @ */ + case ST_COMMENT: + comment_len++; + if ((c == '#') && (comment_len == 1)) { + state = ST_TAG; + break; + } + if ((c == '\r') || (c == '\n')) + state = ST_WS; + if (c == '@') { + char s[10]; + maybe_purpose:; + /* "@@" "purpose" */ + fgets(s, 9, f); + s[8] = '\0'; + if (strcmp(s, "@purpose") == 0) { + head->type = PCB_FP_PARAMETRIC; + goto out; + } + } + break; + case ST_TAG: + if ((c == '\r') || (c == '\n')) { /* end of a tag */ + if (need_tags && (tag.used != 0)) + vts0_append(&head->tags, (char *)pcb_fp_tag(tag.array, 1)); + + tag.used = 0; + state = ST_WS; + break; + } + if (c == '@') + goto maybe_purpose; + gds_append(&tag, c); + } + } + +out:; + gds_uninit(&tag); + return head; +} Index: trunk/src_plugins/io_lihata/read.h =================================================================== --- trunk/src_plugins/io_lihata/read.h (revision 30792) +++ trunk/src_plugins/io_lihata/read.h (revision 30793) @@ -31,6 +31,6 @@ int io_lihata_parse_font(pcb_plug_io_t *ctx, pcb_font_t *Ptr, const char *Filename); int io_lihata_parse_element(pcb_plug_io_t *ctx, pcb_data_t *Ptr, const char *name); int io_lihata_parse_buffer(pcb_plug_io_t *ctx, pcb_buffer_t *buff, const char *filename); +pcb_plug_fp_map_t *io_lihata_map_footprint(pcb_plug_io_t *ctx, FILE *f, const char *fn, pcb_plug_fp_map_t *head, int need_tags); - Index: trunk/src_plugins/io_pcb/file.c =================================================================== --- trunk/src_plugins/io_pcb/file.c (revision 30792) +++ trunk/src_plugins/io_pcb/file.c (revision 30793) @@ -1206,14 +1206,11 @@ #endif -TODO("subc: should be split up to multiple plugins") /* Decide about the type of a footprint file: - it is a file element if the first non-comment is "Element(" or "Element[" - - else it is a parametric element (footprint generator) if it contains - "@@" "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 + - if need_tags is set, tags are saved */ pcb_plug_fp_map_t *io_pcb_map_footprint(pcb_plug_io_t *ctx, FILE *f, const char *fn, pcb_plug_fp_map_t *head, int need_tags) { @@ -1246,17 +1243,6 @@ state = ST_COMMENT; break; } - else if ((first_element) && (c == 'l')) { -TODO("fp: rather call plug_io if it is not parametric") - char s[23]; - /* li:pcb-rnd-subcircuit */ - fgets(s, 21, f); - s[20] = '\0'; - if (strcmp(s, "i:pcb-rnd-subcircuit") == 0) { - head->type = PCB_FP_FILE; - goto out; - } - } else if ((first_element) && (c == 'E')) { char s[8]; /* Element */ @@ -1287,20 +1273,9 @@ } if ((c == '\r') || (c == '\n')) state = ST_WS; - if (c == '@') { - char s[10]; - maybe_purpose:; - /* "@@" "purpose" */ - fgets(s, 9, f); - s[8] = '\0'; - if (strcmp(s, "@purpose") == 0) { - head->type = PCB_FP_PARAMETRIC; - goto out; - } - } break; case ST_TAG: - if ((c == '\r') || (c == '\n')) { /* end of a tag */ + if ((c == '\r') || (c == '\n')) { /* end of a tag */ if (need_tags && (tag.used != 0)) vts0_append(&head->tags, (char *)pcb_fp_tag(tag.array, 1)); @@ -1308,8 +1283,6 @@ state = ST_WS; break; } - if (c == '@') - goto maybe_purpose; gds_append(&tag, c); } }