the list of user-defined format placeholders has grown steadily longer since they were first introduced. We currently have about forty placeholders, and the room for new mnemonics is growing scarce. To make more room, we introduce "long forms" for placeholders, which take the form: '%(' <label> [ ':' <arg> [ ',' <arg> ]* ] ')' eg: %(wrap: 80, 0, 4) We start by adding a long-form to the %w(...) placeholder, mostly because as it already takes multiple arguments, it is a good example. Signed-off-by: Will Palmer <wmpalmer@xxxxxxxxx> --- Documentation/pretty-formats.txt | 1 + pretty.c | 47 +++++++++++++++++++++++++++++++++----- test-pretty.c | 1 + 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt index 561cc9f..c9f3fb6 100644 --- a/Documentation/pretty-formats.txt +++ b/Documentation/pretty-formats.txt @@ -144,6 +144,7 @@ The placeholders are: - '%x00': print a byte from a hex code - '%w([<w>[,<i1>[,<i2>]]])': switch line wrapping, like the -w option of linkgit:git-shortlog[1]. +- '%(wrap:[<w>[,<i1>[,<i2>]]])': alternative form of %w(...) NOTE: Some placeholders may depend on other options given to the revision traversal engine. For example, the `%g*` reflog options will diff --git a/pretty.c b/pretty.c index cb02879..8301008 100644 --- a/pretty.c +++ b/pretty.c @@ -108,12 +108,10 @@ const char *parse_arg(struct format_part *part, enum format_arg_type type, arg.type = type; c += strspn(c, WHITESPACE); - if (!isdigit(*c)) - return NULL; - arg.uint = strtoul(c, &t, 10); - if (t == c) - return NULL; - c = t + strspn(t, WHITESPACE); + if (isdigit(*c)) { + arg.uint = strtoul(c, &t, 10); + c = t + strspn(t, WHITESPACE); + } if (*c == ',' || *c == ')'){ ALLOC_GROW(part->args, part->argc+1, part->args_alloc); memcpy(&(part->args[part->argc]), &arg, @@ -124,6 +122,41 @@ const char *parse_arg(struct format_part *part, enum format_arg_type type, return NULL; } +static struct format_part *parse_extended(const char *unparsed) +{ + struct format_part *part = format_part_alloc(); + const char *c = unparsed + 2; /* "%(..." + strlen("%(") */ + + c += strspn(c, WHITESPACE); + + if (!prefixcmp(c, "wrap")) { + part->type = FORMAT_PART_WRAP; + c += 4; + while(part->argc <= 3){ + c += strspn(c, WHITESPACE); + if (*c == ')') + goto success; + if (*c != (part->argc ? ',' : ':')) + goto fail; + if (part->argc == 3) + goto fail; + + c = parse_arg(part, FORMAT_ARG_UINT, c+1); + if (!c) + goto fail; + } + goto fail; + } + +fail: + format_part_free(&part); + return NULL; + +success: + part->format_len = c - unparsed + 1; + return part; +} + static struct format_part *parse_special(const char *unparsed) { struct format_part *part = NULL; @@ -156,6 +189,8 @@ static struct format_part *parse_special(const char *unparsed) } } return part; + case '(': + return parse_extended(unparsed); } part = format_part_alloc(); diff --git a/test-pretty.c b/test-pretty.c index 57c1c65..64a8218 100644 --- a/test-pretty.c +++ b/test-pretty.c @@ -17,6 +17,7 @@ static const char *all = "a" "%gD%gd%gs" "%Cred%Cgreen%Cblue%Creset%C(reset)" "%m%w()%w(1)%w(1,2)%w(1,2,3)" +"%(wrap)%(wrap:1)%(wrap:1,2)%(wrap:1,2,3)" "%x0a%n%%%@"; static struct strbuf *parts_debug(struct format_parts *parts, -- 1.7.4.2 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html