diff options
| author | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-06-09 18:55:56 -0400 |
|---|---|---|
| committer | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-06-09 18:55:56 -0400 |
| commit | 91296180405086d4e840db85efee86fb3cb00533 (patch) | |
| tree | 1791409207e2ead78096a545893e15fd49ed63c5 /src | |
| parent | 126e591e81f05c801387468db2f3659d29763565 (diff) | |
| download | slapi-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.c | 394 |
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; } } } |
