From ae2dc9643abab6b6f15e2f5fa6c8596e0010494e Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Mon, 16 Aug 2021 06:54:04 -0700 Subject: format: bug: sign not reset before each conversion. For instance, this bad output is produced: (pic "+0####.## <<<<<" 123 1) -> "+00123.00 +1 " The second argument should not have any leading + sign. * stream.c (formatv): For each new conversion specifier introduced by ~, reset the sign variable to zero also. That's the semantic change here, occluded by the fact that I'm rearranging the declaration of the variables, adding comments, and condensing the assignments while also getting them into the same order as the declarations, in order that this sort of bug does not creep in in the future, should another such variable be added. * tests/018/format.tl: Adding correct version of above test case. --- stream.c | 19 ++++++++----------- tests/018/format.tl | 4 ++++ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/stream.c b/stream.c index 3f2cafb3..56100bd9 100644 --- a/stream.c +++ b/stream.c @@ -3337,12 +3337,14 @@ val formatv(val stream_in, val fmtstr, struct args *al) enum { vf_init, vf_width, vf_digits, vf_star, vf_precision, vf_spec } state = vf_init, saved_state = vf_init; - int width = 0, precision = 0, precision_p = 0, digits = 0, lt = 0, neg = 0; - enum align align = al_right; - int sign = 0, zeropad = 0, dfl_precision = 0; - int dfl_digits = 0, print_base = 0; cnum value; cnum arg_ix = 0; + /* conversion variables that are reset before for each conversion */ + int width = 0, precision = 0, precision_p = 0, digits = 0, lt = 0, neg = 0; + int sign = 0, zeropad = 0; + enum align align = al_right; + /* conversion variables that persist across conversions */ + int dfl_precision = 0, dfl_digits = 0, print_base = 0; for (;;) { val obj; @@ -3357,14 +3359,9 @@ val formatv(val stream_in, val fmtstr, struct args *al) break; case '~': state = vf_width; - width = 0; + width = precision = precision_p = 0; + digits = lt = neg = sign = zeropad = 0; align = al_right; - zeropad = 0; - precision = 0; - precision_p = 0; - digits = 0; - lt = 0; - neg = 0; continue; default: put_char(chr(ch), stream); diff --git a/tests/018/format.tl b/tests/018/format.tl index 1b161936..0496d51f 100644 --- a/tests/018/format.tl +++ b/tests/018/format.tl @@ -227,3 +227,7 @@ (let ((a 2) (b "###") (c 13.5)) (pic `abc@(+ a a)###.##@b>>>>` c "x")) "abc4 13.50### x") + +(test + (pic "+0####.## <<<<<" 123 1) + "+00123.00 1 ") -- cgit v1.2.3