55
{ "color" },
56
};
57
58
+#define REF_FORMATTING_STATE_INIT { 0, NULL }
59
+
60
+struct ref_formatting_stack {
61
+ struct ref_formatting_stack *prev;
62
+ struct strbuf output;
63
+};
64
+
65
+struct ref_formatting_state {
66
+ int quote_style;
67
+ struct ref_formatting_stack *stack;
68
+};
69
+
70
struct atom_value {
71
const char *s;
72
unsigned long ul; /* used for sorting when not FIELD_STR */
141
return at;
142
}
143
144
+static void push_stack_element(struct ref_formatting_stack **stack)
145
+{
146
+ struct ref_formatting_stack *s = xcalloc(1, sizeof(struct ref_formatting_stack));
147
+
148
+ strbuf_init(&s->output, 0);
149
+ s->prev = *stack;
150
+ *stack = s;
151
+}
152
+
153
+static void pop_stack_element(struct ref_formatting_stack **stack)
154
+{
155
+ struct ref_formatting_stack *current = *stack;
156
+ struct ref_formatting_stack *prev = current->prev;
157
+
158
+ if (prev)
159
+ strbuf_addbuf(&prev->output, ¤t->output);
160
+ strbuf_release(¤t->output);
161
+ free(current);
162
+ *stack = prev;
163
+}
164
+
165
/*
166
* In a format string, find the next occurrence of %(atom).
167
*/
1228
qsort(array->items, array->nr, sizeof(struct ref_array_item *), compare_refs);
1229
}
1230
1198
-static void print_value(struct atom_value *v, int quote_style)
1231
+static void append_atom(struct atom_value *v, struct ref_formatting_state *state)
1232
{
1200
- struct strbuf sb = STRBUF_INIT;
1201
- switch (quote_style) {
1233
+ struct strbuf *s = &state->stack->output;
1234
+
1235
+ switch (state->quote_style) {
1236
case QUOTE_NONE:
1203
- fputs(v->s, stdout);
1237
+ strbuf_addstr(s, v->s);
1238
break;
1239
case QUOTE_SHELL:
1206
- sq_quote_buf(&sb, v->s);
1240
+ sq_quote_buf(s, v->s);
1241
break;
1242
case QUOTE_PERL:
1209
- perl_quote_buf(&sb, v->s);
1243
+ perl_quote_buf(s, v->s);
1244
break;
1245
case QUOTE_PYTHON:
1212
- python_quote_buf(&sb, v->s);
1246
+ python_quote_buf(s, v->s);
1247
break;
1248
case QUOTE_TCL:
1215
- tcl_quote_buf(&sb, v->s);
1249
+ tcl_quote_buf(s, v->s);
1250
break;
1251
}
1218
- if (quote_style != QUOTE_NONE) {
1219
- fputs(sb.buf, stdout);
1220
- strbuf_release(&sb);
1221
- }
1252
}
1253
1254
static int hex1(char ch)
1269
return -1;
1270
}
1271
1242
-static void emit(const char *cp, const char *ep)
1272
+static void append_literal(const char *cp, const char *ep, struct ref_formatting_state *state)
1273
{
1274
+ struct strbuf *s = &state->stack->output;
1275
+
1276
while (*cp && (!ep || cp < ep)) {
1277
if (*cp == '%') {
1278
if (cp[1] == '%')
1280
else {
1281
int ch = hex2(cp + 1);
1282
if (0 <= ch) {
1251
- putchar(ch);
1283
+ strbuf_addch(s, ch);
1284
cp += 3;
1285
continue;
1286
}
1287
}
1288
}
1257
- putchar(*cp);
1289
+ strbuf_addch(s, *cp);
1290
cp++;
1291
}
1292
}
1294
void show_ref_array_item(struct ref_array_item *info, const char *format, int quote_style)
1295
{
1296
const char *cp, *sp, *ep;
1297
+ struct strbuf *final_buf;
1298
+ struct ref_formatting_state state = REF_FORMATTING_STATE_INIT;
1299
+
1300
+ state.quote_style = quote_style;
1301
+ push_stack_element(&state.stack);
1302
1303
for (cp = format; *cp && (sp = find_next(cp)); cp = ep + 1) {
1304
struct atom_value *atomv;
1305
1306
ep = strchr(sp, ')');
1307
if (cp < sp)
1271
- emit(cp, sp);
1308
+ append_literal(cp, sp, &state);
1309
get_ref_atom_value(info, parse_ref_filter_atom(sp + 2, ep), &atomv);
1273
- print_value(atomv, quote_style);
1310
+ append_atom(atomv, &state);
1311
}
1312
if (*cp) {
1313
sp = cp + strlen(cp);
1277
- emit(cp, sp);
1314
+ append_literal(cp, sp, &state);
1315
}
1316
if (need_color_reset_at_eol) {
1317
struct atom_value resetv;
1320
if (color_parse("reset", color) < 0)
1321
die("BUG: couldn't parse 'reset' as a color");
1322
resetv.s = color;
1286
- print_value(&resetv, quote_style);
1323
+ append_atom(&resetv, &state);
1324
}
1325
+ final_buf = &state.stack->output;
1326
+ fwrite(final_buf->buf, 1, final_buf->len, stdout);
1327
+ pop_stack_element(&state.stack);
1328
putchar('\n');
1329
}
1330