ref-filter: introduce contents_atom_parser()

Introduce contents_atom_parser() which will parse the '%(contents)' atom and store information into the 'used_atom' structure based on the modifiers used along with the atom. Also introduce body_atom_parser() and subject_atom_parser() for parsing atoms '%(body)' and '%(subject)' respectively. Helped-by: Ramsay Jones <ramsay@ramsayjones.plus.com> Helped-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Karthik Nayak <Karthik.188@gmail.com> Reviewed-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Karthik Nayak committed Feb 17, 2016 at 23:36 UTC 452db3973c7380808d6e000eff609825e0069105
1 file changed +50 -29
ref-filter.c
+50 -29
@@ -39,6 +39,10 @@ static struct used_atom {
39 struct align align;
40 enum { RR_NORMAL, RR_SHORTEN, RR_TRACK, RR_TRACKSHORT }
41 remote_ref;
42 + struct {
43 + enum { C_BARE, C_BODY, C_BODY_DEP, C_LINES, C_SIG, C_SUB } option;
44 + unsigned int nlines;
45 + } contents;
46 } u;
47 } *used_atom;
48 static int used_atom_cnt, need_tagged, need_symref;
@@ -66,6 +70,38 @@ static void remote_ref_atom_parser(struct used_atom *atom, const char *arg)
70 die(_("unrecognized format: %%(%s)"), atom->name);
71 }
72
73 +static void body_atom_parser(struct used_atom *atom, const char *arg)
74 +{
75 + if (arg)
76 + die("%%(body) does not take arguments");
77 + atom->u.contents.option = C_BODY_DEP;
78 +}
79 +
80 +static void subject_atom_parser(struct used_atom *atom, const char *arg)
81 +{
82 + if (arg)
83 + die("%%(subject) does not take arguments");
84 + atom->u.contents.option = C_SUB;
85 +}
86 +
87 +static void contents_atom_parser(struct used_atom *atom, const char *arg)
88 +{
89 + if (!arg)
90 + atom->u.contents.option = C_BARE;
91 + else if (!strcmp(arg, "body"))
92 + atom->u.contents.option = C_BODY;
93 + else if (!strcmp(arg, "signature"))
94 + atom->u.contents.option = C_SIG;
95 + else if (!strcmp(arg, "subject"))
96 + atom->u.contents.option = C_SUB;
97 + else if (skip_prefix(arg, "lines=", &arg)) {
98 + atom->u.contents.option = C_LINES;
99 + if (strtoul_ui(arg, 10, &atom->u.contents.nlines))
100 + die(_("positive value expected contents:lines=%s"), arg);
101 + } else
102 + die(_("unrecognized %%(contents) argument: %s"), arg);
103 +}
104 +
105 static align_type parse_align_position(const char *s)
106 {
107 if (!strcmp(s, "right"))
@@ -145,9 +181,9 @@ static struct {
181 { "taggerdate", FIELD_TIME },
182 { "creator" },
183 { "creatordate", FIELD_TIME },
148 - { "subject" },
149 - { "body" },
150 - { "contents" },
184 + { "subject", FIELD_STR, subject_atom_parser },
185 + { "body", FIELD_STR, body_atom_parser },
186 + { "contents", FIELD_STR, contents_atom_parser },
187 { "upstream", FIELD_STR, remote_ref_atom_parser },
188 { "push", FIELD_STR, remote_ref_atom_parser },
189 { "symref" },
@@ -160,11 +196,6 @@ static struct {
196
197 #define REF_FORMATTING_STATE_INIT { 0, NULL }
198
163 -struct contents {
164 - unsigned int lines;
165 - struct object_id oid;
166 -};
167 -
199 struct ref_formatting_stack {
200 struct ref_formatting_stack *prev;
201 struct strbuf output;
@@ -181,7 +212,6 @@ struct atom_value {
212 const char *s;
213 union {
214 struct align align;
184 - struct contents contents;
215 } u;
216 void (*handler)(struct atom_value *atomv, struct ref_formatting_state *state);
217 unsigned long ul; /* used for sorting when not FIELD_STR */
@@ -733,20 +763,16 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct obj
763 unsigned long sublen = 0, bodylen = 0, nonsiglen = 0, siglen = 0;
764
765 for (i = 0; i < used_atom_cnt; i++) {
736 - const char *name = used_atom[i].name;
766 + struct used_atom *atom = &used_atom[i];
767 + const char *name = atom->name;
768 struct atom_value *v = &val[i];
738 - const char *valp = NULL;
769 if (!!deref != (*name == '*'))
770 continue;
771 if (deref)
772 name++;
773 if (strcmp(name, "subject") &&
774 strcmp(name, "body") &&
745 - strcmp(name, "contents") &&
746 - strcmp(name, "contents:subject") &&
747 - strcmp(name, "contents:body") &&
748 - strcmp(name, "contents:signature") &&
749 - !starts_with(name, "contents:lines="))
775 + !starts_with(name, "contents"))
776 continue;
777 if (!subpos)
778 find_subpos(buf, sz,
@@ -754,28 +780,23 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct obj
780 &bodypos, &bodylen, &nonsiglen,
781 &sigpos, &siglen);
782
757 - if (!strcmp(name, "subject"))
758 - v->s = copy_subject(subpos, sublen);
759 - else if (!strcmp(name, "contents:subject"))
783 + if (atom->u.contents.option == C_SUB)
784 v->s = copy_subject(subpos, sublen);
761 - else if (!strcmp(name, "body"))
785 + else if (atom->u.contents.option == C_BODY_DEP)
786 v->s = xmemdupz(bodypos, bodylen);
763 - else if (!strcmp(name, "contents:body"))
787 + else if (atom->u.contents.option == C_BODY)
788 v->s = xmemdupz(bodypos, nonsiglen);
765 - else if (!strcmp(name, "contents:signature"))
789 + else if (atom->u.contents.option == C_SIG)
790 v->s = xmemdupz(sigpos, siglen);
767 - else if (!strcmp(name, "contents"))
768 - v->s = xstrdup(subpos);
769 - else if (skip_prefix(name, "contents:lines=", &valp)) {
791 + else if (atom->u.contents.option == C_LINES) {
792 struct strbuf s = STRBUF_INIT;
793 const char *contents_end = bodylen + bodypos - siglen;
794
773 - if (strtoul_ui(valp, 10, &v->u.contents.lines))
774 - die(_("positive value expected contents:lines=%s"), valp);
795 /* Size is the length of the message after removing the signature */
776 - append_lines(&s, subpos, contents_end - subpos, v->u.contents.lines);
796 + append_lines(&s, subpos, contents_end - subpos, atom->u.contents.nlines);
797 v->s = strbuf_detach(&s, NULL);
778 - }
798 + } else if (atom->u.contents.option == C_BARE)
799 + v->s = xstrdup(subpos);
800 }
801 }
802