Skip to content

Commit 23fa93c

Browse files
committed
lib: cbprintf: refactor handling of dynamic format flags
Format width and precision can be extracted from arguments. A negative value is interpreted by changing flag state and using the non-negative value. Refactor pull_va_args() so the raw value from the stack is preserved in the state so it can be packed, deferring the interpretation to point-of-use. Signed-off-by: Peter Bigot <[email protected]>
1 parent c770a4e commit 23fa93c

File tree

1 file changed

+44
-43
lines changed

1 file changed

+44
-43
lines changed

lib/os/cbprintf_complete.c

Lines changed: 44 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,54 +1359,16 @@ static void pull_va_args(struct cbprintf_state *state)
13591359
struct conversion *const conv = &state->conv;
13601360
union argument_value *const value = &state->value;
13611361

1362-
state->width = -1;
1363-
state->precision = -1;
1364-
1365-
/* If dynamic width is specified, process it, otherwise set
1366-
* with if present.
1367-
*/
13681362
if (conv->width_star) {
13691363
state->width = va_arg(state->ap, int);
1370-
1371-
if (state->width < 0) {
1372-
conv->flag_dash = true;
1373-
state->width = -state->width;
1374-
}
1375-
} else if (conv->width_present) {
1376-
state->width = conv->width_value;
1364+
} else {
1365+
state->width = -1;
13771366
}
13781367

1379-
/* If dynamic precision is specified, process it, otherwise
1380-
* set precision if present. For floating point where
1381-
* precision is not present use 6.
1382-
*/
13831368
if (conv->prec_star) {
1384-
int arg = va_arg(state->ap, int);
1385-
1386-
if (arg < 0) {
1387-
conv->prec_present = false;
1388-
} else {
1389-
state->precision = arg;
1390-
}
1391-
} else if (conv->prec_present) {
1392-
state->precision = conv->prec_value;
1393-
}
1394-
1395-
/* Reuse width and precision memory in conv for value
1396-
* padding counts.
1397-
*/
1398-
conv->pad0_value = 0;
1399-
conv->pad0_pre_exp = 0;
1400-
1401-
/* FP conversion requires knowing the precision. */
1402-
if (IS_ENABLED(CONFIG_CBPRINTF_FP_SUPPORT)
1403-
&& (conv->specifier_cat == SPECIFIER_FP)
1404-
&& !conv->prec_present) {
1405-
if (conv->specifier_a) {
1406-
state->precision = FRACTION_HEX;
1407-
} else {
1408-
state->precision = 6;
1409-
}
1369+
state->precision = va_arg(state->ap, int);
1370+
} else {
1371+
state->precision = -1;
14101372
}
14111373

14121374
enum specifier_cat_enum specifier_cat
@@ -1562,6 +1524,45 @@ int cbvprintf(cbprintf_cb out, void *ctx, const char *fp, va_list ap)
15621524
fp = extract_conversion(conv, sp);
15631525
pull_va_args(&state);
15641526

1527+
/* Apply flag changes for negative width argument or
1528+
* copy out format value.
1529+
*/
1530+
if (conv->width_star) {
1531+
if (state.width < 0) {
1532+
conv->flag_dash = true;
1533+
state.width = -state.width;
1534+
}
1535+
} else if (conv->width_present) {
1536+
state.width = conv->width_value;
1537+
}
1538+
1539+
/* Apply flag changes for negative precision argument */
1540+
if (conv->prec_star) {
1541+
if (state.precision < 0) {
1542+
conv->prec_present = false;
1543+
state.precision = -1;
1544+
}
1545+
} else if (conv->prec_present) {
1546+
state.precision = conv->prec_value;
1547+
}
1548+
1549+
/* Reuse width and precision memory in conv for value
1550+
* padding counts.
1551+
*/
1552+
conv->pad0_value = 0;
1553+
conv->pad0_pre_exp = 0;
1554+
1555+
/* FP conversion requires knowing the precision. */
1556+
if (IS_ENABLED(CONFIG_CBPRINTF_FP_SUPPORT)
1557+
&& (conv->specifier_cat == SPECIFIER_FP)
1558+
&& !conv->prec_present) {
1559+
if (conv->specifier_a) {
1560+
state.precision = FRACTION_HEX;
1561+
} else {
1562+
state.precision = 6;
1563+
}
1564+
}
1565+
15651566
/* We've now consumed all arguments related to this
15661567
* specification. If the conversion is invalid, or is
15671568
* something we don't support, then output the original

0 commit comments

Comments
 (0)