summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-08-16 06:54:04 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-08-16 06:54:04 -0700
commitae2dc9643abab6b6f15e2f5fa6c8596e0010494e (patch)
tree87d2e0e473d1140d6497076409a442f59d669fd9
parentf90f54c07d9839ffeb823cb529d9bbc3076dda18 (diff)
downloadtxr-ae2dc9643abab6b6f15e2f5fa6c8596e0010494e.tar.gz
txr-ae2dc9643abab6b6f15e2f5fa6c8596e0010494e.tar.bz2
txr-ae2dc9643abab6b6f15e2f5fa6c8596e0010494e.zip
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.
-rw-r--r--stream.c19
-rw-r--r--tests/018/format.tl4
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 ")