108
struct worktree **worktrees;
109
} ref_to_worktree_map;
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
+
161
/*
162
* An atom is a valid field atom listed below, possibly prefixed with
163
* a "*" to denote deref_tag().
169
* array.
170
*/
171
static struct used_atom {
172
+ enum atom_type atom_type;
173
const char *name;
174
cmp_type type;
175
info_source source;
557
int (*parser)(const struct ref_format *format, struct used_atom *atom,
558
const char *arg, struct strbuf *err);
559
} valid_atom[] = {
509
- { "refname", SOURCE_NONE, FIELD_STR, refname_atom_parser },
510
- { "objecttype", SOURCE_OTHER, FIELD_STR, objecttype_atom_parser },
511
- { "objectsize", SOURCE_OTHER, FIELD_ULONG, objectsize_atom_parser },
512
- { "objectname", SOURCE_OTHER, FIELD_STR, oid_atom_parser },
513
- { "deltabase", SOURCE_OTHER, FIELD_STR, deltabase_atom_parser },
514
- { "tree", SOURCE_OBJ, FIELD_STR, oid_atom_parser },
515
- { "parent", SOURCE_OBJ, FIELD_STR, oid_atom_parser },
516
- { "numparent", SOURCE_OBJ, FIELD_ULONG },
517
- { "object", SOURCE_OBJ },
518
- { "type", SOURCE_OBJ },
519
- { "tag", SOURCE_OBJ },
520
- { "author", SOURCE_OBJ },
521
- { "authorname", SOURCE_OBJ },
522
- { "authoremail", SOURCE_OBJ, FIELD_STR, person_email_atom_parser },
523
- { "authordate", SOURCE_OBJ, FIELD_TIME },
524
- { "committer", SOURCE_OBJ },
525
- { "committername", SOURCE_OBJ },
526
- { "committeremail", SOURCE_OBJ, FIELD_STR, person_email_atom_parser },
527
- { "committerdate", SOURCE_OBJ, FIELD_TIME },
528
- { "tagger", SOURCE_OBJ },
529
- { "taggername", SOURCE_OBJ },
530
- { "taggeremail", SOURCE_OBJ, FIELD_STR, person_email_atom_parser },
531
- { "taggerdate", SOURCE_OBJ, FIELD_TIME },
532
- { "creator", SOURCE_OBJ },
533
- { "creatordate", SOURCE_OBJ, FIELD_TIME },
534
- { "subject", SOURCE_OBJ, FIELD_STR, subject_atom_parser },
535
- { "body", SOURCE_OBJ, FIELD_STR, body_atom_parser },
536
- { "trailers", SOURCE_OBJ, FIELD_STR, trailers_atom_parser },
537
- { "contents", SOURCE_OBJ, FIELD_STR, contents_atom_parser },
538
- { "upstream", SOURCE_NONE, FIELD_STR, remote_ref_atom_parser },
539
- { "push", SOURCE_NONE, FIELD_STR, remote_ref_atom_parser },
540
- { "symref", SOURCE_NONE, FIELD_STR, refname_atom_parser },
541
- { "flag", SOURCE_NONE },
542
- { "HEAD", SOURCE_NONE, FIELD_STR, head_atom_parser },
543
- { "color", SOURCE_NONE, FIELD_STR, color_atom_parser },
544
- { "worktreepath", SOURCE_NONE },
545
- { "align", SOURCE_NONE, FIELD_STR, align_atom_parser },
546
- { "end", SOURCE_NONE },
547
- { "if", SOURCE_NONE, FIELD_STR, if_atom_parser },
548
- { "then", SOURCE_NONE },
549
- { "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 },
601
/*
602
* Please update $__git_ref_fieldlist in git-completion.bash
603
* when you add new atoms
679
at = used_atom_cnt;
680
used_atom_cnt++;
681
REALLOC_ARRAY(used_atom, used_atom_cnt);
682
+ used_atom[at].atom_type = i;
683
used_atom[at].name = xmemdupz(atom, ep - atom);
684
used_atom[at].type = valid_atom[i].cmp_type;
685
used_atom[at].source = valid_atom[i].source;
704
return -1;
705
if (*atom == '*')
706
need_tagged = 1;
655
- if (!strcmp(valid_atom[i].name, "symref"))
707
+ if (i == ATOM_SYMREF)
708
need_symref = 1;
709
return at;
710
}
1017
1018
for (i = 0; i < used_atom_cnt; i++) {
1019
const char *name = used_atom[i].name;
1020
+ enum atom_type atom_type = used_atom[i].atom_type;
1021
struct atom_value *v = &val[i];
1022
if (!!deref != (*name == '*'))
1023
continue;
1024
if (deref)
1025
name++;
973
- if (!strcmp(name, "objecttype"))
1026
+ if (atom_type == ATOM_OBJECTTYPE)
1027
v->s = xstrdup(type_name(oi->type));
975
- else if (starts_with(name, "objectsize")) {
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);
1033
v->value = oi->size;
1034
v->s = xstrfmt("%"PRIuMAX , (uintmax_t)oi->size);
1035
}
983
- } else if (!strcmp(name, "deltabase"))
1036
+ } else if (atom_type == ATOM_DELTABASE)
1037
v->s = xstrdup(oid_to_hex(&oi->delta_base_oid));
985
- else if (deref)
1038
+ else if (atom_type == ATOM_OBJECTNAME && deref)
1039
grab_oid(name, "objectname", &oi->oid, v, &used_atom[i]);
1040
}
1041
}
1048
1049
for (i = 0; i < used_atom_cnt; i++) {
1050
const char *name = used_atom[i].name;
1051
+ enum atom_type atom_type = used_atom[i].atom_type;
1052
struct atom_value *v = &val[i];
1053
if (!!deref != (*name == '*'))
1054
continue;
1055
if (deref)
1056
name++;
1003
- if (!strcmp(name, "tag"))
1057
+ if (atom_type == ATOM_TAG)
1058
v->s = xstrdup(tag->tag);
1005
- else if (!strcmp(name, "type") && tag->tagged)
1059
+ else if (atom_type == ATOM_TYPE && tag->tagged)
1060
v->s = xstrdup(type_name(tag->tagged->type));
1007
- else if (!strcmp(name, "object") && tag->tagged)
1061
+ else if (atom_type == ATOM_OBJECT && tag->tagged)
1062
v->s = xstrdup(oid_to_hex(&tag->tagged->oid));
1063
}
1064
}
1071
1072
for (i = 0; i < used_atom_cnt; i++) {
1073
const char *name = used_atom[i].name;
1074
+ enum atom_type atom_type = used_atom[i].atom_type;
1075
struct atom_value *v = &val[i];
1076
if (!!deref != (*name == '*'))
1077
continue;
1078
if (deref)
1079
name++;
1025
- 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]))
1082
continue;
1027
- if (!strcmp(name, "numparent")) {
1083
+ if (atom_type == ATOM_NUMPARENT) {
1084
v->value = commit_list_count(commit->parents);
1085
v->s = xstrfmt("%lu", (unsigned long)v->value);
1086
}
1031
- else if (starts_with(name, "parent")) {
1087
+ else if (atom_type == ATOM_PARENT) {
1088
struct commit_list *parents;
1089
struct strbuf s = STRBUF_INIT;
1090
for (parents = commit->parents; parents; parents = parents->next) {
1264
return;
1265
for (i = 0; i < used_atom_cnt; i++) {
1266
const char *name = used_atom[i].name;
1267
+ enum atom_type atom_type = used_atom[i].atom_type;
1268
struct atom_value *v = &val[i];
1269
if (!!deref != (*name == '*'))
1270
continue;
1271
if (deref)
1272
name++;
1273
1217
- if (starts_with(name, "creatordate"))
1274
+ if (atom_type == ATOM_CREATORDATE)
1275
grab_date(wholine, v, name);
1219
- else if (!strcmp(name, "creator"))
1276
+ else if (atom_type == ATOM_CREATOR)
1277
v->s = copy_line(wholine);
1278
}
1279
}
1753
/* Fill in specials first */
1754
for (i = 0; i < used_atom_cnt; i++) {
1755
struct used_atom *atom = &used_atom[i];
1756
+ enum atom_type atom_type = atom->atom_type;
1757
const char *name = used_atom[i].name;
1758
struct atom_value *v = &ref->value[i];
1759
int deref = 0;
1768
name++;
1769
}
1770
1713
- if (starts_with(name, "refname"))
1771
+ if (atom_type == ATOM_REFNAME)
1772
refname = get_refname(atom, ref);
1715
- else if (!strcmp(name, "worktreepath")) {
1773
+ else if (atom_type == ATOM_WORKTREEPATH) {
1774
if (ref->kind == FILTER_REFS_BRANCHES)
1775
v->s = get_worktree_path(atom, ref);
1776
else
1777
v->s = xstrdup("");
1778
continue;
1779
}
1722
- else if (starts_with(name, "symref"))
1780
+ else if (atom_type == ATOM_SYMREF)
1781
refname = get_symref(atom, ref);
1724
- else if (starts_with(name, "upstream")) {
1782
+ else if (atom_type == ATOM_UPSTREAM) {
1783
const char *branch_name;
1784
/* only local branches may have an upstream */
1785
if (!skip_prefix(ref->refname, "refs/heads/",
1795
else
1796
v->s = xstrdup("");
1797
continue;
1740
- } else if (atom->u.remote_ref.push) {
1798
+ } else if (atom_type == ATOM_PUSH && atom->u.remote_ref.push) {
1799
const char *branch_name;
1800
v->s = xstrdup("");
1801
if (!skip_prefix(ref->refname, "refs/heads/",
1814
free((char *)v->s);
1815
fill_remote_ref_details(atom, refname, branch, &v->s);
1816
continue;
1759
- } else if (starts_with(name, "color:")) {
1817
+ } else if (atom_type == ATOM_COLOR) {
1818
v->s = xstrdup(atom->u.color);
1819
continue;
1762
- } else if (!strcmp(name, "flag")) {
1820
+ } else if (atom_type == ATOM_FLAG) {
1821
char buf[256], *cp = buf;
1822
if (ref->flag & REF_ISSYMREF)
1823
cp = copy_advance(cp, ",symref");
1830
v->s = xstrdup(buf + 1);
1831
}
1832
continue;
1775
- } else if (!deref && grab_oid(name, "objectname", &ref->objectname, v, atom)) {
1776
- continue;
1777
- } 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) {
1837
if (atom->u.head && !strcmp(ref->refname, atom->u.head))
1838
v->s = xstrdup("*");
1839
else
1840
v->s = xstrdup(" ");
1841
continue;
1783
- } else if (starts_with(name, "align")) {
1842
+ } else if (atom_type == ATOM_ALIGN) {
1843
v->handler = align_atom_handler;
1844
v->s = xstrdup("");
1845
continue;
1787
- } else if (!strcmp(name, "end")) {
1846
+ } else if (atom_type == ATOM_END) {
1847
v->handler = end_atom_handler;
1848
v->s = xstrdup("");
1849
continue;
1791
- } else if (starts_with(name, "if")) {
1850
+ } else if (atom_type == ATOM_IF) {
1851
const char *s;
1852
if (skip_prefix(name, "if:", &s))
1853
v->s = xstrdup(s);
1855
v->s = xstrdup("");
1856
v->handler = if_atom_handler;
1857
continue;
1799
- } else if (!strcmp(name, "then")) {
1858
+ } else if (atom_type == ATOM_THEN) {
1859
v->handler = then_atom_handler;
1860
v->s = xstrdup("");
1861
continue;
1803
- } else if (!strcmp(name, "else")) {
1862
+ } else if (atom_type == ATOM_ELSE) {
1863
v->handler = else_atom_handler;
1864
v->s = xstrdup("");
1865
continue;