Skip to content

Commit

Permalink
precision specifier cancels out the leading-zero flag on int conversi…
Browse files Browse the repository at this point in the history
…ons (#245)

* precision specifier cancels out the leading-zero flag on int conversions

* uncomment the new conformance test now that it passes
  • Loading branch information
charlesnicholson authored Mar 23, 2023
1 parent 1e254af commit 1e0ba1d
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 58 deletions.
88 changes: 30 additions & 58 deletions nanoprintf.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,23 +300,12 @@ int npf_parse_format_spec(char const *format, npf_format_spec_t *out_spec) {
while (*++cur) { // cur points at the leading '%' character
switch (*cur) { // Optional flags
#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1
case '-':
out_spec->left_justified = '-';
out_spec->leading_zero_pad = 0;
continue;
case '0':
out_spec->leading_zero_pad = !out_spec->left_justified;
continue;
#endif
case '+':
out_spec->prepend = '+';
continue;
case ' ':
if (out_spec->prepend == 0) { out_spec->prepend = ' '; }
continue;
case '#':
out_spec->alt_form = '#';
continue;
case '-': out_spec->left_justified = '-'; out_spec->leading_zero_pad = 0; continue;
case '0': out_spec->leading_zero_pad = !out_spec->left_justified; continue;
#endif
case '+': out_spec->prepend = '+'; continue;
case ' ': if (out_spec->prepend == 0) { out_spec->prepend = ' '; } continue;
case '#': out_spec->alt_form = '#'; continue;
default: break;
}
break;
Expand Down Expand Up @@ -358,6 +347,7 @@ int npf_parse_format_spec(char const *format, npf_format_spec_t *out_spec) {
}
#endif

int tmp_conv = -1;
out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_NONE;
switch (*cur++) { // Length modifier
case 'h':
Expand All @@ -377,86 +367,68 @@ int npf_parse_format_spec(char const *format, npf_format_spec_t *out_spec) {
#endif
break;
#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1
case 'L':
out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LONG_DOUBLE;
break;
case 'L': out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LONG_DOUBLE; break;
#endif
#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1
case 'j':
out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_INTMAX;
break;
case 'z':
out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_SIZET;
break;
case 't':
out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_PTRDIFFT;
break;
case 'j': out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_INTMAX; break;
case 'z': out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_SIZET; break;
case 't': out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_PTRDIFFT; break;
#endif
default: --cur; break;
}

switch (*cur++) { // Conversion specifier
case '%':
out_spec->conv_spec = NPF_FMT_SPEC_CONV_PERCENT;
case '%': out_spec->conv_spec = NPF_FMT_SPEC_CONV_PERCENT;
#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1
out_spec->prec_opt = NPF_FMT_SPEC_OPT_NONE;
#endif
break;
case 'c':
out_spec->conv_spec = NPF_FMT_SPEC_CONV_CHAR;

case 'c': out_spec->conv_spec = NPF_FMT_SPEC_CONV_CHAR;
#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1
out_spec->prec_opt = NPF_FMT_SPEC_OPT_NONE;
#endif
break;
case 's':
out_spec->conv_spec = NPF_FMT_SPEC_CONV_STRING;

case 's': out_spec->conv_spec = NPF_FMT_SPEC_CONV_STRING;
#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1
out_spec->leading_zero_pad = 0;
#endif
break;

case 'i':
case 'd':
out_spec->conv_spec = NPF_FMT_SPEC_CONV_SIGNED_INT;
break;

case 'o':
out_spec->conv_spec = NPF_FMT_SPEC_CONV_OCTAL;
break;
case 'u':
out_spec->conv_spec = NPF_FMT_SPEC_CONV_UNSIGNED_INT;
break;

case 'X':
out_spec->case_adjust = 0;
case 'x':
out_spec->conv_spec = NPF_FMT_SPEC_CONV_HEX_INT;
case 'd': tmp_conv = NPF_FMT_SPEC_CONV_SIGNED_INT;
case 'o': if (tmp_conv == -1) { tmp_conv = NPF_FMT_SPEC_CONV_OCTAL; }
case 'u': if (tmp_conv == -1) { tmp_conv = NPF_FMT_SPEC_CONV_UNSIGNED_INT; }
case 'X': if (tmp_conv == -1) { out_spec->case_adjust = 0; }
case 'x': if (tmp_conv == -1) { tmp_conv = NPF_FMT_SPEC_CONV_HEX_INT; }
out_spec->conv_spec = (npf_format_spec_conversion_t)tmp_conv;
#if (NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1) && \
(NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1)
if (out_spec->prec_opt != NPF_FMT_SPEC_OPT_NONE) { out_spec->leading_zero_pad = 0; }
#endif
break;

#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1
case 'F':
out_spec->case_adjust = 0;
case 'F': out_spec->case_adjust = 0;
case 'f':
out_spec->conv_spec = NPF_FMT_SPEC_CONV_FLOAT_DEC;
if (out_spec->prec_opt == NPF_FMT_SPEC_OPT_NONE) { out_spec->prec = 6; }
break;

case 'E':
out_spec->case_adjust = 0;
case 'E': out_spec->case_adjust = 0;
case 'e':
out_spec->conv_spec = NPF_FMT_SPEC_CONV_FLOAT_SCI;
if (out_spec->prec_opt == NPF_FMT_SPEC_OPT_NONE) { out_spec->prec = 6; }
break;

case 'G':
out_spec->case_adjust = 0;
case 'G': out_spec->case_adjust = 0;
case 'g':
out_spec->conv_spec = NPF_FMT_SPEC_CONV_FLOAT_SHORTEST;
if (out_spec->prec_opt == NPF_FMT_SPEC_OPT_NONE) { out_spec->prec = 6; }
break;

case 'A':
out_spec->case_adjust = 0;
case 'A': out_spec->case_adjust = 0;
case 'a':
out_spec->conv_spec = NPF_FMT_SPEC_CONV_FLOAT_HEX;
if (out_spec->prec_opt == NPF_FMT_SPEC_OPT_NONE) { out_spec->prec = 6; }
Expand Down
1 change: 1 addition & 0 deletions tests/conformance.cc
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ TEST_CASE("conformance to system printf") {
#if (NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1) && \
(NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1)
require_conform(" +01", "%+4.2i", 1);
require_conform(" 0", "%02.1d", 0);
#endif

#if (NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1)
Expand Down
5 changes: 5 additions & 0 deletions tests/unit_parse_format_spec.cc
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,11 @@ TEST_CASE("npf_parse_format_spec") {
REQUIRE(spec.left_justified);
REQUIRE(!spec.leading_zero_pad);
}

SUBCASE("0 flag is ignored when precision is specified") {
REQUIRE(npf_parse_format_spec("%0.1u", &spec) == 5);
REQUIRE(!spec.leading_zero_pad);
}
}

SUBCASE("field width") {
Expand Down

0 comments on commit 1e0ba1d

Please sign in to comment.