@@ -39,6 +39,10 @@ static struct used_atom {
3939 struct align align ;
4040 enum { RR_NORMAL , RR_SHORTEN , RR_TRACK , RR_TRACKSHORT }
4141 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 ;
4246 } u ;
4347} * used_atom ;
4448static 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)
6670 die (_ ("unrecognized format: %%(%s)" ), atom -> name );
6771}
6872
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+
69105static align_type parse_align_position (const char * s )
70106{
71107 if (!strcmp (s , "right" ))
@@ -145,9 +181,9 @@ static struct {
145181 { "taggerdate" , FIELD_TIME },
146182 { "creator" },
147183 { "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 },
151187 { "upstream" , FIELD_STR , remote_ref_atom_parser },
152188 { "push" , FIELD_STR , remote_ref_atom_parser },
153189 { "symref" },
@@ -160,11 +196,6 @@ static struct {
160196
161197#define REF_FORMATTING_STATE_INIT { 0, NULL }
162198
163- struct contents {
164- unsigned int lines ;
165- struct object_id oid ;
166- };
167-
168199struct ref_formatting_stack {
169200 struct ref_formatting_stack * prev ;
170201 struct strbuf output ;
@@ -181,7 +212,6 @@ struct atom_value {
181212 const char * s ;
182213 union {
183214 struct align align ;
184- struct contents contents ;
185215 } u ;
186216 void (* handler )(struct atom_value * atomv , struct ref_formatting_state * state );
187217 unsigned long ul ; /* used for sorting when not FIELD_STR */
@@ -733,49 +763,40 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct obj
733763 unsigned long sublen = 0 , bodylen = 0 , nonsiglen = 0 , siglen = 0 ;
734764
735765 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 ;
737768 struct atom_value * v = & val [i ];
738- const char * valp = NULL ;
739769 if (!!deref != (* name == '*' ))
740770 continue ;
741771 if (deref )
742772 name ++ ;
743773 if (strcmp (name , "subject" ) &&
744774 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" ))
750776 continue ;
751777 if (!subpos )
752778 find_subpos (buf , sz ,
753779 & subpos , & sublen ,
754780 & bodypos , & bodylen , & nonsiglen ,
755781 & sigpos , & siglen );
756782
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 )
760784 v -> s = copy_subject (subpos , sublen );
761- else if (! strcmp ( name , "body" ) )
785+ else if (atom -> u . contents . option == C_BODY_DEP )
762786 v -> s = xmemdupz (bodypos , bodylen );
763- else if (! strcmp ( name , " contents:body" ) )
787+ else if (atom -> u . contents . option == C_BODY )
764788 v -> s = xmemdupz (bodypos , nonsiglen );
765- else if (! strcmp ( name , " contents:signature" ) )
789+ else if (atom -> u . contents . option == C_SIG )
766790 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 ) {
770792 struct strbuf s = STRBUF_INIT ;
771793 const char * contents_end = bodylen + bodypos - siglen ;
772794
773- if (strtoul_ui (valp , 10 , & v -> u .contents .lines ))
774- die (_ ("positive value expected contents:lines=%s" ), valp );
775795 /* 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 );
777797 v -> s = strbuf_detach (& s , NULL );
778- }
798+ } else if (atom -> u .contents .option == C_BARE )
799+ v -> s = xstrdup (subpos );
779800 }
780801}
781802
0 commit comments