179 #define MAC_EXP_BVAL_TRUE "true"
180 #define MAC_EXP_BVAL_FALSE ""
185 #define MAC_EXP_OP_STR_EQ "=="
186 #define MAC_EXP_OP_STR_NE "!="
187 #define MAC_EXP_OP_STR_LT "<"
188 #define MAC_EXP_OP_STR_LE "<="
189 #define MAC_EXP_OP_STR_GE ">="
190 #define MAC_EXP_OP_STR_GT ">"
191 #define MAC_EXP_OP_STR_ANY "\"" MAC_EXP_OP_STR_EQ \
192 "\" or \"" MAC_EXP_OP_STR_NE "\"" \
193 "\" or \"" MAC_EXP_OP_STR_LT "\"" \
194 "\" or \"" MAC_EXP_OP_STR_LE "\"" \
195 "\" or \"" MAC_EXP_OP_STR_GE "\"" \
196 "\" or \"" MAC_EXP_OP_STR_GT "\""
198 #define MAC_EXP_OP_TOK_NONE 0
199 #define MAC_EXP_OP_TOK_EQ 1
200 #define MAC_EXP_OP_TOK_NE 2
201 #define MAC_EXP_OP_TOK_LT 3
202 #define MAC_EXP_OP_TOK_LE 4
203 #define MAC_EXP_OP_TOK_GE 5
204 #define MAC_EXP_OP_TOK_GT 6
206 static const NAME_CODE mac_exp_op_table[] =
220 #define MAC_EXP_WHITESPACE CHARS_SPACE
224 static long atol_or_die(
const char *strval)
229 result = strtol(strval, &remainder, 10);
230 if (*strval == 0 || *remainder != 0 || errno == ERANGE)
231 msg_fatal(
"mac_exp_eval: bad conversion: %s", strval);
237 static int mac_exp_eval(
const char *left,
int tok_val,
240 static const char myname[] =
"mac_exp_eval";
247 delta = atol_or_die(left) - atol_or_die(rite);
249 delta = strcmp(left, rite);
285 #define MAC_EXP_ERR_RETURN(mc, fmt, ...) do { \
286 return (mac_exp_parse_error(mc, fmt, __VA_ARGS__)); \
308 #define MAC_EXP_FIND_LEFT_CURLY(len, cp) \
309 ((cp[len = strspn(cp, MAC_EXP_WHITESPACE)] == '{') ? \
314 static char *mac_exp_extract_curly_payload(
MAC_EXP_CONTEXT *mc,
char **bp)
325 for (level = 1, cp = *bp, payload = ++cp; ; cp++) {
326 if ((ch = *cp) == 0) {
327 mac_exp_parse_error(mc,
"unbalanced {} in attribute expression: "
331 }
else if (ch ==
'{') {
333 }
else if (ch ==
'}') {
349 static int mac_exp_parse_relational(
MAC_EXP_CONTEXT *mc,
const char **lookup,
355 const char *left_op_strval;
356 const char *rite_op_strval;
368 if ((left_op_strval = mac_exp_extract_curly_payload(mc, &cp)) == 0)
375 op_len = strspn(cp,
"<>!=?+-*/~&|%");
389 "\"...{%s} %.*s>>>%.20s\"",
390 left_op_strval, (
int) op_len, op_pos, cp);
391 if ((rite_op_strval = mac_exp_extract_curly_payload(mc, &cp)) == 0)
403 op_result = mac_exp_eval(
vstring_str(left_op_buf), op_tokval,
422 static int mac_expand_callback(
int type,
VSTRING *buf,
void *ptr)
424 static const char myname[] =
"mac_expand_callback";
432 const char *res_iftrue;
433 const char *res_iffalse;
438 if (mc->
level++ > 100)
439 mac_exp_parse_error(mc,
"unreasonable macro call nesting: \"%s\"",
457 if (mac_exp_parse_relational(mc, &lookup, &cp) != 0)
463 if ((ch = *cp) != 0) {
464 if (ch !=
'?' && ch !=
':')
466 "\"...}>>>%.20s\"", cp);
488 if (ch ==
'?' || ch ==
':') {
495 if (!
ISALNUM(ch) && ch !=
'_') {
497 "\"...%.*s>>>%.20s\"",
523 if ((res_iftrue = mac_exp_extract_curly_payload(mc, &cp)) == 0)
536 "\"...%s}>>>%.20s\"", res_iftrue, cp);
541 if ((res_iffalse = mac_exp_extract_curly_payload(mc, &cp)) == 0)
552 "\"...%s}>>>%.20s\"", res_iffalse, cp);
570 while (*(cp += strspn(cp, mc->
filter)))
576 msg_panic(
"%s: unknown operator code %d", myname, ch);
612 status =
mac_parse(pattern, mac_expand_callback, (
void *) &mc);
630 static const char *lookup(
const char *name,
int unused_mode,
void *context)
637 int main(
int unused_argc,
char **unused_argv)
676 (
char *) 0, lookup, (
void *) table);
void htable_free(HTABLE *table, void(*free_fn)(void *))
#define MAC_EXP_WHITESPACE
#define MAC_EXP_FLAG_PRINTABLE
char * mystrdup(const char *str)
int mac_expand(VSTRING *result, const char *pattern, int flags, const char *filter, MAC_EXP_LOOKUP_FN lookup, void *context)
#define MAC_EXP_OP_STR_ANY
int vstring_get_nonl(VSTRING *vp, VSTREAM *fp)
#define MAC_EXP_OP_STR_GE
NORETURN msg_panic(const char *fmt,...)
#define MAC_EXP_FLAG_SCAN
int main(int argc, char **argv)
#define MAC_EXP_OP_STR_GT
#define MAC_EXP_OP_TOK_GE
#define MAC_EXP_FLAG_RECURSE
#define MAC_EXP_OP_TOK_NONE
int alldig(const char *string)
#define MAC_EXP_OP_TOK_EQ
char * mystrtok(char **src, const char *sep)
VSTRING * vstring_strcpy(VSTRING *vp, const char *src)
#define VSTRING_TERMINATE(vp)
HTABLE * htable_create(ssize_t size)
#define MAC_EXP_ERR_RETURN(mc, fmt,...)
#define MAC_EXP_BVAL_FALSE
#define MAC_EXP_OP_TOK_GT
#define MAC_EXP_OP_TOK_LT
#define MAC_EXP_FLAG_NONE
const char *(* MAC_EXP_LOOKUP_FN)(const char *, int, void *)
#define MAC_EXP_OP_STR_LT
#define MAC_EXP_OP_TOK_LE
#define MAC_EXP_BVAL_TRUE
VSTREAM * vstream_printf(const char *fmt,...)
#define VSTRING_RESET(vp)
#define MAC_EXP_MODE_TEST
#define MAC_EXP_FIND_LEFT_CURLY(len, cp)
VSTRING * vstring_alloc(ssize_t len)
#define NAME_CODE_FLAG_NONE
void * htable_find(HTABLE *table, const char *key)
int name_code(const NAME_CODE *table, int flags, const char *name)
void vmsg_warn(const char *fmt, va_list ap)
NORETURN msg_fatal(const char *fmt,...)
int vstream_fflush(VSTREAM *stream)
int mac_parse(const char *value, MAC_PARSE_FN action, void *context)
char * mystrndup(const char *str, ssize_t len)
#define MAC_EXP_OP_TOK_NE
#define MAC_EXP_OP_STR_NE
VSTRING * vstring_free(VSTRING *vp)
#define MAC_EXP_OP_STR_LE
#define MAC_EXP_OP_STR_EQ
#define MAC_EXP_FLAG_APPEND
char * printable(char *string, int replacement)
VSTRING * vstring_strcat(VSTRING *vp, const char *src)
HTABLE_INFO * htable_enter(HTABLE *table, const char *key, void *value)