summaryrefslogtreecommitdiffstats
path: root/src/format.c
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-10-24 17:56:26 -0400
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-10-24 17:56:26 -0400
commit154dd3cb503050cc41927f1c6fed99b0336789b9 (patch)
tree3940e8fee337753ea892057c7e629f9693d35360 /src/format.c
parent985474b5203566ce7b3cb17eef406e6d049ebe97 (diff)
downloadslapi-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.c94
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;