410
410
vstring_free(buf);
414
* Helper for macro expansion callback.
416
struct dict_eval_context {
417
const char *dict_name; /* where to look */
418
VSTRING *buf; /* result buffer */
419
int recursive; /* recursive or not */
422
/* dict_eval_action - macro parser call-back routine */
424
static int dict_eval_action(int type, VSTRING *buf, char *ptr)
413
/* dict_eval_lookup - macro parser call-back routine */
415
static const char *dict_eval_lookup(const char *key, int unused_type,
426
struct dict_eval_context *ctxt = (struct dict_eval_context *) ptr;
427
char *myname = "dict_eval_action";
431
msg_info("%s: type %s buf %s context %s \"%s\" %s",
432
myname, type == MAC_PARSE_VARNAME ? "variable" : "literal",
433
STR(buf), ctxt->dict_name, STR(ctxt->buf),
434
ctxt->recursive ? "recursive" : "non-recursive");
437
* In order to support recursion, we must save the dict_lookup() result.
438
* We use the input buffer since it will not be needed anymore.
421
* XXX how would one recover?
440
if (type == MAC_PARSE_VARNAME) {
441
if ((pp = dict_lookup(ctxt->dict_name, STR(buf))) == 0) {
442
if (dict_errno) /* XXX how would one recover? */
443
msg_fatal("dictionary %s: lookup %s: temporary error",
444
ctxt->dict_name, STR(buf));
445
} else if (ctxt->recursive) {
446
vstring_strcpy(buf, pp); /* XXX clobber input */
447
dict_eval(ctxt->dict_name, STR(buf), ctxt->recursive);
449
vstring_strcat(ctxt->buf, pp);
452
vstring_strcat(ctxt->buf, STR(buf));
423
if ((pp = dict_lookup(dict_name, key)) == 0 && dict_errno != 0)
424
msg_fatal("dictionary %s: lookup %s: temporary error", dict_name, key);
457
429
/* dict_eval - expand embedded dictionary references */
459
431
const char *dict_eval(const char *dict_name, const char *value, int recursive)
433
const char *myname = "dict_eval";
461
434
static VSTRING *buf;
462
static struct dict_eval_context ctxt;
469
msg_fatal("unreasonable macro nesting: \"%s\"", value);
475
441
buf = vstring_alloc(10);
479
ctxt.recursive = recursive;
480
ctxt.dict_name = dict_name;
483
444
* Expand macros, possibly recursively.
486
msg_info("dict_eval[%d] %s", loop, value);
488
mac_parse(value, dict_eval_action, (char *) &ctxt);
491
msg_info("dict_eval[%d] result %s", loop, STR(buf));
497
VSTRING_TERMINATE(buf);
446
#define DONT_FILTER (char *) 0
448
status = mac_expand(buf, value,
449
recursive ? MAC_EXP_FLAG_RECURSE : MAC_EXP_FLAG_NONE,
450
DONT_FILTER, dict_eval_lookup, (char *) dict_name);
451
if (status & MAC_PARSE_ERROR)
452
msg_fatal("dictionary %s: macro processing error", dict_name);
454
if (strcmp(value, STR(buf)) != 0)
455
msg_info("%s: expand %s -> %s", myname, value, STR(buf));
457
msg_info("%s: const %s", myname, value);
499
459
return (STR(buf));