summaryrefslogtreecommitdiffstats
path: root/src/format.c
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-06-09 14:04:08 -0400
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-06-09 14:04:08 -0400
commita3837b5d6eea45ea50a1489485cb26f1333e3a4a (patch)
tree4996f56a15b52268318fb19d3065fa95de1a17aa /src/format.c
parent68aa41b079b6e37adb6e0c3f39e5ccb349b282d7 (diff)
- add support for '#'/'##'/'%'/'%%' in attribute value specifications, a la bash
Diffstat (limited to 'src/format.c')
-rw-r--r--src/format.c139
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) {