diff options
| author | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-06-09 14:04:08 -0400 |
|---|---|---|
| committer | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-06-09 14:04:08 -0400 |
| commit | a3837b5d6eea45ea50a1489485cb26f1333e3a4a (patch) | |
| tree | 4996f56a15b52268318fb19d3065fa95de1a17aa /src/format.c | |
| parent | 68aa41b079b6e37adb6e0c3f39e5ccb349b282d7 (diff) | |
- add support for '#'/'##'/'%'/'%%' in attribute value specifications, a la bash
Diffstat (limited to 'src/format.c')
| -rw-r--r-- | src/format.c | 139 |
1 files changed, 116 insertions, 23 deletions
diff --git a/src/format.c b/src/format.c index 929e49a..ff8be5f 100644 --- a/src/format.c +++ b/src/format.c @@ -1247,6 +1247,67 @@ xstrndupp(const char *start, const char *end) return ret; } +/* Trim off prefixes or suffixes which match the given patterns, free the + * original, and return the result. */ +static char * +format_trim_value(char *tmp, + const char *shortstart, const char *longstart, + const char *shortend, const char *longend) +{ + char *ret; + int i, len; + ret = strdup(tmp); + len = strlen(tmp); + if (ret != NULL) { + if (shortstart) { + for (i = 0; i < len; i++) { + memcpy(ret, tmp, i); + ret[i] = '\0'; + if (fnmatch(shortstart, ret, 0) == 0) { + strcpy(ret, tmp + i); + free(tmp); + return ret; + } + } + } + if (shortend) { + for (i = 1; i <= len; i++) { + strcpy(ret, tmp + len - i); + if (fnmatch(shortend, ret, 0) == 0) { + strcpy(ret, tmp); + ret[len - i] = '\0'; + free(tmp); + return ret; + } + } + } + if (longstart) { + for (i = 1; i <= len; i++) { + memcpy(ret, tmp, (len - i)); + ret[len - i] = '\0'; + if (fnmatch(longstart, ret, 0) == 0) { + strcpy(ret, tmp + (len - i)); + free(tmp); + return ret; + } + } + } + if (longend) { + for (i = 0; i < len; i++) { + strcpy(ret, tmp + i); + if (fnmatch(longend, ret, 0) == 0) { + strcpy(ret, tmp); + ret[i] = '\0'; + free(tmp); + return ret; + } + } + } + free(ret); + } + return tmp; +} + /* 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 @@ -1260,10 +1321,11 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, { int i, j; int exp_used, exp_size, level; - const char *fmtstart, *fmtend, *match, *attribute; + const char *fmtstart, *fmtend, *match, *attribute, *p; char *tmp, *fnname, *spd_id; char *expr; const char *default_value, *alternate_value, *paramstart, *paramend; + const char *shortstart, *longstart, *shortend, *longend; size_t spn; int (*formatfn)(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, @@ -1493,32 +1555,59 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, return -ENOBUFS; } } else { - /* It's a simple expression, so evaluate it. 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. */ + shortstart = NULL; + longstart = NULL; + shortend = NULL; + longend = 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, "#", 1)) { + shortstart = p + 1; + } + else if (strncmp(p, "%", 1)) { + shortend = p + 1; + } 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; + } 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. */ @@ -1552,6 +1641,10 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, free(expr); return i; } else { + /* Munge up the looked-up value. */ + tmp = format_trim_value(tmp, + shortstart, longstart, + shortend, longend); /* Supply the looked-up value. */ i = strlen(tmp); if (i <= outbuf_len) { |
