Index: trunk/src/plug_io.c =================================================================== --- trunk/src/plug_io.c (revision 718) +++ trunk/src/plug_io.c (revision 719) @@ -119,3 +119,105 @@ return -1; } + +/*** save ***/ + +typedef struct { + int prio; + camv_io_t *io; +} prio_t; +#define GVT(x) vtpr_ ## x +#define GVT_ELEM_TYPE prio_t +#define GVT_SIZE_TYPE int +#define GVT_DOUBLING_THRS 32 +#define GVT_START_SIZE 8 +#define GVT_FUNC +#define GVT_SET_NEW_BYTES_TO 0 +#include +#define GVT_REALLOC(vect, ptr, size) realloc(ptr, size) +#define GVT_FREE(vect, ptr) free(ptr) +#include + +static int prio_cmp(const void *d1, const void *d2) +{ + const prio_t *p1 = d1, *p2 = d2; + if (p1->prio <= p2->prio) return 1; + return -1; +} + +typedef enum { + LIST_SAVE +#if 0 + LIST_EXPORT +#endif +} io_list_dir_t; + +static void camv_plug_io_list(vtpr_t *res, const char *fn, const char *fmt, camv_io_type_t type, io_list_dir_t dir) +{ + int n, p; + prio_t *pr; + + for(n = 0; n < vtp0_len(&camv_io); n++) { + camv_io_t *io = camv_io.array[n]; + if (io == NULL) continue; + switch(dir) { + case LIST_SAVE: + if (io->save_prio == NULL) continue; + p = io->save_prio(fn, fmt, type); + break; +#if 0 + case LIST_EXPORT: + if (io->export_prio == NULL) continue; + p = io->export_prio(fn, fmt, type); + break; +#endif + } + + if (p > 0) { + pr = vtpr_alloc_append(res, 1); + pr->prio = p; + pr->io = io; + } + } + qsort(res->array, vtpr_len(res), sizeof(prio_t), prio_cmp); +} + +static int camv_save_design(camv_design_t *camv, const char *fn_, const char *fmt) +{ + vtpr_t prios; + int n, ret = -1, len; + char *fn, *ext = NULL; + + if ((fmt == NULL) || (*fmt == '\0')) + return -1; + + len = strlen(fn_); + fn = malloc(len+1); + memcpy(fn, fn_, len+1); + if (fn[len-1] == '*') + ext = fn + len - 1; + + vtpr_init(&prios); + camv_plug_io_list(&prios, fn, fmt, CSCH_IOTYP_DESIGN, LIST_SAVE); + for(n = 0; n < vtpr_len(&prios); n++) { + prio_t *pr = &prios.array[n]; + if (ext != NULL) { + if (pr->io->ext_save_design != NULL) + strcpy(ext, pr->io->ext_save_design); + else + *ext = '\0'; + break; + } + + rnd_event(&camv->hidlib, RND_EVENT_SAVE_PRE, "s", fmt); + ret = pr->io->save_design(camv, fn); + rnd_event(&camv->hidlib, RND_EVENT_SAVE_POST, "si", fmt, ret); + + if (ret == 0) + break; + } + + free(fn); + vtpr_uninit(&prios); + return ret; +} Index: trunk/src/plug_io.h =================================================================== --- trunk/src/plug_io.h (revision 718) +++ trunk/src/plug_io.h (revision 719) @@ -30,12 +30,22 @@ #include #include "data.h" +typedef enum camv_io_type_s { /* bitfield so multiple detections (e.g. design-or-layer) can be handled */ + CSCH_IOTYP_DESIGN = 1, + CSCH_IOTYP_LAYER = 2 +} camv_io_type_t; + + typedef struct camv_io_s { const char *name; int prio; /* the higher the better */ int (*test_load)(camv_design_t *camv, const char *fn, FILE *f); /* returns non-zero if the file looks good for the plugin */ int (*load)(camv_design_t *camv, const char *fn, FILE *f); + + int (*save_prio)(const char *fn, const char *fmt, camv_io_type_t type); int (*save_design)(camv_design_t *camv, const char *fn); + const char *ext_save_design; + } camv_io_t; void camv_io_reg(camv_io_t *io); Index: trunk/src_plugins/io_tedax/io_tedax.c =================================================================== --- trunk/src_plugins/io_tedax/io_tedax.c (revision 718) +++ trunk/src_plugins/io_tedax/io_tedax.c (revision 719) @@ -561,7 +561,9 @@ "tEDAx camv layer", 100, camv_tdx_test_load, camv_tdx_load, + NULL, camv_tdx_save_design, + "tdx" };