Skip to content

Commit c5d5562

Browse files
committed
lib: cbprintf: factor out core conversion implementation
An upcoming enhancement supports conversion with information provided from sources other than a va_list. Add a level of indirection so the core conversion operation isn't tied to the stdarg API. Signed-off-by: Peter Bigot <[email protected]>
1 parent 1b6dd8d commit c5d5562

File tree

1 file changed

+31
-21
lines changed

1 file changed

+31
-21
lines changed

lib/os/cbprintf_complete.c

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,19 +1420,13 @@ static void pull_va_args(struct cbprintf_state *state)
14201420
}
14211421
}
14221422

1423-
int cbvprintf(cbprintf_cb out, void *ctx, const char *fp, va_list ap)
1423+
static int process_conversion(cbprintf_cb out, void *ctx, const char *fp,
1424+
struct cbprintf_state *state)
14241425
{
14251426
char buf[CONVERTED_BUFLEN];
14261427
size_t count = 0;
1427-
struct cbprintf_state state;
1428-
struct conversion *const conv = &state.conv;
1429-
union argument_value *const value = &state.value;
1430-
1431-
/* Make a copy of the arguments, because we can't pass ap to
1432-
* subroutines by value (caller wouldn't see the changes) nor
1433-
* by address (va_list may be an array type).
1434-
*/
1435-
va_copy(state.ap, ap);
1428+
struct conversion *const conv = &state->conv;
1429+
union argument_value *const value = &state->value;
14361430

14371431
/* Output character, returning EOF if output failed, otherwise
14381432
* updating count.
@@ -1470,28 +1464,28 @@ int cbvprintf(cbprintf_cb out, void *ctx, const char *fp, va_list ap)
14701464
const char *sp = fp;
14711465

14721466
fp = extract_conversion(conv, sp);
1473-
pull_va_args(&state);
1467+
pull_va_args(state);
14741468

14751469
/* Apply flag changes for negative width argument or
14761470
* copy out format value.
14771471
*/
14781472
if (conv->width_star) {
1479-
if (state.width < 0) {
1473+
if (state->width < 0) {
14801474
conv->flag_dash = true;
1481-
state.width = -state.width;
1475+
state->width = -state->width;
14821476
}
14831477
} else if (conv->width_present) {
1484-
state.width = conv->width_value;
1478+
state->width = conv->width_value;
14851479
}
14861480

14871481
/* Apply flag changes for negative precision argument */
14881482
if (conv->prec_star) {
1489-
if (state.precision < 0) {
1483+
if (state->precision < 0) {
14901484
conv->prec_present = false;
1491-
state.precision = -1;
1485+
state->precision = -1;
14921486
}
14931487
} else if (conv->prec_present) {
1494-
state.precision = conv->prec_value;
1488+
state->precision = conv->prec_value;
14951489
}
14961490

14971491
/* Reuse width and precision memory in conv for value
@@ -1505,9 +1499,9 @@ int cbvprintf(cbprintf_cb out, void *ctx, const char *fp, va_list ap)
15051499
&& (conv->specifier_cat == SPECIFIER_FP)
15061500
&& !conv->prec_present) {
15071501
if (conv->specifier_a) {
1508-
state.precision = FRACTION_HEX;
1502+
state->precision = FRACTION_HEX;
15091503
} else {
1510-
state.precision = 6;
1504+
state->precision = 6;
15111505
}
15121506
}
15131507

@@ -1521,8 +1515,8 @@ int cbvprintf(cbprintf_cb out, void *ctx, const char *fp, va_list ap)
15211515
continue;
15221516
}
15231517

1524-
int width = state.width;
1525-
int precision = state.precision;
1518+
int width = state->width;
1519+
int precision = state->precision;
15261520
const char *bps = NULL;
15271521
const char *bpe = buf + sizeof(buf);
15281522
char sign = 0;
@@ -1782,3 +1776,19 @@ int cbvprintf(cbprintf_cb out, void *ctx, const char *fp, va_list ap)
17821776
#undef OUTS
17831777
#undef OUTC
17841778
}
1779+
1780+
int cbvprintf(cbprintf_cb out, void *ctx, const char *fp, va_list ap)
1781+
{
1782+
/* Zero-initialized state. */
1783+
struct cbprintf_state state = {
1784+
.width = 0,
1785+
};
1786+
1787+
/* Make a copy of the arguments, because we can't pass ap to
1788+
* subroutines by value (caller wouldn't see the changes) nor
1789+
* by address (va_list may be an array type).
1790+
*/
1791+
va_copy(state.ap, ap);
1792+
1793+
return process_conversion(out, ctx, fp, &state);
1794+
}

0 commit comments

Comments
 (0)