diff options
author | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-10-24 17:56:26 -0400 |
---|---|---|
committer | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-10-24 17:56:26 -0400 |
commit | 154dd3cb503050cc41927f1c6fed99b0336789b9 (patch) | |
tree | 3940e8fee337753ea892057c7e629f9693d35360 /src/format.c | |
parent | 985474b5203566ce7b3cb17eef406e6d049ebe97 (diff) | |
download | slapi-nis-154dd3cb503050cc41927f1c6fed99b0336789b9.tar.gz slapi-nis-154dd3cb503050cc41927f1c6fed99b0336789b9.tar.xz slapi-nis-154dd3cb503050cc41927f1c6fed99b0336789b9.zip |
- add an %ifelse function
- fix a bug in function argument parsing
Diffstat (limited to 'src/format.c')
-rw-r--r-- | src/format.c | 94 |
1 files changed, 89 insertions, 5 deletions
diff --git a/src/format.c b/src/format.c index e0d6e06..9926c07 100644 --- a/src/format.c +++ b/src/format.c @@ -849,7 +849,7 @@ format_first(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, } } if ((int) lengths[first] > outbuf_len) { - ret = -ENOSPC; + ret = -ENOBUFS; } else { memcpy(outbuf, values[first], lengths[first]); ret = lengths[first]; @@ -2128,6 +2128,89 @@ format_regsub(struct plugin_state *state, "format_regsub", format_regsub_cb); } +/* If the expression given by the first argument evaluates to the value given + * in the second, return the third, else return the fourth. */ +static int +format_ifelse(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, + const char *group, const char *set, + const char *args, const char *disallowed, + char *outbuf, int outbuf_len, + struct format_choice **outbuf_choices, + char ***ref_attrs, struct format_inref_attr ***inref_attrs, + struct format_ref_attr_list ***ref_attr_list, + struct format_ref_attr_list ***inref_attr_list) +{ + int ret, argc; + unsigned int expression_len, value_len, result_len; + char **argv, *expression, *value, *result; + bool_t matched; + + ret = format_parse_args(state, args, &argc, &argv); + if (argc < 1) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "ifelse: error parsing arguments\n"); + return -EINVAL; + } + if (argc != 4) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "ifelse: expected four arguments (got %d)\n", + argc); + return -EINVAL; + } + expression = format_get_data(state, e, group, set, argv[0], + disallowed, + ref_attrs, inref_attrs, + ref_attr_list, inref_attr_list, + &expression_len); + if (expression == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "ifelse: error evaluating \"%s\"\n", argv[0]); + format_free_parsed_args(argv); + return -EINVAL; + } + value = format_get_data(state, e, group, set, argv[1], + disallowed, + ref_attrs, inref_attrs, + ref_attr_list, inref_attr_list, + &value_len); + if (value == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "ifelse: error evaluating \"%s\"\n", argv[1]); + format_free_data(expression); + format_free_parsed_args(argv); + return -EINVAL; + } + matched = (expression_len == value_len) && + (memcmp(expression, value, value_len) == 0); + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "ifelse: \"%s\" %s \"%s\"\n", + expression, matched ? "matches" : "doesn't match", + value); + format_free_data(expression); + format_free_data(value); + result = format_get_data(state, e, group, set, argv[matched ? 2 : 3], + disallowed, + ref_attrs, inref_attrs, + ref_attr_list, inref_attr_list, + &result_len); + if (result == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "ifelse: error evaluating \"%s\"\n", + argv[matched ? 2 : 3]); + format_free_parsed_args(argv); + return -EINVAL; + } + format_free_parsed_args(argv); + if ((int) result_len > outbuf_len) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "ifelse: out of space\n"); + return -ENOBUFS; + } + memcpy(outbuf, result, result_len); + format_free_data(result); + return result_len; +} + /* Choose a formatting function by name. */ static void * format_lookup_fn(const char *fnname) @@ -2155,6 +2238,7 @@ format_lookup_fn(const char *fnname) {"match", format_match}, {"regmatch", format_regmatch}, {"regsub", format_regsub}, + {"ifelse", format_ifelse}, }; for (i = 0; i < sizeof(fns) / sizeof(fns[0]); i++) { if ((fns[i].name != NULL) && @@ -2268,7 +2352,7 @@ format_find_closer(const char *pair, const char *pattern) int i, dq, level = 0; for (i = 0, dq = 0; pattern[i] != '\0'; i++) { if (pattern[i] == '\\') { - i += 2; + i++; continue; } if (pattern[i] == '"') { @@ -2283,9 +2367,9 @@ format_find_closer(const char *pair, const char *pattern) level--; } } - } - if (level == 0) { - return &pattern[i]; + if (level == 0) { + return &pattern[i]; + } } } return NULL; |