|
16 | 16 | #include "trailer.h"
|
17 | 17 |
|
18 | 18 | typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type;
|
| 19 | +typedef enum { COMPARE_EQUAL, COMPARE_UNEQUAL, COMPARE_NONE } cmp_status; |
19 | 20 |
|
20 | 21 | struct align {
|
21 | 22 | align_type position;
|
22 | 23 | unsigned int width;
|
23 | 24 | };
|
24 | 25 |
|
25 | 26 | struct if_then_else {
|
| 27 | + cmp_status cmp_status; |
| 28 | + const char *str; |
26 | 29 | unsigned int then_atom_seen : 1,
|
27 | 30 | else_atom_seen : 1,
|
28 | 31 | condition_satisfied : 1;
|
@@ -50,6 +53,10 @@ static struct used_atom {
|
50 | 53 | enum { C_BARE, C_BODY, C_BODY_DEP, C_LINES, C_SIG, C_SUB, C_TRAILERS } option;
|
51 | 54 | unsigned int nlines;
|
52 | 55 | } contents;
|
| 56 | + struct { |
| 57 | + cmp_status cmp_status; |
| 58 | + const char *str; |
| 59 | + } if_then_else; |
53 | 60 | enum { O_FULL, O_SHORT } objectname;
|
54 | 61 | } u;
|
55 | 62 | } *used_atom;
|
@@ -179,6 +186,21 @@ static void align_atom_parser(struct used_atom *atom, const char *arg)
|
179 | 186 | string_list_clear(¶ms, 0);
|
180 | 187 | }
|
181 | 188 |
|
| 189 | +static void if_atom_parser(struct used_atom *atom, const char *arg) |
| 190 | +{ |
| 191 | + if (!arg) { |
| 192 | + atom->u.if_then_else.cmp_status = COMPARE_NONE; |
| 193 | + return; |
| 194 | + } else if (skip_prefix(arg, "equals=", &atom->u.if_then_else.str)) { |
| 195 | + atom->u.if_then_else.cmp_status = COMPARE_EQUAL; |
| 196 | + } else if (skip_prefix(arg, "notequals=", &atom->u.if_then_else.str)) { |
| 197 | + atom->u.if_then_else.cmp_status = COMPARE_UNEQUAL; |
| 198 | + } else { |
| 199 | + die(_("unrecognized %%(if) argument: %s"), arg); |
| 200 | + } |
| 201 | +} |
| 202 | + |
| 203 | + |
182 | 204 | static struct {
|
183 | 205 | const char *name;
|
184 | 206 | cmp_type cmp_type;
|
@@ -220,7 +242,7 @@ static struct {
|
220 | 242 | { "color", FIELD_STR, color_atom_parser },
|
221 | 243 | { "align", FIELD_STR, align_atom_parser },
|
222 | 244 | { "end" },
|
223 |
| - { "if" }, |
| 245 | + { "if", FIELD_STR, if_atom_parser }, |
224 | 246 | { "then" },
|
225 | 247 | { "else" },
|
226 | 248 | };
|
@@ -422,6 +444,9 @@ static void if_atom_handler(struct atom_value *atomv, struct ref_formatting_stat
|
422 | 444 | struct ref_formatting_stack *new;
|
423 | 445 | struct if_then_else *if_then_else = xcalloc(sizeof(struct if_then_else), 1);
|
424 | 446 |
|
| 447 | + if_then_else->str = atomv->atom->u.if_then_else.str; |
| 448 | + if_then_else->cmp_status = atomv->atom->u.if_then_else.cmp_status; |
| 449 | + |
425 | 450 | push_stack_element(&state->stack);
|
426 | 451 | new = state->stack;
|
427 | 452 | new->at_end = if_then_else_handler;
|
@@ -453,10 +478,17 @@ static void then_atom_handler(struct atom_value *atomv, struct ref_formatting_st
|
453 | 478 | die(_("format: %%(then) atom used after %%(else)"));
|
454 | 479 | if_then_else->then_atom_seen = 1;
|
455 | 480 | /*
|
456 |
| - * If there exists non-empty string between the 'if' and |
457 |
| - * 'then' atom then the 'if' condition is satisfied. |
| 481 | + * If the 'equals' or 'notequals' attribute is used then |
| 482 | + * perform the required comparison. If not, only non-empty |
| 483 | + * strings satisfy the 'if' condition. |
458 | 484 | */
|
459 |
| - if (cur->output.len && !is_empty(cur->output.buf)) |
| 485 | + if (if_then_else->cmp_status == COMPARE_EQUAL) { |
| 486 | + if (!strcmp(if_then_else->str, cur->output.buf)) |
| 487 | + if_then_else->condition_satisfied = 1; |
| 488 | + } else if (if_then_else->cmp_status == COMPARE_UNEQUAL) { |
| 489 | + if (strcmp(if_then_else->str, cur->output.buf)) |
| 490 | + if_then_else->condition_satisfied = 1; |
| 491 | + } else if (cur->output.len && !is_empty(cur->output.buf)) |
460 | 492 | if_then_else->condition_satisfied = 1;
|
461 | 493 | strbuf_reset(&cur->output);
|
462 | 494 | }
|
@@ -1158,7 +1190,11 @@ static void populate_value(struct ref_array_item *ref)
|
1158 | 1190 | } else if (!strcmp(name, "end")) {
|
1159 | 1191 | v->handler = end_atom_handler;
|
1160 | 1192 | continue;
|
1161 |
| - } else if (!strcmp(name, "if")) { |
| 1193 | + } else if (starts_with(name, "if")) { |
| 1194 | + const char *s; |
| 1195 | + |
| 1196 | + if (skip_prefix(name, "if:", &s)) |
| 1197 | + v->s = xstrdup(s); |
1162 | 1198 | v->handler = if_atom_handler;
|
1163 | 1199 | continue;
|
1164 | 1200 | } else if (!strcmp(name, "then")) {
|
|
0 commit comments