@@ -108,6 +108,56 @@ static struct ref_to_worktree_map {
108
108
struct worktree * * worktrees ;
109
109
} ref_to_worktree_map ;
110
110
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
+
111
161
/*
112
162
* An atom is a valid field atom listed below, possibly prefixed with
113
163
* a "*" to denote deref_tag().
@@ -119,6 +169,7 @@ static struct ref_to_worktree_map {
119
169
* array.
120
170
*/
121
171
static struct used_atom {
172
+ enum atom_type atom_type ;
122
173
const char * name ;
123
174
cmp_type type ;
124
175
info_source source ;
@@ -146,6 +197,9 @@ static struct used_atom {
146
197
enum { O_FULL , O_LENGTH , O_SHORT } option ;
147
198
unsigned int length ;
148
199
} oid ;
200
+ struct {
201
+ enum { O_SIZE , O_SIZE_DISK } option ;
202
+ } objectsize ;
149
203
struct email_option {
150
204
enum { EO_RAW , EO_TRIM , EO_LOCALPART } option ;
151
205
} email_option ;
@@ -269,11 +323,13 @@ static int objectsize_atom_parser(const struct ref_format *format, struct used_a
269
323
const char * arg , struct strbuf * err )
270
324
{
271
325
if (!arg ) {
326
+ atom -> u .objectsize .option = O_SIZE ;
272
327
if (* atom -> name == '*' )
273
328
oi_deref .info .sizep = & oi_deref .size ;
274
329
else
275
330
oi .info .sizep = & oi .size ;
276
331
} else if (!strcmp (arg , "disk" )) {
332
+ atom -> u .objectsize .option = O_SIZE_DISK ;
277
333
if (* atom -> name == '*' )
278
334
oi_deref .info .disk_sizep = & oi_deref .disk_size ;
279
335
else
@@ -501,47 +557,47 @@ static struct {
501
557
int (* parser )(const struct ref_format * format , struct used_atom * atom ,
502
558
const char * arg , struct strbuf * err );
503
559
} 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 },
545
601
/*
546
602
* Please update $__git_ref_fieldlist in git-completion.bash
547
603
* when you add new atoms
@@ -623,6 +679,7 @@ static int parse_ref_filter_atom(const struct ref_format *format,
623
679
at = used_atom_cnt ;
624
680
used_atom_cnt ++ ;
625
681
REALLOC_ARRAY (used_atom , used_atom_cnt );
682
+ used_atom [at ].atom_type = i ;
626
683
used_atom [at ].name = xmemdupz (atom , ep - atom );
627
684
used_atom [at ].type = valid_atom [i ].cmp_type ;
628
685
used_atom [at ].source = valid_atom [i ].source ;
@@ -647,7 +704,7 @@ static int parse_ref_filter_atom(const struct ref_format *format,
647
704
return -1 ;
648
705
if (* atom == '*' )
649
706
need_tagged = 1 ;
650
- if (! strcmp ( valid_atom [ i ]. name , "symref" ) )
707
+ if (i == ATOM_SYMREF )
651
708
need_symref = 1 ;
652
709
return at ;
653
710
}
@@ -960,22 +1017,25 @@ static void grab_common_values(struct atom_value *val, int deref, struct expand_
960
1017
961
1018
for (i = 0 ; i < used_atom_cnt ; i ++ ) {
962
1019
const char * name = used_atom [i ].name ;
1020
+ enum atom_type atom_type = used_atom [i ].atom_type ;
963
1021
struct atom_value * v = & val [i ];
964
1022
if (!!deref != (* name == '*' ))
965
1023
continue ;
966
1024
if (deref )
967
1025
name ++ ;
968
- if (! strcmp ( name , "objecttype" ) )
1026
+ if (atom_type == ATOM_OBJECTTYPE )
969
1027
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 )
977
1037
v -> s = xstrdup (oid_to_hex (& oi -> delta_base_oid ));
978
- else if (deref )
1038
+ else if (atom_type == ATOM_OBJECTNAME && deref )
979
1039
grab_oid (name , "objectname" , & oi -> oid , v , & used_atom [i ]);
980
1040
}
981
1041
}
@@ -988,16 +1048,17 @@ static void grab_tag_values(struct atom_value *val, int deref, struct object *ob
988
1048
989
1049
for (i = 0 ; i < used_atom_cnt ; i ++ ) {
990
1050
const char * name = used_atom [i ].name ;
1051
+ enum atom_type atom_type = used_atom [i ].atom_type ;
991
1052
struct atom_value * v = & val [i ];
992
1053
if (!!deref != (* name == '*' ))
993
1054
continue ;
994
1055
if (deref )
995
1056
name ++ ;
996
- if (! strcmp ( name , "tag" ) )
1057
+ if (atom_type == ATOM_TAG )
997
1058
v -> s = xstrdup (tag -> tag );
998
- else if (! strcmp ( name , "type" ) && tag -> tagged )
1059
+ else if (atom_type == ATOM_TYPE && tag -> tagged )
999
1060
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 )
1001
1062
v -> s = xstrdup (oid_to_hex (& tag -> tagged -> oid ));
1002
1063
}
1003
1064
}
@@ -1010,18 +1071,20 @@ static void grab_commit_values(struct atom_value *val, int deref, struct object
1010
1071
1011
1072
for (i = 0 ; i < used_atom_cnt ; i ++ ) {
1012
1073
const char * name = used_atom [i ].name ;
1074
+ enum atom_type atom_type = used_atom [i ].atom_type ;
1013
1075
struct atom_value * v = & val [i ];
1014
1076
if (!!deref != (* name == '*' ))
1015
1077
continue ;
1016
1078
if (deref )
1017
1079
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 ]))
1019
1082
continue ;
1020
- if (! strcmp ( name , "numparent" ) ) {
1083
+ if (atom_type == ATOM_NUMPARENT ) {
1021
1084
v -> value = commit_list_count (commit -> parents );
1022
1085
v -> s = xstrfmt ("%lu" , (unsigned long )v -> value );
1023
1086
}
1024
- else if (starts_with ( name , "parent" ) ) {
1087
+ else if (atom_type == ATOM_PARENT ) {
1025
1088
struct commit_list * parents ;
1026
1089
struct strbuf s = STRBUF_INIT ;
1027
1090
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
1201
1264
return ;
1202
1265
for (i = 0 ; i < used_atom_cnt ; i ++ ) {
1203
1266
const char * name = used_atom [i ].name ;
1267
+ enum atom_type atom_type = used_atom [i ].atom_type ;
1204
1268
struct atom_value * v = & val [i ];
1205
1269
if (!!deref != (* name == '*' ))
1206
1270
continue ;
1207
1271
if (deref )
1208
1272
name ++ ;
1209
1273
1210
- if (starts_with ( name , "creatordate" ) )
1274
+ if (atom_type == ATOM_CREATORDATE )
1211
1275
grab_date (wholine , v , name );
1212
- else if (! strcmp ( name , "creator" ) )
1276
+ else if (atom_type == ATOM_CREATOR )
1213
1277
v -> s = copy_line (wholine );
1214
1278
}
1215
1279
}
@@ -1689,6 +1753,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
1689
1753
/* Fill in specials first */
1690
1754
for (i = 0 ; i < used_atom_cnt ; i ++ ) {
1691
1755
struct used_atom * atom = & used_atom [i ];
1756
+ enum atom_type atom_type = atom -> atom_type ;
1692
1757
const char * name = used_atom [i ].name ;
1693
1758
struct atom_value * v = & ref -> value [i ];
1694
1759
int deref = 0 ;
@@ -1703,18 +1768,18 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
1703
1768
name ++ ;
1704
1769
}
1705
1770
1706
- if (starts_with ( name , "refname" ) )
1771
+ if (atom_type == ATOM_REFNAME )
1707
1772
refname = get_refname (atom , ref );
1708
- else if (! strcmp ( name , "worktreepath" ) ) {
1773
+ else if (atom_type == ATOM_WORKTREEPATH ) {
1709
1774
if (ref -> kind == FILTER_REFS_BRANCHES )
1710
1775
v -> s = get_worktree_path (atom , ref );
1711
1776
else
1712
1777
v -> s = xstrdup ("" );
1713
1778
continue ;
1714
1779
}
1715
- else if (starts_with ( name , "symref" ) )
1780
+ else if (atom_type == ATOM_SYMREF )
1716
1781
refname = get_symref (atom , ref );
1717
- else if (starts_with ( name , "upstream" ) ) {
1782
+ else if (atom_type == ATOM_UPSTREAM ) {
1718
1783
const char * branch_name ;
1719
1784
/* only local branches may have an upstream */
1720
1785
if (!skip_prefix (ref -> refname , "refs/heads/" ,
@@ -1730,7 +1795,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
1730
1795
else
1731
1796
v -> s = xstrdup ("" );
1732
1797
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 ) {
1734
1799
const char * branch_name ;
1735
1800
v -> s = xstrdup ("" );
1736
1801
if (!skip_prefix (ref -> refname , "refs/heads/" ,
@@ -1749,10 +1814,10 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
1749
1814
free ((char * )v -> s );
1750
1815
fill_remote_ref_details (atom , refname , branch , & v -> s );
1751
1816
continue ;
1752
- } else if (starts_with ( name , "color:" ) ) {
1817
+ } else if (atom_type == ATOM_COLOR ) {
1753
1818
v -> s = xstrdup (atom -> u .color );
1754
1819
continue ;
1755
- } else if (! strcmp ( name , "flag" ) ) {
1820
+ } else if (atom_type == ATOM_FLAG ) {
1756
1821
char buf [256 ], * cp = buf ;
1757
1822
if (ref -> flag & REF_ISSYMREF )
1758
1823
cp = copy_advance (cp , ",symref" );
@@ -1765,35 +1830,36 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
1765
1830
v -> s = xstrdup (buf + 1 );
1766
1831
}
1767
1832
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 ) {
1771
1837
if (atom -> u .head && !strcmp (ref -> refname , atom -> u .head ))
1772
1838
v -> s = xstrdup ("*" );
1773
1839
else
1774
1840
v -> s = xstrdup (" " );
1775
1841
continue ;
1776
- } else if (starts_with ( name , "align" ) ) {
1842
+ } else if (atom_type == ATOM_ALIGN ) {
1777
1843
v -> handler = align_atom_handler ;
1778
1844
v -> s = xstrdup ("" );
1779
1845
continue ;
1780
- } else if (! strcmp ( name , "end" ) ) {
1846
+ } else if (atom_type == ATOM_END ) {
1781
1847
v -> handler = end_atom_handler ;
1782
1848
v -> s = xstrdup ("" );
1783
1849
continue ;
1784
- } else if (starts_with ( name , "if" ) ) {
1850
+ } else if (atom_type == ATOM_IF ) {
1785
1851
const char * s ;
1786
1852
if (skip_prefix (name , "if:" , & s ))
1787
1853
v -> s = xstrdup (s );
1788
1854
else
1789
1855
v -> s = xstrdup ("" );
1790
1856
v -> handler = if_atom_handler ;
1791
1857
continue ;
1792
- } else if (! strcmp ( name , "then" ) ) {
1858
+ } else if (atom_type == ATOM_THEN ) {
1793
1859
v -> handler = then_atom_handler ;
1794
1860
v -> s = xstrdup ("" );
1795
1861
continue ;
1796
- } else if (! strcmp ( name , "else" ) ) {
1862
+ } else if (atom_type == ATOM_ELSE ) {
1797
1863
v -> handler = else_atom_handler ;
1798
1864
v -> s = xstrdup ("" );
1799
1865
continue ;
0 commit comments