summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-06-09 18:55:56 -0400
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-06-09 18:55:56 -0400
commit91296180405086d4e840db85efee86fb3cb00533 (patch)
tree1791409207e2ead78096a545893e15fd49ed63c5 /src
parent126e591e81f05c801387468db2f3659d29763565 (diff)
downloadslapi-nis-91296180405086d4e840db85efee86fb3cb00533.tar.gz
slapi-nis-91296180405086d4e840db85efee86fb3cb00533.tar.xz
slapi-nis-91296180405086d4e840db85efee86fb3cb00533.zip
- finish cleaning up variable substitution
Diffstat (limited to 'src')
-rw-r--r--src/format.c394
1 files changed, 216 insertions, 178 deletions
diff --git a/src/format.c b/src/format.c
index 6ee102e..d706bd4 100644
--- a/src/format.c
+++ b/src/format.c
@@ -53,7 +53,7 @@ static int format_expand(struct plugin_state *state,
char *outbuf, int outbuf_len,
char ***ref_attrs,
struct format_inref_attr ***inref_attrs,
- bool_t is_expression);
+ bool_t is_simple_expression);
void
format_free_data(char *data)
@@ -1263,29 +1263,35 @@ format_trim_value(struct plugin_state *state, char *input,
if (ret != NULL) {
if (forbidden) {
/* Any forbidden character rejects this value. */
- if (strcspn(ret, forbidden) != strlen(ret)) {
+ if (strcspn(input, forbidden) != (size_t) len) {
slapi_log_error(SLAPI_LOG_PLUGIN,
state->plugin_desc->spd_id,
- "trim: value \"%s\" contains "
+ "trim-f: value \"%s\" contains "
"forbidden character '%c'\n",
- ret,
- ret + strcspn(ret, forbidden));
+ input,
+ input + strcspn(input,
+ forbidden));
free(ret);
free(input);
return NULL;
+ } else {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "trim-f: ->%s<- => ->%s<-\n",
+ input, input);
}
}
if (shortstart) {
/* The shortest initial substring which matches gets
* skipped. */
- for (i = 0; i < len; i++) {
+ for (i = 0; i <= len; i++) {
memcpy(ret, input, i);
ret[i] = '\0';
if (fnmatch(shortstart, ret, 0) == 0) {
strcpy(ret, input + i);
slapi_log_error(SLAPI_LOG_PLUGIN,
state->plugin_desc->spd_id,
- "trim: ->%s<- => "
+ "trim-ss: ->%s<- => "
"->%s<-\n",
input, ret);
free(input);
@@ -1296,14 +1302,14 @@ format_trim_value(struct plugin_state *state, char *input,
if (shortend) {
/* The shortest ending substring which matches gets
* snipped. */
- for (i = 1; i <= len; i++) {
+ for (i = 0; i <= len; i++) {
strcpy(ret, input + len - i);
if (fnmatch(shortend, ret, 0) == 0) {
strcpy(ret, input);
ret[len - i] = '\0';
slapi_log_error(SLAPI_LOG_PLUGIN,
state->plugin_desc->spd_id,
- "trim: ->%s<- => "
+ "trim-se: ->%s<- => "
"->%s<-\n",
input, ret);
free(input);
@@ -1314,14 +1320,14 @@ format_trim_value(struct plugin_state *state, char *input,
if (longstart) {
/* The longest initial substring which matches gets
* skipped. */
- for (i = 1; i <= len; i++) {
+ for (i = 0; i <= len; i++) {
memcpy(ret, input, (len - i));
ret[len - i] = '\0';
if (fnmatch(longstart, ret, 0) == 0) {
strcpy(ret, input + (len - i));
slapi_log_error(SLAPI_LOG_PLUGIN,
state->plugin_desc->spd_id,
- "trim: ->%s<- => "
+ "trim-ls: ->%s<- => "
"->%s<-\n",
input, ret);
free(input);
@@ -1332,14 +1338,14 @@ format_trim_value(struct plugin_state *state, char *input,
if (longend) {
/* The longest ending substring which matches gets
* snipped. */
- for (i = 0; i < len; i++) {
+ for (i = 0; i <= len; i++) {
strcpy(ret, input + i);
if (fnmatch(longend, ret, 0) == 0) {
strcpy(ret, input);
ret[i] = '\0';
slapi_log_error(SLAPI_LOG_PLUGIN,
state->plugin_desc->spd_id,
- "trim: ->%s<- => "
+ "trim-le: ->%s<- => "
"->%s<-\n",
input, ret);
free(input);
@@ -1364,10 +1370,9 @@ format_trim_value(struct plugin_state *state, char *input,
strcpy(ret + j, input + i);
for (k = strlen(ret + j); k > 0; k--) {
ret[j + k] = '\0';
- if (fnmatch(ret + j, replaceall, 0)) {
+ if (fnmatch(replace, ret + j, 0) == 0) {
strcpy(ret + j, replaceval);
- j += (strlen(replaceval) - 1);
- i += (k - 1);
+ strcat(ret + j, input + i + k);
replaceval = NULL;
break;
}
@@ -1375,7 +1380,8 @@ format_trim_value(struct plugin_state *state, char *input,
}
slapi_log_error(SLAPI_LOG_PLUGIN,
state->plugin_desc->spd_id,
- "trim: ->%s<- => ->%s<-\n", input, ret);
+ "trim-r: ->%s<- => ->%s<-\n",
+ input, ret);
free(input);
return ret;
}
@@ -1393,7 +1399,8 @@ format_trim_value(struct plugin_state *state, char *input,
strcpy(ret + j, input + i);
for (k = strlen(ret + j); k > 0; k--) {
ret[j + k] = '\0';
- if (fnmatch(ret + j, replaceall, 0)) {
+ if (fnmatch(replaceall, ret + j,
+ 0) == 0) {
strcpy(ret + j, replaceval);
j += (strlen(replaceval) - 1);
i += (k - 1);
@@ -1403,7 +1410,8 @@ format_trim_value(struct plugin_state *state, char *input,
}
slapi_log_error(SLAPI_LOG_PLUGIN,
state->plugin_desc->spd_id,
- "trim: ->%s<- => ->%s<-\n", input, ret);
+ "trim-r+: ->%s<- => ->%s<-\n",
+ input, ret);
free(input);
return ret;
}
@@ -1412,6 +1420,163 @@ format_trim_value(struct plugin_state *state, char *input,
return input;
}
+/* Expand the simple expression into the output buffer. This is limited to one
+ * attribute value, perhaps with a default or alternate value, perhaps with a
+ * prefix or suffix stripped, perhaps with internal replacements made. */
+static int
+format_expand_simple(struct plugin_state *state,
+ Slapi_PBlock *pb, Slapi_Entry *e,
+ const char *domain, const char *map,
+ const char *fmt, char *outbuf, int outbuf_len,
+ char ***ref_attrs, struct format_inref_attr ***inref_attrs)
+{
+ char *shortstart, *longstart, *shortend, *longend;
+ char *replace, *replaceall, *replaceval, *forbidden, *tmp, *expr, *p;
+ const char *attribute, *default_value, *alternate_value;
+ size_t spn;
+ int i;
+ shortstart = NULL;
+ longstart = NULL;
+ shortend = NULL;
+ longend = NULL;
+ replace = NULL;
+ replaceall = NULL;
+ replaceval = NULL;
+ forbidden = NULL;
+ expr = strdup(fmt);
+ /* It's a simple expression, so evaluate it. Check for substitutions
+ * and text to be stripped if the magic character occurs before the
+ * default/alternate signals. */
+ if (strcspn(expr, "#%/!") < strcspn(expr, ":")) {
+ spn = strcspn(expr, "#%/!");
+ p = expr + spn;
+ if (strncmp(p, "##", 2) == 0) {
+ longstart = p + 2;
+ }
+ else if (strncmp(p, "%%", 2) == 0) {
+ longend = p + 2;
+ }
+ else if (strncmp(p, "//", 2) == 0) {
+ replaceall = p + 2;
+ }
+ else if (strncmp(p, "#", 1) == 0) {
+ shortstart = p + 1;
+ }
+ else if (strncmp(p, "%", 1) == 0) {
+ shortend = p + 1;
+ }
+ else if (strncmp(p, "/", 1) == 0) {
+ replace = p + 1;
+ }
+ else if (strncmp(p, "!", 1) == 0) {
+ forbidden = p + 1;
+ }
+ expr[spn] = '\0';
+ if ((replace != NULL) || (replaceall != NULL)) {
+ replaceval = NULL;
+ if (replace != NULL) {
+ spn = strcspn(replace, "/");
+ replaceval = replace + spn;
+ }
+ if (replaceall != NULL) {
+ spn = strcspn(replaceall, "/");
+ replaceval = replaceall + spn;
+ }
+ if ((replaceval != NULL) &&
+ (*replaceval != '\0')) {
+ *replaceval = '\0';
+ replaceval++;
+ }
+ }
+ attribute = expr;
+ alternate_value = NULL;
+ default_value = NULL;
+ } else {
+ /* Check if it uses a default/alternate value. */
+ spn = strcspn(expr, ":");
+ if (spn == strlen(expr)) {
+ /* Plain old variable, no alternate or default value.
+ * */
+ attribute = expr;
+ alternate_value = NULL;
+ default_value = NULL;
+ } else {
+ /* Make a copy of the attribute name. */
+ expr[spn] = '\0';
+ attribute = expr;
+ alternate_value = NULL;
+ default_value = NULL;
+ /* Figure out if there's an alternate or default value
+ * given. */
+ switch (expr[spn + 1]) {
+ case '+':
+ alternate_value = expr + spn + 2;
+ break;
+ case '-':
+ default_value = expr + spn + 2;
+ break;
+ default:
+ default_value = expr + spn + 1;
+ break;
+ }
+ }
+ }
+ /* Retrieve the value. */
+ tmp = format_single(state, pb, e, attribute);
+ if (tmp == NULL) {
+ /* The attribute is undefined, or we're treating it as if it
+ * is. */
+ if (default_value != NULL) {
+ /* Supply the default value, expanding it if needed. */
+ i = format_expand(state, pb, e,
+ domain, map, default_value,
+ outbuf, outbuf_len,
+ ref_attrs, inref_attrs, FALSE);
+ free(expr);
+ return i;
+ } else {
+ /* No value, and no default: FAIL. */
+ free(expr);
+ return -ENOENT;
+ }
+ } else {
+ /* There's no value defined (or it's multi-valued, which is
+ * usually trouble). */
+ if (alternate_value != NULL) {
+ /* Supply the alternate value. */
+ i = format_expand(state, pb, e,
+ domain, map, alternate_value,
+ outbuf, outbuf_len,
+ ref_attrs, inref_attrs, FALSE);
+ free(tmp);
+ free(expr);
+ return i;
+ } else {
+ /* Munge up the looked-up value. */
+ tmp = format_trim_value(state, tmp,
+ shortstart, longstart,
+ shortend, longend,
+ replace, replaceall,
+ replaceval, forbidden);
+ /* Supply the looked-up value. */
+ if (tmp != NULL) {
+ i = strlen(tmp);
+ if (i <= outbuf_len) {
+ memcpy(outbuf, tmp, i);
+ }
+ free(tmp);
+ free(expr);
+ return i;
+ } else {
+ /* No useful value: FAIL. */
+ free(expr);
+ return -ENOENT;
+ }
+ }
+ }
+ /* not reached */
+}
+
/* Recursively expand the expression into the output buffer. adding any entries
* we visit (other than e) to the list of visited NDNs. If the result will
* also be an expression, treat the entire result as an attribute specifier and
@@ -1421,7 +1586,7 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
const char *domain, const char *map, const char *fmt,
char *outbuf, int outbuf_len,
char ***ref_attrs, struct format_inref_attr ***inref_attrs,
- bool_t is_expression)
+ bool_t is_simple_expression)
{
int i, j;
int exp_used, exp_size, level;
@@ -1448,11 +1613,11 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
return -ENOMEM;
}
- /* First, expand any subexpressions and call any "functions". */
+ /* Expand any subexpressions and call any "functions". */
level = 0;
i = 0;
j = 0;
- while (fmt[i] != '\0') {
+ while ((fmt[i] != '\0') && (j < exp_size)) {
switch (fmt[i]) {
case '%':
/* This might be a subexpression, a "function" call, or
@@ -1465,9 +1630,10 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
continue;
break;
case '{':
- /* Find the beginning of the subexpression. */
+ /* Find the beginning of the simple expression.
+ */
fmtstart = fmt + i;
- /* Find the end of the subexpression. */
+ /* Find the end of the simple expression. */
match = format_find_closer("{}", fmtstart + 1);
if (match == NULL) {
slapi_log_error(SLAPI_LOG_PLUGIN,
@@ -1478,9 +1644,10 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
return -EINVAL;
} else {
/* Mark the first character after the
- * subexpression. */
+ * simple expression. */
fmtend = match + 1;
- /* Make a copy of the subexpression. */
+ /* Make a copy of the simple
+ * expression. */
tmp = xstrndupp(fmtstart + 2,
fmtend - 1);
if (tmp == NULL) {
@@ -1492,16 +1659,16 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
free(expr);
return -ENOMEM;
}
- /* Recursively expand the
- * subexpression. */
- exp_used = format_expand(state, pb, e,
- domain, map,
- tmp,
- expr + j,
- exp_size - j,
- ref_attrs,
- inref_attrs,
- TRUE);
+ /* Expand the simple expression. */
+ exp_used = format_expand_simple(state,
+ pb, e,
+ domain,
+ map,
+ tmp,
+ expr + j,
+ exp_size - j,
+ ref_attrs,
+ inref_attrs);
if (exp_used < 0) {
/* Miscellaneous failure, FAIL.
*/
@@ -1648,154 +1815,25 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
}
expr[j] = '\0';
- if (!is_expression) {
- /* The result is literal text, so we're done. */
- i = strlen(expr);
- if (i <= outbuf_len) {
- memcpy(outbuf, expr, i);
+ if (is_simple_expression) {
+ exp_used = format_expand_simple(state, pb, e, domain, map,
+ expr, outbuf, outbuf_len,
+ ref_attrs, inref_attrs);
+ if (exp_used < 0) {
free(expr);
- return i;
+ return exp_used;
} else {
free(expr);
- return -ENOBUFS;
+ return j + exp_used;
}
} else {
- shortstart = NULL;
- longstart = NULL;
- shortend = NULL;
- longend = NULL;
- replace = NULL;
- replaceall = NULL;
- replaceval = NULL;
- forbidden = NULL;
- /* It's a simple expression, so evaluate it. Check for
- * substitutions. */
- spn = strcspn(expr, "#%/!");
- if (spn != strlen(expr)) {
- p = expr + spn;
- if (strncmp(p, "##", 2)) {
- longstart = p + 2;
- }
- else if (strncmp(p, "%%", 2)) {
- longend = p + 2;
- }
- else if (strncmp(p, "//", 2)) {
- replaceall = p + 2;
- }
- else if (strncmp(p, "#", 1)) {
- shortstart = p + 1;
- }
- else if (strncmp(p, "%", 1)) {
- shortend = p + 1;
- }
- else if (strncmp(p, "/", 1)) {
- replace = p + 1;
- }
- else if (strncmp(p, "!", 1)) {
- forbidden = p + 1;
- }
- expr[spn] = '\0';
- if ((replace != NULL) || (replaceall != NULL)) {
- replaceval = NULL;
- if (replace != NULL) {
- spn = strcspn(replace, "/");
- replaceval = replace + spn;
- }
- if (replaceall != NULL) {
- spn = strcspn(replaceall, "/");
- replaceval = replaceall + spn;
- }
- if ((replaceval != NULL) &&
- (*replaceval != '\0')) {
- *replaceval = '\0';
- replaceval++;
- }
- }
- attribute = expr;
- alternate_value = NULL;
- default_value = NULL;
- } else {
- /* Check if it uses a default/alternate value. */
- spn = strcspn(expr, ":");
- if (spn == strlen(expr)) {
- /* Plain old variable, no alternate or default
- * value. */
- attribute = expr;
- alternate_value = NULL;
- default_value = NULL;
- } else {
- /* Make a copy of the attribute name. */
- expr[spn] = '\0';
- attribute = expr;
- alternate_value = NULL;
- default_value = NULL;
- /* Figure out if there's an alternate or
- * default value given. */
- switch (expr[spn + 1]) {
- case '+':
- alternate_value = expr + spn + 2;
- break;
- case '-':
- default_value = expr + spn + 2;
- break;
- default:
- default_value = expr + spn + 1;
- break;
- }
- }
- }
- /* Retrieve the value. */
- tmp = format_single(state, pb, e, attribute);
- if (tmp == NULL) {
- /* The attribute is undefined, or we're treating it as
- * if it is. */
- if (default_value != NULL) {
- /* Supply the default value. */
- i = strlen(default_value);
- if (i <= outbuf_len) {
- memcpy(outbuf, default_value, i);
- }
- free(expr);
- return i;
- } else {
- /* No value, and no default: FAIL. */
- free(expr);
- return -ENOENT;
- }
+ if (outbuf_len < j) {
+ free(expr);
+ return -ENOBUFS;
} else {
- /* There's no value defined (or it's
- * multi-valued, which is usually trouble). */
- if (alternate_value != NULL) {
- /* Supply the alternate value. */
- i = strlen(alternate_value);
- if (i <= outbuf_len) {
- memcpy(outbuf, alternate_value, i);
- }
- free(tmp);
- free(expr);
- return i;
- } else {
- /* Munge up the looked-up value. */
- tmp = format_trim_value(state, tmp,
- shortstart, longstart,
- shortend, longend,
- replace, replaceall,
- replaceval, forbidden);
- /* Supply the looked-up value. */
- if (tmp != NULL) {
- i = strlen(tmp);
- if (i <= outbuf_len) {
- memcpy(outbuf, tmp, i);
- }
- free(tmp);
- free(expr);
- return i;
- } else {
- /* No useful value: FAIL. */
- free(expr);
- return -ENOENT;
- }
- }
+ memcpy(outbuf, expr, j);
+ free(expr);
+ return j;
}
}
}