summaryrefslogtreecommitdiff
path: root/ref-filter.c
diff options
context:
space:
mode:
authorLibravatar Karthik Nayak <karthik.188@gmail.com>2015-09-11 20:34:16 +0530
committerLibravatar Junio C Hamano <gitster@pobox.com>2015-09-17 10:02:48 -0700
commit1bb38e5a6a8fb6cf9b882a1a7038d649ceba0085 (patch)
tree8a0b9e69aadeb9f1b27fcb9a6698e82234507b98 /ref-filter.c
parentref-filter: add option to filter out tags, branches and remotes (diff)
downloadtgif-1bb38e5a6a8fb6cf9b882a1a7038d649ceba0085.tar.xz
ref-filter: add support for %(contents:lines=X)
In 'tag.c' we can print N lines from the annotation of the tag using the '-n<num>' option. Copy code from 'tag.c' to 'ref-filter' and modify it to support appending of N lines from the annotation of tags to the given strbuf. Implement %(contents:lines=X) where X lines of the given object are obtained. While we're at it, remove unused "contents:<suboption>" atoms from the `valid_atom` array. Add documentation and test for the same. Mentored-by: Christian Couder <christian.couder@gmail.com> Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr> Signed-off-by: Karthik Nayak <karthik.188@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'ref-filter.c')
-rw-r--r--ref-filter.c47
1 files changed, 43 insertions, 4 deletions
diff --git a/ref-filter.c b/ref-filter.c
index f046d826bd..32aab37d36 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -45,9 +45,6 @@ static struct {
{ "subject" },
{ "body" },
{ "contents" },
- { "contents:subject" },
- { "contents:body" },
- { "contents:signature" },
{ "upstream" },
{ "push" },
{ "symref" },
@@ -65,6 +62,11 @@ struct align {
unsigned int width;
};
+struct contents {
+ unsigned int lines;
+ struct object_id oid;
+};
+
struct ref_formatting_stack {
struct ref_formatting_stack *prev;
struct strbuf output;
@@ -81,6 +83,7 @@ struct atom_value {
const char *s;
union {
struct align align;
+ struct contents contents;
} u;
void (*handler)(struct atom_value *atomv, struct ref_formatting_state *state);
unsigned long ul; /* used for sorting when not FIELD_STR */
@@ -643,6 +646,30 @@ static void find_subpos(const char *buf, unsigned long sz,
*nonsiglen = *sig - buf;
}
+/*
+ * If 'lines' is greater than 0, append that many lines from the given
+ * 'buf' of length 'size' to the given strbuf.
+ */
+static void append_lines(struct strbuf *out, const char *buf, unsigned long size, int lines)
+{
+ int i;
+ const char *sp, *eol;
+ size_t len;
+
+ sp = buf;
+
+ for (i = 0; i < lines && sp < buf + size; i++) {
+ if (i)
+ strbuf_addstr(out, "\n ");
+ eol = memchr(sp, '\n', size - (sp - buf));
+ len = eol ? eol - sp : size - (sp - buf);
+ strbuf_add(out, sp, len);
+ if (!eol)
+ break;
+ sp = eol + 1;
+ }
+}
+
/* See grab_values */
static void grab_sub_body_contents(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
{
@@ -653,6 +680,7 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct obj
for (i = 0; i < used_atom_cnt; i++) {
const char *name = used_atom[i];
struct atom_value *v = &val[i];
+ const char *valp = NULL;
if (!!deref != (*name == '*'))
continue;
if (deref)
@@ -662,7 +690,8 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct obj
strcmp(name, "contents") &&
strcmp(name, "contents:subject") &&
strcmp(name, "contents:body") &&
- strcmp(name, "contents:signature"))
+ strcmp(name, "contents:signature") &&
+ !starts_with(name, "contents:lines="))
continue;
if (!subpos)
find_subpos(buf, sz,
@@ -682,6 +711,16 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct obj
v->s = xmemdupz(sigpos, siglen);
else if (!strcmp(name, "contents"))
v->s = xstrdup(subpos);
+ else if (skip_prefix(name, "contents:lines=", &valp)) {
+ struct strbuf s = STRBUF_INIT;
+ const char *contents_end = bodylen + bodypos - siglen;
+
+ if (strtoul_ui(valp, 10, &v->u.contents.lines))
+ die(_("positive value expected contents:lines=%s"), valp);
+ /* Size is the length of the message after removing the signature */
+ append_lines(&s, subpos, contents_end - subpos, v->u.contents.lines);
+ v->s = strbuf_detach(&s, NULL);
+ }
}
}