* Set default error code to -4 in main(), Fixes #1142
* fix --exit-code with more than one object in input, Fixes #1139
- Return code 1 or 4 based on last output, not last input.
Nicolas Williams [Tue, 11 Dec 2018 03:54:59 +0000 (21:54 -0600)]
Allow variable refs as object keys {$key:value}
Users are often surprised by the requirement to parenthesize any
non-trivial object key expressions in object constructors. E.g.,
{"a"+"b":1}. This commit adds one more kind of key expression besides
literals and idents: variable references.
A common use case for this is jq programs as JSON templates to fill in
with variables computed from inputs or passed in on the command-line.
E.g., {some_key:$value}. Now users can also use, e.g., {$key:$value}.
This and the restrictions on key and value expressions in object
constructors are now clarified a bit in the documentation.
Alex Ozdemir [Thu, 2 Aug 2018 07:25:07 +0000 (00:25 -0700)]
Bugfix: Math function checking
We had config machinery that determined which math functions are
available in libc. If a c math function was missing on the host system,
then the corresponding jq function would be removed from the source,
enabling the build to proceed anyway. The detection machinery was broken
in a subtle way, as was shown after glibc updated to 2.27, dropping the
`pow10` function. This caused compilation to fail.
The essential problem was that we detected whether a math function was
available by compiling and linking a small program evaluating that
function on constants. However, since gcc's optimization machinery has
special knowledge of some math functions (e.g. `pow10`), it can
optimize them away, even if they don't exist in the library and are not
linkable. That is, the following example compiles and links against
glibc 2.27, even though `pow10` has been removed:
```
int main () {
printf("%f", pow10(0.5));
return 0;
}
```
What?!
On the other hand, this program does not link:
```
int main () {
double f;
printf("%f", &f);
printf("%f", pow10(f));
return 0;
}
```
In the first program the call to `pow10` can be optimized away as a
constant expression. This requires GCC to know about `pow10` (which it
does!), but it does not require `pow10` to be in the library (and
actually linkable).
The solution is to use autoconf's machinery for detecting function
presence, instead of our own (buggy) machinery. This has the added
benefit of simplifying the code.
William Langford [Sat, 18 Aug 2018 03:23:10 +0000 (23:23 -0400)]
Restore JV_PRINT_COLOUR as an alias
JV_PRINT_COLOUR was part of the public libjq headers and was removed as
part of 2d05b54. While JV_PRINT_COLOR is definitely the preferred
spelling this side of the pond, we shouldn't just remove otherwise
exposed enum values.
William Langford [Sat, 18 Aug 2018 02:47:13 +0000 (22:47 -0400)]
Fix destructuring alternation
Attempting to use the existing FORK_OPT opcode resulted in difficulty
knowing when to pop an error message off the stack and when not to. This
commit makes DESTRUCTURE_ALT a real opcode that is identical to
FORK_OPT, except for never pushing the error message onto the stack when
continuing from an error backtrack.
Some small changes were necessary to the DUP/POP behavior surrounding
destructuring to accomodate this.
jv_file.c: check to see if the file is a directory and fail
Not all stdio implementations disallow one to open a directory with
fopen(3) and so we specifically check for directories as it is also
in the standard search path.
While the semantics are desirable, there is no way to implement them
efficiently. The reason is that in order to handle backtracking (empty)
from the state update expression, we have to retain a reference to the
reduction state value in order to restore it upon backtracking.
Retaining a reference to the reduction state kills performance by
causing lots of additional memory allocations and garbage because the
input to the update expression will always have at least two references,
thus no changes to it can be done in-place, and all changes end up being
CoW changes.
Avoiding this is the very reason for the LOADVN instruction (leaving
`null` in the variable loaded from).
William Langford [Thu, 30 Nov 2017 01:40:36 +0000 (20:40 -0500)]
Actually fix the strptime tests
This has been a complicated issue to fix for a number of reasons.
The core of it is that the behavior is different between different
versions of macOS, some of which set possible-but-incorrect values.
This commit addresses the issue by always using our computation for
tm_wday and tm_yday on macOS. As a side-effect, strptime format
strings that specify %u and %j will no longer work on macOS.
Keep object keys in parsing order in `tostream` output
As noted by @nicowilliams, `tostream` used `keys`,
which sorts the keys in alphabetical order, instead
of `keys_unsorted`, which preserves the parsing order.
William Langford [Tue, 28 Nov 2017 03:57:50 +0000 (22:57 -0500)]
Fix strptime tests on macOS 10.12
Dates in 1900 are before the Unix epoch. We shouldn't make any promises
about how well they are supported, especially given that our time
support is a thin wrapper over the libc functions.
This changes the test to use dates after the epoch, which should fit
within both a signed and an unsigned 32-bit time_t.
Nicolas Williams [Sun, 21 May 2017 21:24:48 +0000 (16:24 -0500)]
Deal with strptime() on OS X and *BSD (fix #1415)
strptime() on OS X and *BSDs (reputedly) does not set tm_wday and
tm_yday unless corresponding %U and %j format specifiers were used.
That can be... surprising when one parsed year, month, and day anyways.
Glibc's strptime() conveniently sets tm_wday and tm_yday in those cases,
but OS X's does not, ignoring them completely.
This commit makes jq compute those where possible, though the day of
week computation may be wrong for dates before 1900-03-01 or after
2099-12-31.
Nicolas Williams [Sun, 21 May 2017 06:58:18 +0000 (01:58 -0500)]
Attempt to fix #1415
OS X (and *BSD) strptime() does not set tm_wday nor tm_yday unless
corresponding format options are used. That means we must call timegm()
to set them.
Nicolas Williams [Wed, 15 Mar 2017 06:07:37 +0000 (01:07 -0500)]
Conditional exprs are not path exprs (fix #1368)
The conditional expression in if-then-elif-else-end cannot contribute to
path expressions because it doesn't change the input to any of the then/
elif/else expressions. These must be generated via gen_subexp().