Skip to content

Commit 42eeb7a

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 23fa93c commit 42eeb7a

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
@@ -1471,20 +1471,14 @@ static void pull_va_args(struct cbprintf_state *state)
14711471
}
14721472
}
14731473

1474-
int cbvprintf(cbprintf_cb out, void *ctx, const char *fp, va_list ap)
1474+
static int process_conversion(cbprintf_cb out, void *ctx, const char *fp,
1475+
struct cbprintf_state *state)
14751476
{
14761477
char buf[CONVERTED_BUFLEN];
14771478
size_t count = 0;
14781479
sint_value_type sint;
1479-
struct cbprintf_state state;
1480-
struct conversion *const conv = &state.conv;
1481-
union argument_value *const value = &state.value;
1482-
1483-
/* Make a copy of the arguments, because we can't pass ap to
1484-
* subroutines by value (caller wouldn't see the changes) nor
1485-
* by address (va_list may be an array type).
1486-
*/
1487-
va_copy(state.ap, ap);
1480+
struct conversion *const conv = &state->conv;
1481+
union argument_value *const value = &state->value;
14881482

14891483
/* Output character, returning EOF if output failed, otherwise
14901484
* updating count.
@@ -1522,28 +1516,28 @@ int cbvprintf(cbprintf_cb out, void *ctx, const char *fp, va_list ap)
15221516
const char *sp = fp;
15231517

15241518
fp = extract_conversion(conv, sp);
1525-
pull_va_args(&state);
1519+
pull_va_args(state);
15261520

15271521
/* Apply flag changes for negative width argument or
15281522
* copy out format value.
15291523
*/
15301524
if (conv->width_star) {
1531-
if (state.width < 0) {
1525+
if (state->width < 0) {
15321526
conv->flag_dash = true;
1533-
state.width = -state.width;
1527+
state->width = -state->width;
15341528
}
15351529
} else if (conv->width_present) {
1536-
state.width = conv->width_value;
1530+
state->width = conv->width_value;
15371531
}
15381532

15391533
/* Apply flag changes for negative precision argument */
15401534
if (conv->prec_star) {
1541-
if (state.precision < 0) {
1535+
if (state->precision < 0) {
15421536
conv->prec_present = false;
1543-
state.precision = -1;
1537+
state->precision = -1;
15441538
}
15451539
} else if (conv->prec_present) {
1546-
state.precision = conv->prec_value;
1540+
state->precision = conv->prec_value;
15471541
}
15481542

15491543
/* Reuse width and precision memory in conv for value
@@ -1557,9 +1551,9 @@ int cbvprintf(cbprintf_cb out, void *ctx, const char *fp, va_list ap)
15571551
&& (conv->specifier_cat == SPECIFIER_FP)
15581552
&& !conv->prec_present) {
15591553
if (conv->specifier_a) {
1560-
state.precision = FRACTION_HEX;
1554+
state->precision = FRACTION_HEX;
15611555
} else {
1562-
state.precision = 6;
1556+
state->precision = 6;
15631557
}
15641558
}
15651559

@@ -1573,8 +1567,8 @@ int cbvprintf(cbprintf_cb out, void *ctx, const char *fp, va_list ap)
15731567
continue;
15741568
}
15751569

1576-
int width = state.width;
1577-
int precision = state.precision;
1570+
int width = state->width;
1571+
int precision = state->precision;
15781572
const char *bps = NULL;
15791573
const char *bpe = buf + sizeof(buf);
15801574
char sign = 0;
@@ -1839,3 +1833,19 @@ int cbvprintf(cbprintf_cb out, void *ctx, const char *fp, va_list ap)
18391833
#undef OUTS
18401834
#undef OUTC
18411835
}
1836+
1837+
int cbvprintf(cbprintf_cb out, void *ctx, const char *fp, va_list ap)
1838+
{
1839+
/* Zero-initialized state. */
1840+
struct cbprintf_state state = {
1841+
.width = 0,
1842+
};
1843+
1844+
/* Make a copy of the arguments, because we can't pass ap to
1845+
* subroutines by value (caller wouldn't see the changes) nor
1846+
* by address (va_list may be an array type).
1847+
*/
1848+
va_copy(state.ap, ap);
1849+
1850+
return process_conversion(out, ctx, fp, &state);
1851+
}

0 commit comments

Comments
 (0)