summaryrefslogtreecommitdiffstats
path: root/src/execute.c
diff options
context:
space:
mode:
authorLeonid S. Usov <leonid@practi.net>2018-10-19 21:57:41 +0300
committerWilliam Langford <wlangfor@gmail.com>2019-04-03 22:20:31 -0400
commitff8924ce16e58f7a7545f42a4971e2dbd3804ab7 (patch)
tree6e611aeb2df4688c66ee891302e93a4c354ae2c0 /src/execute.c
parentb9d2d1f666c5a5d813c23dcebb222285d08f8ae5 (diff)
Save literal value of the parsed number to preserve it for the output
Extend jv_number to use decNumber for storing number literals. Any math operations on the numbers will truncate them to double precision. Comparisons when both numbers are literal numbers will compare them without truncation. Delay conversion of numbers to doubles until a math operation is performed, to preserve precision. A literal jv_number will only need conversion to double once, and will reuse the resultant double on subsequent conversions. Outputting literal jv_numbers preserves the original precision. Add strong pthread requirement to manage contexts/allocations for converting numbers between their decNumber, string, and double formats.
Diffstat (limited to 'src/execute.c')
-rw-r--r--src/execute.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/execute.c b/src/execute.c
index 65c6bc77..fd2ab2c7 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -509,21 +509,25 @@ jv jq_next(jq_state *jq) {
uint16_t v = *pc++;
jv* var = frame_local_var(jq, v, level);
jv max = stack_pop(jq);
- if (raising) goto do_backtrack;
+ if (raising) {
+ jv_free(max);
+ goto do_backtrack;
+ }
if (jv_get_kind(*var) != JV_KIND_NUMBER ||
jv_get_kind(max) != JV_KIND_NUMBER) {
set_error(jq, jv_invalid_with_msg(jv_string_fmt("Range bounds must be numeric")));
jv_free(max);
goto do_backtrack;
- } else if (jv_number_value(jv_copy(*var)) >= jv_number_value(jv_copy(max))) {
+ } else if (jv_number_value(*var) >= jv_number_value(max)) {
/* finished iterating */
+ jv_free(max);
goto do_backtrack;
} else {
- jv curr = jv_copy(*var);
+ jv curr = *var;
*var = jv_number(jv_number_value(*var) + 1);
struct stack_pos spos = stack_get_pos(jq);
- stack_push(jq, jv_copy(max));
+ stack_push(jq, max);
stack_save(jq, pc - 3, spos);
stack_push(jq, curr);
@@ -1010,6 +1014,9 @@ jq_state *jq_init(void) {
jq->attrs = jv_object();
jq->path = jv_null();
jq->value_at_path = jv_null();
+
+ jq->nomem_handler = NULL;
+ jq->nomem_handler_data = NULL;
return jq;
}