Index: trunk/src/hid_cam.c =================================================================== --- trunk/src/hid_cam.c (revision 24100) +++ trunk/src/hid_cam.c (revision 24101) @@ -29,6 +29,10 @@ */ #include "config.h" + +#include +#include + #include "board.h" #include "data.h" #include "hid_cam.h" @@ -37,7 +41,7 @@ #include "layer_vis.h" #include "plug_io.h" -char *pcb_cam_base = NULL; +htsp_t *pcb_cam_vars = NULL; /* substitute %% variables from this hash */ char *pcb_layer_to_file_name(char *dest, pcb_layer_id_t lid, unsigned int flags, const char *purpose, int purpi, pcb_file_name_style_t style) { @@ -454,6 +458,7 @@ pcb_cam_t *cam; const pcb_layergrp_t *grp; const pcb_virt_layer_t *vl; + htsp_t *vars; } cam_name_ctx_t; /* convert string to integer, step input beyond the terminating % */ @@ -484,10 +489,6 @@ else if (ctx->vl != NULL) gds_append_str(s, ctx->vl->name); } - if (strncmp(*input, "base%", 5) == 0) { - (*input) += 5; - gds_append_str(s, pcb_cam_base == NULL ? "unspecifiedbase" : pcb_cam_base); - } else if (strncmp(*input, "top_offs", 8) == 0) { int tune, from_top = -1; pcb_layergrp_t *tcop = pcb_get_grp(&PCB->LayerGroups, PCB_LYT_TOP, PCB_LYT_COPPER); @@ -510,7 +511,32 @@ pcb_layergrp_dist(PCB, pcb_layergrp_id(PCB, ctx->grp), bcop_id, PCB_LYT_COPPER, &from_bot); pcb_append_printf(s, "%d", from_bot+tune); } + else { + char *end = strchr(*input, '%'); + char varname[128]; + int len; + if (end == NULL) { + gds_append_str(s, *input); + return 0; + } + + if (ctx->vars != NULL) { + len = end - *input; + if (len < sizeof(varname)-1) { + const char *val; + strncpy(varname, *input, len); + val = htsp_get(ctx->vars, varname); + if (val != NULL) + gds_append_str(s, val); + } + else + pcb_message(PCB_MSG_ERROR, "cam job error: %%%% variable name too long at: '%%%s' - did not substitute\n", *input); + } + + *input = end+1; + } + return 0; } @@ -524,6 +550,7 @@ ctx.cam = cam; ctx.grp = pcb_get_layergrp(cam->pcb, gid); ctx.vl = vl; + ctx.vars = pcb_cam_vars; cam->fn = pcb_strdup_subst(cam->fn_template, cam_update_name_cb, &ctx, PCB_SUBST_HOME | PCB_SUBST_PERCENT | PCB_SUBST_CONF); if ((cam->fn_last == NULL) || (strcmp(cam->fn, cam->fn_last) != 0)) { cam->fn_changed = 1; @@ -566,3 +593,32 @@ return cam_update_name(cam, group, NULL);; } + +void *pcb_cam_init_vars(void) +{ + void *old = pcb_cam_vars; + pcb_cam_vars = htsp_alloc(strhash, strkeyeq); + return old; +} + +void pcb_cam_uninit_vars(void *as_inited) +{ + htsp_entry_t *e; + + for(e = htsp_first(pcb_cam_vars); e != NULL; e = htsp_next(pcb_cam_vars, e)) { + free(e->key); + free(e->value); + } + htsp_free(pcb_cam_vars); + pcb_cam_vars = as_inited; +} + +void pcb_cam_set_var(char *key, char *val) +{ + htsp_entry_t *e = htsp_popentry(pcb_cam_vars, key); + if (e != NULL) { + free(e->key); + free(e->value); + } + htsp_set(pcb_cam_vars, key, val); +} Index: trunk/src/hid_cam.h =================================================================== --- trunk/src/hid_cam.h (revision 24100) +++ trunk/src/hid_cam.h (revision 24101) @@ -4,7 +4,7 @@ #include "layer.h" #include "hid_attrib.h" -/*** CAM API ***/ +/*** CAM plugin side API ***/ typedef struct pcb_cam_s { /* public */ char *fn; @@ -27,8 +27,6 @@ int exported_grps; } pcb_cam_t; -extern char *pcb_cam_base; /* substitute %base% with this */ - int pcb_cam_begin(pcb_board_t *pcb, pcb_cam_t *dst, const char *src, const pcb_hid_attribute_t *attr_tbl, int numa, pcb_hid_attr_val_t *options); /* Finish cam export, free all memory, mark cam export inactive and report @@ -49,6 +47,18 @@ should return (and skip the current group) */ int pcb_cam_set_layer_group_(pcb_cam_t *cam, pcb_layergrp_id_t group, const char *purpose, int purpi, unsigned int flags, pcb_xform_t **xform); +/*** CAM caller side API for global export ***/ + +/* Init/uninit a new var context; caller needs to store the void * returned by + init and supply it with the uninit call. */ +void *pcb_cam_init_vars(void); +void pcb_cam_uninit_vars(void *as_inited); + +/* Overwrite a CAM variable in the currently active context; both key + and val must be strdup'd on caller side (they are free'd by the CAM code) */ +void pcb_cam_set_var(char *key, char *val); + + /*** Obsolete file suffix API - new plugins should not use this ***/ /* maximum size of a derived suffix */ #define PCB_DERIVE_FN_SUFF_LEN 20 Index: trunk/src_plugins/cam/cam.c =================================================================== --- trunk/src_plugins/cam/cam.c (revision 24100) +++ trunk/src_plugins/cam/cam.c (revision 24101) @@ -57,7 +57,7 @@ char *argv[128]; /* [0] and [1] are for --cam; the rest point into args */ int argc; - char *old_base; + void *old_vars; gds_t tmp; } cam_ctx_t; @@ -65,23 +65,22 @@ static void cam_init_inst(cam_ctx_t *ctx) { memset(ctx, 0, sizeof(cam_ctx_t)); - ctx->old_base = pcb_cam_base; + ctx->old_vars = pcb_cam_init_vars(); + if (PCB->Filename != NULL) { - char *end = strrchr(PCB->Filename, PCB_DIR_SEPARATOR_C); + char *val, *end = strrchr(PCB->Filename, PCB_DIR_SEPARATOR_C); if (end != NULL) - pcb_cam_base = pcb_strdup(end+1); + val = pcb_strdup(end+1); else - pcb_cam_base = pcb_strdup(PCB->Filename); + val = pcb_strdup(PCB->Filename); + pcb_cam_set_var(pcb_strdup("base"), val); } - else - pcb_cam_base = NULL; } static void cam_uninit_inst(cam_ctx_t *ctx) { - free(pcb_cam_base); - pcb_cam_base = ctx->old_base; + pcb_cam_uninit_vars(ctx->old_vars); free(ctx->prefix); free(ctx->args); gds_uninit(&ctx->tmp); @@ -252,12 +251,7 @@ static int cam_parse_opt(cam_ctx_t *ctx, const char *opt) { - if (strncmp(opt, "base=", 5) == 0) { - free(pcb_cam_base); - pcb_cam_base = pcb_strdup(opt+5); - return 0; - } - else if (strncmp(opt, "outfile=", 8) == 0) { + if (strncmp(opt, "outfile=", 8) == 0) { char *fn, *tmp = pcb_strdup(opt+8); int dirlen = prefix_mkdir(tmp, &fn); @@ -270,11 +264,20 @@ } else ctx->prefix = NULL; - free(pcb_cam_base); - pcb_cam_base = pcb_strdup(fn); + pcb_cam_set_var(pcb_strdup("base"), pcb_strdup(fn)); free(tmp); return 0; } + else { + char *sep = strchr(opt, '='); + if (sep != NULL) { + char *key = pcb_strndup(opt, sep-opt); + char *val = pcb_strdup(sep+1); + pcb_cam_set_var(key, val); + return 0; + } + } + return 1; } Index: trunk/src_plugins/cam/cam.conf =================================================================== --- trunk/src_plugins/cam/cam.conf (revision 24100) +++ trunk/src_plugins/cam/cam.conf (revision 24101) @@ -6,8 +6,8 @@ doc_png { desc export top and bottom copper and silk in 600 DPI pngs plugin png --dpi 600 - write top.png=top-copper,top-silk - write bottom.png=bottom-copper,bottom-silk + write %base%.top.png=top-copper,top-silk + write %base%.bottom.png=bottom-copper,bottom-silk } {gerber:eagle} { desc gerber export compatible with Eagle's gerber file names Index: trunk/src_plugins/cam/cam_gui.c =================================================================== --- trunk/src_plugins/cam/cam_gui.c (revision 24100) +++ trunk/src_plugins/cam/cam_gui.c (revision 24101) @@ -91,6 +91,16 @@ pcb_dad_tree_update_hide(attr); } +static void cam_gui_export_cb(void *hid_ctx, void *caller_data, pcb_hid_attribute_t *attr_btn) +{ + cam_dlg_t *ctx = caller_data; + pcb_hid_attribute_t *attr = &ctx->dlg[ctx->wjobs]; + pcb_hid_row_t *row = pcb_dad_tree_get_selected(attr); + + if (row != NULL) + pcb_actionl("cam", "call", row->cell[0], NULL); +} + static void cam_job_select_cb(pcb_hid_attribute_t *attrib, void *hid_ctx, pcb_hid_row_t *row) { pcb_hid_tree_t *tree = (pcb_hid_tree_t *)attrib->enumerations; @@ -135,6 +145,7 @@ PCB_DAD_COMPFLAG(ctx->dlg, PCB_HATF_EXPFILL); PCB_DAD_END(ctx->dlg); PCB_DAD_BUTTON(ctx->dlg, "export!"); + PCB_DAD_CHANGE_CB(ctx->dlg, cam_gui_export_cb); PCB_DAD_END(ctx->dlg); PCB_DAD_END(ctx->dlg);