Index: trunk/src/plug_io.c =================================================================== --- trunk/src/plug_io.c (revision 27332) +++ trunk/src/plug_io.c (revision 27333) @@ -404,7 +404,7 @@ return res; } -int pcb_write_footprint_data(FILE *f, pcb_data_t *e, const char *fmt) +int pcb_write_footprint_data(FILE *f, pcb_data_t *e, const char *fmt, long subc_idx) { int res, newfmt = 0; pcb_plug_io_t *p = e->loader; @@ -415,7 +415,7 @@ } if ((p != NULL) && (p->write_footprint != NULL)) - res = p->write_footprint(p, f, e); + res = p->write_footprint(p, f, e, subc_idx); if ((res == 0) && (newfmt)) e->loader = p; @@ -602,7 +602,7 @@ { if (thePcb) { if (PCB->is_footprint) - return pcb_write_footprint_data(fp, PCB->Data, fmt); + return pcb_write_footprint_data(fp, PCB->Data, fmt, subc_idx); return pcb_write_pcb(fp, old_path, new_path, fmt, emergency); } return pcb_write_buffer(fp, PCB_PASTEBUFFER, fmt, subc_only, subc_idx); Index: trunk/src/plug_io.h =================================================================== --- trunk/src/plug_io.h (revision 27332) +++ trunk/src/plug_io.h (revision 27333) @@ -87,8 +87,10 @@ /* Write the idxth subcircuit from buffer to a file. Return 0 on success. */ int (*write_buffer_subc)(pcb_plug_io_t *ctx, FILE *f, pcb_buffer_t *buff, long idx); - /* Write subcirciots from 'e' to a library file. Return 0 on success. */ - int (*write_footprint)(pcb_plug_io_t *ctx, FILE *f, pcb_data_t *e); + /* Write subcircuit(s) from 'e' to a library file. If subc_idx is -1, write + all subcircuits as a library (if the format allows), else write only + th sucb_idxth subcircuit as a footprint. Return 0 on success. */ + int (*write_footprint)(pcb_plug_io_t *ctx, FILE *f, pcb_data_t *e, long subc_idx); /* Write PCB to f; there's a copy of the file we are going to "overwrite", named in old_filename and the new file name we are @@ -126,7 +128,7 @@ int pcb_parse_pcb(pcb_board_t *Ptr, const char *Filename, const char *fmt, int load_settings, int ignore_missing); int pcb_parse_footprint(pcb_data_t *Ptr, const char *name, const char *fmt); int pcb_parse_font(pcb_font_t *Ptr, const char *Filename); -int pcb_write_footprint_data(FILE *f, pcb_data_t *e, const char *fmt); +int pcb_write_footprint_data(FILE *f, pcb_data_t *e, const char *fmt, long subc_idx); int pcb_write_font(pcb_font_t *Ptr, const char *Filename, const char *fmt); /********** common function used to be part of file.[ch] and friends **********/ Index: trunk/src_plugins/io_kicad/write.c =================================================================== --- trunk/src_plugins/io_kicad/write.c (revision 27332) +++ trunk/src_plugins/io_kicad/write.c (revision 27333) @@ -672,7 +672,7 @@ kicad_print_pstks(ctx, data, ind, dx, dy); } -static int kicad_print_subcs(wctx_t *ctx, pcb_data_t *Data, pcb_cardinal_t ind, pcb_coord_t dx, pcb_coord_t dy) +static int kicad_print_subcs(wctx_t *ctx, pcb_data_t *Data, pcb_cardinal_t ind, pcb_coord_t dx, pcb_coord_t dy, long subc_idx) { gdl_iterator_t sit; pcb_subc_t *subc; @@ -695,6 +695,9 @@ int silkLayer = 21; /* hard coded default, 20 is bottom silk */ int copperLayer = 15; /* hard coded default, 0 is bottom copper */ + if ((subc_idx >= 0) && (subc_idx != sit.count)) + continue; + /* elementlist_dedup_skip(ededup, element); */ TODO(": why?") /* let's not skip duplicate elements for layout export */ @@ -788,7 +791,7 @@ } /* writes element data in kicad legacy format for use in a .mod library */ -int io_kicad_write_element(pcb_plug_io_t *ctx, FILE *FP, pcb_data_t *Data) +int io_kicad_write_element(pcb_plug_io_t *ctx, FILE *FP, pcb_data_t *Data, long subc_idx) { wctx_t wctx; @@ -808,7 +811,7 @@ if (kicad_map_layers(&wctx) != 0) return -1; - return kicad_print_subcs(&wctx, Data, 0, 0, 0); + return kicad_print_subcs(&wctx, Data, 0, 0, 0, subc_idx); } static int write_kicad_equipotential_netlists(FILE *FP, pcb_board_t *Layout, pcb_cardinal_t indentation) @@ -970,7 +973,7 @@ /* module descriptions come next */ fputs("\n", FP); - kicad_print_subcs(&wctx, PCB->Data, baseSExprIndent, wctx.ox, wctx.oy); + kicad_print_subcs(&wctx, PCB->Data, baseSExprIndent, wctx.ox, wctx.oy, -1); kicad_print_data(&wctx, PCB->Data, baseSExprIndent, wctx.ox, wctx.oy); kicad_fixup_outline(&wctx, baseSExprIndent); Index: trunk/src_plugins/io_kicad/write.h =================================================================== --- trunk/src_plugins/io_kicad/write.h (revision 27332) +++ trunk/src_plugins/io_kicad/write.h (revision 27333) @@ -30,7 +30,7 @@ #include #include "data.h" -int io_kicad_write_element(pcb_plug_io_t *ctx, FILE *FP, pcb_data_t *Data); +int io_kicad_write_element(pcb_plug_io_t *ctx, FILE *FP, pcb_data_t *Data, long subc_idx); int io_kicad_write_buffer_subc(pcb_plug_io_t *ctx, FILE *FP, pcb_buffer_t *buff, long idx); int io_kicad_write_pcb(pcb_plug_io_t *ctx, FILE *FP, const char *old_filename, const char *new_filename, pcb_bool emergency); Index: trunk/src_plugins/io_kicad_legacy/write.c =================================================================== --- trunk/src_plugins/io_kicad_legacy/write.c (revision 27332) +++ trunk/src_plugins/io_kicad_legacy/write.c (revision 27333) @@ -663,9 +663,9 @@ } } -int io_kicad_legacy_write_buffer_subc(pcb_plug_io_t *ctx, FILE *FP, pcb_buffer_t *buff, long idx) +int io_kicad_legacy_write_buffer_subc(pcb_plug_io_t *ctx, FILE *FP, pcb_buffer_t *buff, long subc_idx) { - if (idx != 0) { + if (subc_idx != 0) { pcb_message(PCB_MSG_ERROR, "Only the first subcircuit can be saved at the moment\n"); return -1; } @@ -681,7 +681,7 @@ io_kicad_legacy_write_subc_index(FP, buff->Data); fputs("$EndINDEX\n", FP); - pcb_write_footprint_data(FP, buff->Data, "kicadl"); + pcb_write_footprint_data(FP, buff->Data, "kicadl", subc_idx); return 0; } @@ -1041,7 +1041,7 @@ return 0; } -int io_kicad_legacy_write_element(pcb_plug_io_t *ctx, FILE *FP, pcb_data_t *Data) +int io_kicad_legacy_write_element(pcb_plug_io_t *ctx, FILE *FP, pcb_data_t *Data, long subc_idx) { gdl_iterator_t sit; pcb_subc_t *subc; @@ -1050,8 +1050,10 @@ unm_init(&group1); subclist_foreach(&Data->subc, &sit, subc) { - const char *uname = unm_name(&group1, or_empty(pcb_attribute_get(&subc->Attributes, "footprint")), subc); - res |= io_kicad_legacy_write_subc(FP, PCB, subc, 0, 0, uname); + if ((subc_idx == -1) || (subc_idx == sit.count)) { + const char *uname = unm_name(&group1, or_empty(pcb_attribute_get(&subc->Attributes, "footprint")), subc); + res |= io_kicad_legacy_write_subc(FP, PCB, subc, 0, 0, uname); + } } unm_uninit(&group1); Index: trunk/src_plugins/io_kicad_legacy/write.h =================================================================== --- trunk/src_plugins/io_kicad_legacy/write.h (revision 27332) +++ trunk/src_plugins/io_kicad_legacy/write.h (revision 27333) @@ -30,6 +30,6 @@ #include #include "data.h" -int io_kicad_legacy_write_element(pcb_plug_io_t *ctx, FILE *FP, pcb_data_t *Data); +int io_kicad_legacy_write_element(pcb_plug_io_t *ctx, FILE *FP, pcb_data_t *Data, long subc_idx); int io_kicad_legacy_write_buffer_subc(pcb_plug_io_t *ctx, FILE *FP, pcb_buffer_t *buff, long idx); int io_kicad_legacy_write_pcb(pcb_plug_io_t *ctx, FILE *FP, const char *old_filename, const char *new_filename, pcb_bool emergency); Index: trunk/src_plugins/io_lihata/write.c =================================================================== --- trunk/src_plugins/io_lihata/write.c (revision 27332) +++ trunk/src_plugins/io_lihata/write.c (revision 27333) @@ -1657,13 +1657,13 @@ return 0; } -static int io_lihata_dump_1st_subc(pcb_plug_io_t *ctx, FILE *f, pcb_data_t *data, int enforce1) +static int io_lihata_dump_nth_subc(pcb_plug_io_t *ctx, FILE *f, pcb_data_t *data, int enforce1, long subc_idx) { int res; lht_doc_t *doc; pcb_subc_t *sc; - if ((enforce1) && (pcb_subclist_length(&data->subc)) > 1) { + if ((subc_idx < 0) && (enforce1) && (pcb_subclist_length(&data->subc)) > 1) { pcb_message(PCB_MSG_ERROR, "Can't save more than one subcircuit from a buffer\n"); return -1; } @@ -1682,7 +1682,14 @@ wrver = 1; /* bump version if features require */ - sc = pcb_subclist_first(&data->subc); + if (subc_idx == -1) + sc = pcb_subclist_first(&data->subc); + else + sc = pcb_subclist_nth(&data->subc, subc_idx); + + if (sc == NULL) + return -1; + TODO("subc: for subc-in-subc this should be recursive") if (padstacklist_first(&sc->data->padstack) != NULL) { if (wrver < 4) { @@ -1745,12 +1752,12 @@ return -1; } - return io_lihata_dump_1st_subc(ctx, f, buff->Data, 1); + return io_lihata_dump_nth_subc(ctx, f, buff->Data, 1, idx); } -int io_lihata_write_element(pcb_plug_io_t *ctx, FILE *f, pcb_data_t *dt) +int io_lihata_write_element(pcb_plug_io_t *ctx, FILE *f, pcb_data_t *dt, long subc_idx) { - return io_lihata_dump_1st_subc(ctx, f, dt, 1); + return io_lihata_dump_nth_subc(ctx, f, dt, 1, subc_idx); } typedef struct { Index: trunk/src_plugins/io_pcb/file.c =================================================================== --- trunk/src_plugins/io_pcb/file.c (revision 27332) +++ trunk/src_plugins/io_pcb/file.c (revision 27333) @@ -420,7 +420,7 @@ } } -int io_pcb_WriteSubcData(pcb_plug_io_t *ctx, FILE *FP, pcb_data_t *Data) +int io_pcb_WriteSubcData(pcb_plug_io_t *ctx, FILE *FP, pcb_data_t *Data, long subc_idx) { gdl_iterator_t sit, it; pcb_subc_t *sc; @@ -436,6 +436,9 @@ pcb_pstk_t *ps; pcb_any_obj_t fobj; + if ((subc_idx != -1) && (subc_idx != sit.count)) + continue; + pcb_subc_get_origin(sc, &ox, &oy); trefdes = pcb_subc_get_refdes_text(sc); if (pcb_subc_get_side(sc, &on_bot) != 0) @@ -703,7 +706,7 @@ } } -int io_pcb_WriteBuffer_subc(pcb_plug_io_t *ctx, FILE *FP, pcb_buffer_t *buff, long idx) +int io_pcb_WriteBuffer_subc(pcb_plug_io_t *ctx, FILE *FP, pcb_buffer_t *buff, long subc_idx) { pcb_printf_slot[0] = ((io_pcb_ctx_t *)(ctx->plugin_data))->write_coord_fmt; @@ -711,12 +714,12 @@ pcb_message(PCB_MSG_ERROR, "Buffer has no subcircuits!\n"); return -1; } - if (idx != 0) { + if (subc_idx != 0) { pcb_message(PCB_MSG_ERROR, "Only the first subcircuit can be saved at the moment\n"); return -1; } - io_pcb_WriteSubcData(ctx, FP, buff->Data); + io_pcb_WriteSubcData(ctx, FP, buff->Data, subc_idx); return 0; } @@ -733,7 +736,7 @@ WritePCBFontData(FP); WriteAttributeList(FP, &PCB->Attributes, "", NULL); WriteViaData(FP, PCB->Data); - io_pcb_WriteSubcData(ctx, FP, PCB->Data); + io_pcb_WriteSubcData(ctx, FP, PCB->Data, -1); WritePCBRatData(FP); WriteLayers(FP, PCB->Data); WritePCBNetlistData(FP); Index: trunk/src_plugins/io_pcb/file.h =================================================================== --- trunk/src_plugins/io_pcb/file.h (revision 27332) +++ trunk/src_plugins/io_pcb/file.h (revision 27333) @@ -58,7 +58,7 @@ int io_pcb_WriteBuffer_subc(pcb_plug_io_t *ctx, FILE *f, pcb_buffer_t *buff, long idx); -int io_pcb_WriteSubcData(pcb_plug_io_t *ctx, FILE *f, pcb_data_t *); +int io_pcb_WriteSubcData(pcb_plug_io_t *ctx, FILE *f, pcb_data_t *data, long subc_idx); int io_pcb_WritePCB(pcb_plug_io_t *ctx, FILE *f, const char *old_filename, const char *new_filename, pcb_bool emergency); void PreLoadElementPCB(void); Index: trunk/src_plugins/io_tedax/footprint.c =================================================================== --- trunk/src_plugins/io_tedax/footprint.c (revision 27332) +++ trunk/src_plugins/io_tedax/footprint.c (revision 27333) @@ -274,9 +274,10 @@ } -int tedax_fp_fsave(pcb_data_t *data, FILE *f) +int tedax_fp_fsave(pcb_data_t *data, FILE *f, long subc_idx) { int res = 0; + long cnt = 0; fprintf(f, "tEDAx v1\n"); @@ -283,17 +284,20 @@ PCB_SUBC_LOOP(data) { - const char *fpname = pcb_attribute_get(&subc->Attributes, "tedax::footprint"); - if (fpname == NULL) - fpname = pcb_attribute_get(&subc->Attributes, "visible_footprint"); - if (fpname == NULL) - fpname = pcb_attribute_get(&subc->Attributes, "footprint"); - if ((fpname == NULL) && (subc->refdes != NULL)) - fpname = subc->refdes; - if (fpname == NULL) - fpname = "-"; + if ((subc_idx == -1) || (subc_idx == cnt)) { + const char *fpname = pcb_attribute_get(&subc->Attributes, "tedax::footprint"); + if (fpname == NULL) + fpname = pcb_attribute_get(&subc->Attributes, "visible_footprint"); + if (fpname == NULL) + fpname = pcb_attribute_get(&subc->Attributes, "footprint"); + if ((fpname == NULL) && (subc->refdes != NULL)) + fpname = subc->refdes; + if (fpname == NULL) + fpname = "-"; - res |= tedax_fp_fsave_subc(subc, fpname, 0, f); + res |= tedax_fp_fsave_subc(subc, fpname, 0, f); + } + cnt++; } PCB_END_LOOP; @@ -301,7 +305,7 @@ return res; } -int tedax_fp_save(pcb_data_t *data, const char *fn) +int tedax_fp_save(pcb_data_t *data, const char *fn, long subc_idx) { int res; FILE *f; @@ -311,7 +315,7 @@ pcb_message(PCB_MSG_ERROR, "tedax_fp_save(): can't open %s for writing\n", fn); return -1; } - res = tedax_fp_fsave(data, f); + res = tedax_fp_fsave(data, f, subc_idx); fclose(f); return res; } Index: trunk/src_plugins/io_tedax/footprint.h =================================================================== --- trunk/src_plugins/io_tedax/footprint.h (revision 27332) +++ trunk/src_plugins/io_tedax/footprint.h (revision 27333) @@ -1,8 +1,8 @@ #include "data.h" #include -int tedax_fp_save(pcb_data_t *data, const char *fn); -int tedax_fp_fsave(pcb_data_t *data, FILE *f); +int tedax_fp_save(pcb_data_t *data, const char *fn, long subc_idx); +int tedax_fp_fsave(pcb_data_t *data, FILE *f, long subc_idx); int tedax_fp_load(pcb_data_t *data, const char *fn, int multi, const char *blk_id, int silent); /* parse a single footprint at current file pos; returns NULL on error */ Index: trunk/src_plugins/io_tedax/io_tedax.c =================================================================== --- trunk/src_plugins/io_tedax/io_tedax.c (revision 27332) +++ trunk/src_plugins/io_tedax/io_tedax.c (revision 27333) @@ -79,7 +79,7 @@ } if (pcb_strcasecmp(type, "board-footprints") == 0) { - PCB_ACT_IRES(tedax_fp_save(PCB->Data, fname)); + PCB_ACT_IRES(tedax_fp_save(PCB->Data, fname, -1)); return 0; } @@ -183,18 +183,18 @@ return tedax_fp_load(Ptr, name, 0, NULL, 0); } -static int io_tedax_write_element(pcb_plug_io_t *ctx, FILE *f, pcb_data_t *dt) +static int io_tedax_write_element(pcb_plug_io_t *ctx, FILE *f, pcb_data_t *dt, long subc_idx) { - return tedax_fp_fsave(dt, f); + return tedax_fp_fsave(dt, f, subc_idx); } -static int io_tedax_write_buffer_subc(pcb_plug_io_t *ctx, FILE *f, pcb_buffer_t *buff, long idx) +static int io_tedax_write_buffer_subc(pcb_plug_io_t *ctx, FILE *f, pcb_buffer_t *buff, long subc_idx) { - if (idx != 0) { + if (subc_idx != 0) { pcb_message(PCB_MSG_ERROR, "Only the first subcircuit cna be saved at the moment\n"); return -1; } - return tedax_fp_fsave(buff->Data, f); + return tedax_fp_fsave(buff->Data, f, subc_idx); } static int io_tedax_test_parse(pcb_plug_io_t *plug_ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f)