Index: trunk/src/hid_cam.c =================================================================== --- trunk/src/hid_cam.c (revision 24105) +++ trunk/src/hid_cam.c (revision 24106) @@ -594,31 +594,37 @@ } -void *pcb_cam_init_vars(void) +void *pcb_cam_vars_alloc(void) { - void *old = pcb_cam_vars; - pcb_cam_vars = htsp_alloc(strhash, strkeyeq); - return old; + return htsp_alloc(strhash, strkeyeq); } -void pcb_cam_uninit_vars(void *as_inited) +void pcb_cam_vars_free(void *ctx) { + htsp_t *vars = ctx; htsp_entry_t *e; - for(e = htsp_first(pcb_cam_vars); e != NULL; e = htsp_next(pcb_cam_vars, e)) { + for(e = htsp_first(vars); e != NULL; e = htsp_next(vars, e)) { free(e->key); free(e->value); } - htsp_free(pcb_cam_vars); - pcb_cam_vars = as_inited; + htsp_free(vars); } -void pcb_cam_set_var(char *key, char *val) +void *pcb_cam_vars_use(void *new_vars) { - htsp_entry_t *e = htsp_popentry(pcb_cam_vars, key); + void *old = pcb_cam_vars; + pcb_cam_vars = new_vars; + return old; +} + +void pcb_cam_set_var(void *ctx, char *key, char *val) +{ + htsp_t *vars = ctx; + htsp_entry_t *e = htsp_popentry(vars, key); if (e != NULL) { free(e->key); free(e->value); } - htsp_set(pcb_cam_vars, key, val); + htsp_set(vars, key, val); } Index: trunk/src/hid_cam.h =================================================================== --- trunk/src/hid_cam.h (revision 24105) +++ trunk/src/hid_cam.h (revision 24106) @@ -49,14 +49,18 @@ /*** 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); +/* Allocate or free a var context, in which pcb_cam_set_var() operates and + which then can be 'used' for exporting. */ +void *pcb_cam_vars_alloc(void); +void pcb_cam_vars_free(void *ctx); +/* Use new_vars for the next export; returns the old var context that the + caller needs to restore (with another call to this function) after the export. */ +void *pcb_cam_vars_use(void *new_vars); + /* 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); +void pcb_cam_set_var(void *ctx, char *key, char *val); /*** Obsolete file suffix API - new plugins should not use this ***/ Index: trunk/src_plugins/cam/cam.c =================================================================== --- trunk/src_plugins/cam/cam.c (revision 24105) +++ trunk/src_plugins/cam/cam.c (revision 24106) @@ -57,7 +57,7 @@ char *argv[128]; /* [0] and [1] are for --cam; the rest point into args */ int argc; - void *old_vars; + void *vars; gds_t tmp; } cam_ctx_t; @@ -66,7 +66,7 @@ { memset(ctx, 0, sizeof(cam_ctx_t)); - ctx->old_vars = pcb_cam_init_vars(); + ctx->vars = pcb_cam_vars_alloc(); if (PCB->Filename != NULL) { char *val, *end = strrchr(PCB->Filename, PCB_DIR_SEPARATOR_C); @@ -74,13 +74,13 @@ val = pcb_strdup(end+1); else val = pcb_strdup(PCB->Filename); - pcb_cam_set_var(pcb_strdup("base"), val); + pcb_cam_set_var(ctx->vars, pcb_strdup("base"), val); } } static void cam_uninit_inst(cam_ctx_t *ctx) { - pcb_cam_uninit_vars(ctx->old_vars); + pcb_cam_vars_free(ctx->vars); free(ctx->prefix); free(ctx->args); gds_uninit(&ctx->tmp); @@ -118,9 +118,8 @@ return res; } -static int cam_exec_inst(void *ctx_, char *cmd, char *arg) +static int cam_exec_inst(cam_ctx_t *ctx, char *cmd, char *arg) { - cam_ctx_t *ctx = ctx_; char *curr, *next; char **argv = ctx->argv; @@ -198,11 +197,13 @@ } /* Parse and execute a script */ -static int cam_exec(const char *script_in, int (*exec)(void *ctx, char *cmd, char *arg), void *ctx) +static int cam_exec(cam_ctx_t *ctx, const char *script_in, int (*exec)(cam_ctx_t *ctxctx, char *cmd, char *arg)) { char *arg, *curr, *next, *script = pcb_strdup(script_in); int res = 0; + void *old_vars, *tmp; + old_vars = pcb_cam_vars_use(ctx->vars); for(curr = script; curr != NULL; curr = next) { while(isspace(*curr)) curr++; next = strpbrk(curr, ";\r\n"); @@ -220,6 +221,9 @@ res |= exec(ctx, curr, arg); } + tmp = pcb_cam_vars_use(old_vars); + assert(tmp == ctx->vars); /* we must be restoring from our own context else the recursion is broken */ + free(script); return res; } @@ -243,7 +247,7 @@ const char *script = cam_find_job(job); if (script != NULL) - return cam_exec(script, cam_exec_inst, ctx); + return cam_exec(ctx, script, cam_exec_inst); pcb_message(PCB_MSG_ERROR, "cam: can not find job configuration '%s'\n", job); return -1; @@ -263,7 +267,7 @@ } else ctx->prefix = NULL; - pcb_cam_set_var(pcb_strdup("base"), pcb_strdup(fn)); + pcb_cam_set_var(ctx->vars, pcb_strdup("base"), pcb_strdup(fn)); free(tmp); return 0; } @@ -278,7 +282,7 @@ if (sep != NULL) { char *key = pcb_strndup(opt, sep-opt); char *val = pcb_strdup(sep+1); - pcb_cam_set_var(key, val); + pcb_cam_set_var(ctx->vars, key, val); return 0; } } @@ -321,7 +325,7 @@ return 0; } if (pcb_strcasecmp(cmd, "exec") == 0) - rs = cam_exec(arg, cam_exec_inst, &ctx); + rs = cam_exec(&ctx, arg, cam_exec_inst); else if (pcb_strcasecmp(cmd, "call") == 0) rs = cam_call(arg, &ctx); }