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
commita2a0ee42bae0fb615b2e9d3666090ce3d21031a0 (patch)
tree87d2e0e473d1140d6497076409a442f59d669fd9
parent9d13a0cec435de1b689b2be979df1cfb53f5404d (diff)
downloadtxr-a2a0ee42bae0fb615b2e9d3666090ce3d21031a0.tar.gz
txr-a2a0ee42bae0fb615b2e9d3666090ce3d21031a0.tar.bz2
txr-a2a0ee42bae0fb615b2e9d3666090ce3d21031a0.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 ")