summaryrefslogtreecommitdiffstats
path: root/format.c
diff options
context:
space:
mode:
authornicm <nicm>2020-11-09 09:10:10 +0000
committernicm <nicm>2020-11-09 09:10:10 +0000
commit61e55fa50dc7119a8c88bb385e615a8e6c8d6a85 (patch)
treece341e040b1c21fb3a076b29496f686e689cc982 /format.c
parent1326529f99366e7d438364fd8727ec132a2f7433 (diff)
Change how escaping is processed for formats so that ## and # can be
used in styles. Also add a 'w' format modifier for the width. From Chas J Owens IV in GitHub issue 2389.
Diffstat (limited to 'format.c')
-rw-r--r--format.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/format.c b/format.c
index 99efbc1c..91955259 100644
--- a/format.c
+++ b/format.c
@@ -98,6 +98,7 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2)
#define FORMAT_PANES 0x200
#define FORMAT_PRETTY 0x400
#define FORMAT_LENGTH 0x800
+#define FORMAT_WIDTH 0x1000
/* Limit on recursion. */
#define FORMAT_LOOP_LIMIT 10
@@ -1671,7 +1672,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s,
/*
* Modifiers are a ; separated list of the forms:
- * l,m,C,b,d,n,t,q,E,T,S,W,P,<,>
+ * l,m,C,b,d,n,t,w,q,E,T,S,W,P,<,>
* =a
* =/a
* =/a/
@@ -1688,7 +1689,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s,
cp++;
/* Check single character modifiers with no arguments. */
- if (strchr("lbdnqETSWP<>", cp[0]) != NULL &&
+ if (strchr("lbdnqwETSWP<>", cp[0]) != NULL &&
format_is_end(cp[1])) {
format_add_modifier(&list, count, cp, 1, NULL, 0);
cp++;
@@ -2184,6 +2185,9 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
if (errptr != NULL)
width = 0;
break;
+ case 'w':
+ modifiers |= FORMAT_WIDTH;
+ break;
case 'e':
if (fm->argc < 1 || fm->argc > 3)
break;
@@ -2456,13 +2460,19 @@ done:
format_log(es, "applied padding width %d: %s", width, value);
}
- /* Replace with the length if needed. */
+ /* Replace with the length or width if needed. */
if (modifiers & FORMAT_LENGTH) {
xasprintf(&new, "%zu", strlen(value));
free(value);
value = new;
format_log(es, "replacing with length: %s", new);
}
+ if (modifiers & FORMAT_WIDTH) {
+ xasprintf(&new, "%u", format_width(value));
+ free(value);
+ value = new;
+ format_log(es, "replacing with width: %s", new);
+ }
/* Expand the buffer and copy in the value. */
valuelen = strlen(value);
@@ -2589,8 +2599,30 @@ format_expand1(struct format_expand_state *es, const char *fmt)
break;
fmt += n + 1;
continue;
- case '}':
case '#':
+ /*
+ * If ##[ (with two or more #s), then it is a style and
+ * can be left for format_draw to handle.
+ */
+ ptr = fmt;
+ n = 2;
+ while (*ptr == '#') {
+ ptr++;
+ n++;
+ }
+ if (*ptr == '[') {
+ format_log(es, "found #*%zu[", n);
+ while (len - off < n + 2) {
+ buf = xreallocarray(buf, 2, len);
+ len *= 2;
+ }
+ memcpy(buf + off, fmt - 2, n + 1);
+ off += n + 1;
+ fmt = ptr + 1;
+ continue;
+ }
+ /* FALLTHROUGH */
+ case '}':
case ',':
format_log(es, "found #%c", ch);
while (len - off < 2) {