@@ -108,6 +108,56 @@ static struct ref_to_worktree_map {
108108 struct worktree * * worktrees ;
109109} ref_to_worktree_map ;
110110
111+ /*
112+ * The enum atom_type is used as the index of valid_atom array.
113+ * In the atom parsing stage, it will be passed to used_atom.atom_type
114+ * as the identifier of the atom type. We can check the type of used_atom
115+ * entry by `if (used_atom[i].atom_type == ATOM_*)`.
116+ */
117+ enum atom_type {
118+ ATOM_REFNAME ,
119+ ATOM_OBJECTTYPE ,
120+ ATOM_OBJECTSIZE ,
121+ ATOM_OBJECTNAME ,
122+ ATOM_DELTABASE ,
123+ ATOM_TREE ,
124+ ATOM_PARENT ,
125+ ATOM_NUMPARENT ,
126+ ATOM_OBJECT ,
127+ ATOM_TYPE ,
128+ ATOM_TAG ,
129+ ATOM_AUTHOR ,
130+ ATOM_AUTHORNAME ,
131+ ATOM_AUTHOREMAIL ,
132+ ATOM_AUTHORDATE ,
133+ ATOM_COMMITTER ,
134+ ATOM_COMMITTERNAME ,
135+ ATOM_COMMITTEREMAIL ,
136+ ATOM_COMMITTERDATE ,
137+ ATOM_TAGGER ,
138+ ATOM_TAGGERNAME ,
139+ ATOM_TAGGEREMAIL ,
140+ ATOM_TAGGERDATE ,
141+ ATOM_CREATOR ,
142+ ATOM_CREATORDATE ,
143+ ATOM_SUBJECT ,
144+ ATOM_BODY ,
145+ ATOM_TRAILERS ,
146+ ATOM_CONTENTS ,
147+ ATOM_UPSTREAM ,
148+ ATOM_PUSH ,
149+ ATOM_SYMREF ,
150+ ATOM_FLAG ,
151+ ATOM_HEAD ,
152+ ATOM_COLOR ,
153+ ATOM_WORKTREEPATH ,
154+ ATOM_ALIGN ,
155+ ATOM_END ,
156+ ATOM_IF ,
157+ ATOM_THEN ,
158+ ATOM_ELSE ,
159+ };
160+
111161/*
112162 * An atom is a valid field atom listed below, possibly prefixed with
113163 * a "*" to denote deref_tag().
@@ -119,6 +169,7 @@ static struct ref_to_worktree_map {
119169 * array.
120170 */
121171static struct used_atom {
172+ enum atom_type atom_type ;
122173 const char * name ;
123174 cmp_type type ;
124175 info_source source ;
@@ -146,6 +197,9 @@ static struct used_atom {
146197 enum { O_FULL , O_LENGTH , O_SHORT } option ;
147198 unsigned int length ;
148199 } oid ;
200+ struct {
201+ enum { O_SIZE , O_SIZE_DISK } option ;
202+ } objectsize ;
149203 struct email_option {
150204 enum { EO_RAW , EO_TRIM , EO_LOCALPART } option ;
151205 } email_option ;
@@ -269,11 +323,13 @@ static int objectsize_atom_parser(const struct ref_format *format, struct used_a
269323 const char * arg , struct strbuf * err )
270324{
271325 if (!arg ) {
326+ atom -> u .objectsize .option = O_SIZE ;
272327 if (* atom -> name == '*' )
273328 oi_deref .info .sizep = & oi_deref .size ;
274329 else
275330 oi .info .sizep = & oi .size ;
276331 } else if (!strcmp (arg , "disk" )) {
332+ atom -> u .objectsize .option = O_SIZE_DISK ;
277333 if (* atom -> name == '*' )
278334 oi_deref .info .disk_sizep = & oi_deref .disk_size ;
279335 else
@@ -501,47 +557,47 @@ static struct {
501557 int (* parser )(const struct ref_format * format , struct used_atom * atom ,
502558 const char * arg , struct strbuf * err );
503559} valid_atom [] = {
504- { "refname" , SOURCE_NONE , FIELD_STR , refname_atom_parser },
505- { "objecttype" , SOURCE_OTHER , FIELD_STR , objecttype_atom_parser },
506- { "objectsize" , SOURCE_OTHER , FIELD_ULONG , objectsize_atom_parser },
507- { "objectname" , SOURCE_OTHER , FIELD_STR , oid_atom_parser },
508- { "deltabase" , SOURCE_OTHER , FIELD_STR , deltabase_atom_parser },
509- { "tree" , SOURCE_OBJ , FIELD_STR , oid_atom_parser },
510- { "parent" , SOURCE_OBJ , FIELD_STR , oid_atom_parser },
511- { "numparent" , SOURCE_OBJ , FIELD_ULONG },
512- { "object" , SOURCE_OBJ },
513- { "type" , SOURCE_OBJ },
514- { "tag" , SOURCE_OBJ },
515- { "author" , SOURCE_OBJ },
516- { "authorname" , SOURCE_OBJ },
517- { "authoremail" , SOURCE_OBJ , FIELD_STR , person_email_atom_parser },
518- { "authordate" , SOURCE_OBJ , FIELD_TIME },
519- { "committer" , SOURCE_OBJ },
520- { "committername" , SOURCE_OBJ },
521- { "committeremail" , SOURCE_OBJ , FIELD_STR , person_email_atom_parser },
522- { "committerdate" , SOURCE_OBJ , FIELD_TIME },
523- { "tagger" , SOURCE_OBJ },
524- { "taggername" , SOURCE_OBJ },
525- { "taggeremail" , SOURCE_OBJ , FIELD_STR , person_email_atom_parser },
526- { "taggerdate" , SOURCE_OBJ , FIELD_TIME },
527- { "creator" , SOURCE_OBJ },
528- { "creatordate" , SOURCE_OBJ , FIELD_TIME },
529- { "subject" , SOURCE_OBJ , FIELD_STR , subject_atom_parser },
530- { "body" , SOURCE_OBJ , FIELD_STR , body_atom_parser },
531- { "trailers" , SOURCE_OBJ , FIELD_STR , trailers_atom_parser },
532- { "contents" , SOURCE_OBJ , FIELD_STR , contents_atom_parser },
533- { "upstream" , SOURCE_NONE , FIELD_STR , remote_ref_atom_parser },
534- { "push" , SOURCE_NONE , FIELD_STR , remote_ref_atom_parser },
535- { "symref" , SOURCE_NONE , FIELD_STR , refname_atom_parser },
536- { "flag" , SOURCE_NONE },
537- { "HEAD" , SOURCE_NONE , FIELD_STR , head_atom_parser },
538- { "color" , SOURCE_NONE , FIELD_STR , color_atom_parser },
539- { "worktreepath" , SOURCE_NONE },
540- { "align" , SOURCE_NONE , FIELD_STR , align_atom_parser },
541- { "end" , SOURCE_NONE },
542- { "if" , SOURCE_NONE , FIELD_STR , if_atom_parser },
543- { "then" , SOURCE_NONE },
544- { "else" , SOURCE_NONE },
560+ [ ATOM_REFNAME ] = { "refname" , SOURCE_NONE , FIELD_STR , refname_atom_parser },
561+ [ ATOM_OBJECTTYPE ] = { "objecttype" , SOURCE_OTHER , FIELD_STR , objecttype_atom_parser },
562+ [ ATOM_OBJECTSIZE ] = { "objectsize" , SOURCE_OTHER , FIELD_ULONG , objectsize_atom_parser },
563+ [ ATOM_OBJECTNAME ] = { "objectname" , SOURCE_OTHER , FIELD_STR , oid_atom_parser },
564+ [ ATOM_DELTABASE ] = { "deltabase" , SOURCE_OTHER , FIELD_STR , deltabase_atom_parser },
565+ [ ATOM_TREE ] = { "tree" , SOURCE_OBJ , FIELD_STR , oid_atom_parser },
566+ [ ATOM_PARENT ] = { "parent" , SOURCE_OBJ , FIELD_STR , oid_atom_parser },
567+ [ ATOM_NUMPARENT ] = { "numparent" , SOURCE_OBJ , FIELD_ULONG },
568+ [ ATOM_OBJECT ] = { "object" , SOURCE_OBJ },
569+ [ ATOM_TYPE ] = { "type" , SOURCE_OBJ },
570+ [ ATOM_TAG ] = { "tag" , SOURCE_OBJ },
571+ [ ATOM_AUTHOR ] = { "author" , SOURCE_OBJ },
572+ [ ATOM_AUTHORNAME ] = { "authorname" , SOURCE_OBJ },
573+ [ ATOM_AUTHOREMAIL ] = { "authoremail" , SOURCE_OBJ , FIELD_STR , person_email_atom_parser },
574+ [ ATOM_AUTHORDATE ] = { "authordate" , SOURCE_OBJ , FIELD_TIME },
575+ [ ATOM_COMMITTER ] = { "committer" , SOURCE_OBJ },
576+ [ ATOM_COMMITTERNAME ] = { "committername" , SOURCE_OBJ },
577+ [ ATOM_COMMITTEREMAIL ] = { "committeremail" , SOURCE_OBJ , FIELD_STR , person_email_atom_parser },
578+ [ ATOM_COMMITTERDATE ] = { "committerdate" , SOURCE_OBJ , FIELD_TIME },
579+ [ ATOM_TAGGER ] = { "tagger" , SOURCE_OBJ },
580+ [ ATOM_TAGGERNAME ] = { "taggername" , SOURCE_OBJ },
581+ [ ATOM_TAGGEREMAIL ] = { "taggeremail" , SOURCE_OBJ , FIELD_STR , person_email_atom_parser },
582+ [ ATOM_TAGGERDATE ] = { "taggerdate" , SOURCE_OBJ , FIELD_TIME },
583+ [ ATOM_CREATOR ] = { "creator" , SOURCE_OBJ },
584+ [ ATOM_CREATORDATE ] = { "creatordate" , SOURCE_OBJ , FIELD_TIME },
585+ [ ATOM_SUBJECT ] = { "subject" , SOURCE_OBJ , FIELD_STR , subject_atom_parser },
586+ [ ATOM_BODY ] = { "body" , SOURCE_OBJ , FIELD_STR , body_atom_parser },
587+ [ ATOM_TRAILERS ] = { "trailers" , SOURCE_OBJ , FIELD_STR , trailers_atom_parser },
588+ [ ATOM_CONTENTS ] = { "contents" , SOURCE_OBJ , FIELD_STR , contents_atom_parser },
589+ [ ATOM_UPSTREAM ] = { "upstream" , SOURCE_NONE , FIELD_STR , remote_ref_atom_parser },
590+ [ ATOM_PUSH ] = { "push" , SOURCE_NONE , FIELD_STR , remote_ref_atom_parser },
591+ [ ATOM_SYMREF ] = { "symref" , SOURCE_NONE , FIELD_STR , refname_atom_parser },
592+ [ ATOM_FLAG ] = { "flag" , SOURCE_NONE },
593+ [ ATOM_HEAD ] = { "HEAD" , SOURCE_NONE , FIELD_STR , head_atom_parser },
594+ [ ATOM_COLOR ] = { "color" , SOURCE_NONE , FIELD_STR , color_atom_parser },
595+ [ ATOM_WORKTREEPATH ] = { "worktreepath" , SOURCE_NONE },
596+ [ ATOM_ALIGN ] = { "align" , SOURCE_NONE , FIELD_STR , align_atom_parser },
597+ [ ATOM_END ] = { "end" , SOURCE_NONE },
598+ [ ATOM_IF ] = { "if" , SOURCE_NONE , FIELD_STR , if_atom_parser },
599+ [ ATOM_THEN ] = { "then" , SOURCE_NONE },
600+ [ ATOM_ELSE ] = { "else" , SOURCE_NONE },
545601 /*
546602 * Please update $__git_ref_fieldlist in git-completion.bash
547603 * when you add new atoms
@@ -623,6 +679,7 @@ static int parse_ref_filter_atom(const struct ref_format *format,
623679 at = used_atom_cnt ;
624680 used_atom_cnt ++ ;
625681 REALLOC_ARRAY (used_atom , used_atom_cnt );
682+ used_atom [at ].atom_type = i ;
626683 used_atom [at ].name = xmemdupz (atom , ep - atom );
627684 used_atom [at ].type = valid_atom [i ].cmp_type ;
628685 used_atom [at ].source = valid_atom [i ].source ;
@@ -647,7 +704,7 @@ static int parse_ref_filter_atom(const struct ref_format *format,
647704 return -1 ;
648705 if (* atom == '*' )
649706 need_tagged = 1 ;
650- if (! strcmp ( valid_atom [ i ]. name , "symref" ) )
707+ if (i == ATOM_SYMREF )
651708 need_symref = 1 ;
652709 return at ;
653710}
@@ -960,22 +1017,25 @@ static void grab_common_values(struct atom_value *val, int deref, struct expand_
9601017
9611018 for (i = 0 ; i < used_atom_cnt ; i ++ ) {
9621019 const char * name = used_atom [i ].name ;
1020+ enum atom_type atom_type = used_atom [i ].atom_type ;
9631021 struct atom_value * v = & val [i ];
9641022 if (!!deref != (* name == '*' ))
9651023 continue ;
9661024 if (deref )
9671025 name ++ ;
968- if (! strcmp ( name , "objecttype" ) )
1026+ if (atom_type == ATOM_OBJECTTYPE )
9691027 v -> s = xstrdup (type_name (oi -> type ));
970- else if (!strcmp (name , "objectsize:disk" )) {
971- v -> value = oi -> disk_size ;
972- v -> s = xstrfmt ("%" PRIuMAX , (uintmax_t )oi -> disk_size );
973- } else if (!strcmp (name , "objectsize" )) {
974- v -> value = oi -> size ;
975- v -> s = xstrfmt ("%" PRIuMAX , (uintmax_t )oi -> size );
976- } else if (!strcmp (name , "deltabase" ))
1028+ else if (atom_type == ATOM_OBJECTSIZE ) {
1029+ if (used_atom [i ].u .objectsize .option == O_SIZE_DISK ) {
1030+ v -> value = oi -> disk_size ;
1031+ v -> s = xstrfmt ("%" PRIuMAX , (uintmax_t )oi -> disk_size );
1032+ } else if (used_atom [i ].u .objectsize .option == O_SIZE ) {
1033+ v -> value = oi -> size ;
1034+ v -> s = xstrfmt ("%" PRIuMAX , (uintmax_t )oi -> size );
1035+ }
1036+ } else if (atom_type == ATOM_DELTABASE )
9771037 v -> s = xstrdup (oid_to_hex (& oi -> delta_base_oid ));
978- else if (deref )
1038+ else if (atom_type == ATOM_OBJECTNAME && deref )
9791039 grab_oid (name , "objectname" , & oi -> oid , v , & used_atom [i ]);
9801040 }
9811041}
@@ -988,16 +1048,17 @@ static void grab_tag_values(struct atom_value *val, int deref, struct object *ob
9881048
9891049 for (i = 0 ; i < used_atom_cnt ; i ++ ) {
9901050 const char * name = used_atom [i ].name ;
1051+ enum atom_type atom_type = used_atom [i ].atom_type ;
9911052 struct atom_value * v = & val [i ];
9921053 if (!!deref != (* name == '*' ))
9931054 continue ;
9941055 if (deref )
9951056 name ++ ;
996- if (! strcmp ( name , "tag" ) )
1057+ if (atom_type == ATOM_TAG )
9971058 v -> s = xstrdup (tag -> tag );
998- else if (! strcmp ( name , "type" ) && tag -> tagged )
1059+ else if (atom_type == ATOM_TYPE && tag -> tagged )
9991060 v -> s = xstrdup (type_name (tag -> tagged -> type ));
1000- else if (! strcmp ( name , "object" ) && tag -> tagged )
1061+ else if (atom_type == ATOM_OBJECT && tag -> tagged )
10011062 v -> s = xstrdup (oid_to_hex (& tag -> tagged -> oid ));
10021063 }
10031064}
@@ -1010,18 +1071,20 @@ static void grab_commit_values(struct atom_value *val, int deref, struct object
10101071
10111072 for (i = 0 ; i < used_atom_cnt ; i ++ ) {
10121073 const char * name = used_atom [i ].name ;
1074+ enum atom_type atom_type = used_atom [i ].atom_type ;
10131075 struct atom_value * v = & val [i ];
10141076 if (!!deref != (* name == '*' ))
10151077 continue ;
10161078 if (deref )
10171079 name ++ ;
1018- if (grab_oid (name , "tree" , get_commit_tree_oid (commit ), v , & used_atom [i ]))
1080+ if (atom_type == ATOM_TREE &&
1081+ grab_oid (name , "tree" , get_commit_tree_oid (commit ), v , & used_atom [i ]))
10191082 continue ;
1020- if (! strcmp ( name , "numparent" ) ) {
1083+ if (atom_type == ATOM_NUMPARENT ) {
10211084 v -> value = commit_list_count (commit -> parents );
10221085 v -> s = xstrfmt ("%lu" , (unsigned long )v -> value );
10231086 }
1024- else if (starts_with ( name , "parent" ) ) {
1087+ else if (atom_type == ATOM_PARENT ) {
10251088 struct commit_list * parents ;
10261089 struct strbuf s = STRBUF_INIT ;
10271090 for (parents = commit -> parents ; parents ; parents = parents -> next ) {
@@ -1201,15 +1264,16 @@ static void grab_person(const char *who, struct atom_value *val, int deref, void
12011264 return ;
12021265 for (i = 0 ; i < used_atom_cnt ; i ++ ) {
12031266 const char * name = used_atom [i ].name ;
1267+ enum atom_type atom_type = used_atom [i ].atom_type ;
12041268 struct atom_value * v = & val [i ];
12051269 if (!!deref != (* name == '*' ))
12061270 continue ;
12071271 if (deref )
12081272 name ++ ;
12091273
1210- if (starts_with ( name , "creatordate" ) )
1274+ if (atom_type == ATOM_CREATORDATE )
12111275 grab_date (wholine , v , name );
1212- else if (! strcmp ( name , "creator" ) )
1276+ else if (atom_type == ATOM_CREATOR )
12131277 v -> s = copy_line (wholine );
12141278 }
12151279}
@@ -1689,6 +1753,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
16891753 /* Fill in specials first */
16901754 for (i = 0 ; i < used_atom_cnt ; i ++ ) {
16911755 struct used_atom * atom = & used_atom [i ];
1756+ enum atom_type atom_type = atom -> atom_type ;
16921757 const char * name = used_atom [i ].name ;
16931758 struct atom_value * v = & ref -> value [i ];
16941759 int deref = 0 ;
@@ -1703,18 +1768,18 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
17031768 name ++ ;
17041769 }
17051770
1706- if (starts_with ( name , "refname" ) )
1771+ if (atom_type == ATOM_REFNAME )
17071772 refname = get_refname (atom , ref );
1708- else if (! strcmp ( name , "worktreepath" ) ) {
1773+ else if (atom_type == ATOM_WORKTREEPATH ) {
17091774 if (ref -> kind == FILTER_REFS_BRANCHES )
17101775 v -> s = get_worktree_path (atom , ref );
17111776 else
17121777 v -> s = xstrdup ("" );
17131778 continue ;
17141779 }
1715- else if (starts_with ( name , "symref" ) )
1780+ else if (atom_type == ATOM_SYMREF )
17161781 refname = get_symref (atom , ref );
1717- else if (starts_with ( name , "upstream" ) ) {
1782+ else if (atom_type == ATOM_UPSTREAM ) {
17181783 const char * branch_name ;
17191784 /* only local branches may have an upstream */
17201785 if (!skip_prefix (ref -> refname , "refs/heads/" ,
@@ -1730,7 +1795,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
17301795 else
17311796 v -> s = xstrdup ("" );
17321797 continue ;
1733- } else if (! strcmp ( atom -> name , "push" ) || starts_with ( atom -> name , " push:" ) ) {
1798+ } else if (atom_type == ATOM_PUSH && atom -> u . remote_ref . push ) {
17341799 const char * branch_name ;
17351800 v -> s = xstrdup ("" );
17361801 if (!skip_prefix (ref -> refname , "refs/heads/" ,
@@ -1749,10 +1814,10 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
17491814 free ((char * )v -> s );
17501815 fill_remote_ref_details (atom , refname , branch , & v -> s );
17511816 continue ;
1752- } else if (starts_with ( name , "color:" ) ) {
1817+ } else if (atom_type == ATOM_COLOR ) {
17531818 v -> s = xstrdup (atom -> u .color );
17541819 continue ;
1755- } else if (! strcmp ( name , "flag" ) ) {
1820+ } else if (atom_type == ATOM_FLAG ) {
17561821 char buf [256 ], * cp = buf ;
17571822 if (ref -> flag & REF_ISSYMREF )
17581823 cp = copy_advance (cp , ",symref" );
@@ -1765,35 +1830,36 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
17651830 v -> s = xstrdup (buf + 1 );
17661831 }
17671832 continue ;
1768- } else if (!deref && grab_oid (name , "objectname" , & ref -> objectname , v , atom )) {
1769- continue ;
1770- } else if (!strcmp (name , "HEAD" )) {
1833+ } else if (!deref && atom_type == ATOM_OBJECTNAME &&
1834+ grab_oid (name , "objectname" , & ref -> objectname , v , atom )) {
1835+ continue ;
1836+ } else if (atom_type == ATOM_HEAD ) {
17711837 if (atom -> u .head && !strcmp (ref -> refname , atom -> u .head ))
17721838 v -> s = xstrdup ("*" );
17731839 else
17741840 v -> s = xstrdup (" " );
17751841 continue ;
1776- } else if (starts_with ( name , "align" ) ) {
1842+ } else if (atom_type == ATOM_ALIGN ) {
17771843 v -> handler = align_atom_handler ;
17781844 v -> s = xstrdup ("" );
17791845 continue ;
1780- } else if (! strcmp ( name , "end" ) ) {
1846+ } else if (atom_type == ATOM_END ) {
17811847 v -> handler = end_atom_handler ;
17821848 v -> s = xstrdup ("" );
17831849 continue ;
1784- } else if (starts_with ( name , "if" ) ) {
1850+ } else if (atom_type == ATOM_IF ) {
17851851 const char * s ;
17861852 if (skip_prefix (name , "if:" , & s ))
17871853 v -> s = xstrdup (s );
17881854 else
17891855 v -> s = xstrdup ("" );
17901856 v -> handler = if_atom_handler ;
17911857 continue ;
1792- } else if (! strcmp ( name , "then" ) ) {
1858+ } else if (atom_type == ATOM_THEN ) {
17931859 v -> handler = then_atom_handler ;
17941860 v -> s = xstrdup ("" );
17951861 continue ;
1796- } else if (! strcmp ( name , "else" ) ) {
1862+ } else if (atom_type == ATOM_ELSE ) {
17971863 v -> handler = else_atom_handler ;
17981864 v -> s = xstrdup ("" );
17991865 continue ;
0 commit comments