Compare commits

...
912 Commits
Author SHA1 Message Date
William Langford 46d1ce2667 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.
2018-08-17 23:23:10 -04:00
William Langford 0673dee1b3 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.
2018-08-17 23:15:48 -04:00
William Langford 3dc5f4e948 Create issue template 2018-08-17 09:15:08 -04:00
Roland C. Dowdeswell 90bc29c1b5 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.
2018-05-11 19:32:25 -05:00
Nicolas Williams 7fd9e86ea6 Make limit/2 more efficient
Contributed by @pkoppstein.
2018-03-06 16:35:33 -06:00
Nicolas Williams e113c67d51 limit/2 evals exp one time too many 2018-03-06 11:29:13 -06:00
rain1 bf88c73c20 src/main.c: fix issue #1587 by using jv_dumpf in the raw-output and ascii-output case. retain fwrite in the raw-output case. 2018-03-01 14:33:47 -06:00
Riley Avron ae11f111a5 Fix "provides" typo 2018-02-23 14:10:47 -06:00
David Fetter 2ce1e323df Change backticks to the more legible $() 2018-02-20 15:54:21 -05:00
Jakub Jirutka 68d0048148 Build static binaries and deploy to GH Releases from Travis 2018-02-20 12:11:28 -05:00
Jakub Jirutka bafb43e589 Build and run tests against musl libc using Alpine Linux on Travis 2018-02-20 12:11:28 -05:00
Jakub Jirutka c163e88af3 Change Travis config to utilize Build Stages
See: https://docs.travis-ci.com/user/build-stages/
2018-02-20 12:11:28 -05:00
Paul Chvostek bd34b8dd2e fix FreeBSD install instructions 2018-01-04 15:50:20 -06:00
Larry Aasen 61edf3fa93 Updated the compile-ios.sh script to fix issues with local oniguruma path. 2017-12-12 18:27:59 -06:00
Nicolas Williams 8eff744eec Update AUTHORS 2017-12-11 12:22:02 -06:00
David Fetter b4742c1257 Added rawfile
In passing, clean remnants of argfile from slurpfile docs.
2017-12-11 12:17:17 -06:00
Nicolas Williams 9a4576e756 Revert "reduce: handle empty updates (fix #1313)"
This reverts commit e24af3c78e.

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).
2017-12-11 11:20:16 -06:00
Nicolas Williams b5560d8420 Fix import as $data linking 2017-12-10 23:09:35 -06:00
William Langford 79ece35981 Fix hang for slurped inputs with trailing newline 2017-12-04 20:10:56 -05:00
William Langford f06deb828a Fix #1534 2017-12-04 19:20:58 -05:00
William Langford 0c9eacedaa 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.
2017-11-29 20:47:56 -05:00
Eric Bréchemier 476b36770d 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.

Fixes #1541.
2017-11-29 11:46:08 -06:00
Andrew Speed 239278fd3a Use rvm to install ruby 1.9.3 2017-11-28 08:51:38 -05:00
William Langford 98b36e74b8 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.
2017-11-27 22:57:50 -05:00
William Langford c3cbbdd8a2 Fix memory leaks in various c-coded builtins 2017-11-27 20:37:14 -05:00
Nicolas Williams 18879fb993 Fix leak on error in strptime 2017-11-23 01:51:22 -06:00
trantor bdaddcf107 Typo correction
Suppresion -> Suppression
2017-11-22 13:47:35 -05:00
William Langford 7b81a836c3 Merge pull request #1403 from Argoday/master
Use unsorted keys in walk
2017-06-19 10:55:26 -04:00
Nicolas Williams c538237f4e 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.
2017-05-21 16:24:48 -05:00
Nicolas Williams 4a6241be06 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.
2017-05-21 01:58:18 -05:00
Nicolas Williams 1900c7bcac Add private my_timegm() 2017-05-21 01:57:55 -05:00
Nicolas Williams 578d536233 Fix HAVE_TM_TM_GMT_OFF usage 2017-05-21 01:53:00 -05:00
Nicolas Williams b0d6d28310 Use AC_CHECK_MATH_FUNC() for all math functions 2017-05-21 01:22:39 -05:00
Nicolas Williams 10d66051ef Fix jv_load_file() assertion (fix #1410) 2017-05-20 18:53:48 -05:00
Daniel Lange cb3d5aff84 Improved git build instructions. 2017-05-11 09:05:56 -04:00
Jonathan Word ca12bd9b5d Use unsorted keys in walk
Preserve key sorting order when executing in walk, if sorted keys is desired `--sort-keys` should be used to explicitly obtain sorted keys.
2017-05-03 15:49:21 -04:00
Nico Williams 6d89e297fe Add JQ_COLORS env var for color config (fix #1252) 2017-04-29 14:00:52 -04:00
Nicolas Williams 32d8f2000a Fix build 2017-04-26 20:55:50 -05:00
Nicolas Williams 0bd7614bd5 Always use jv_mem_*alloc() 2017-04-21 18:41:06 -05:00
pkoppstein 4b4cf789e0 def isempty(g) # Testing 'isempty(empty)' at line number 1364 2017-04-15 16:45:00 -05:00
William Langford 76b1fc18f1 Update oniguruma to fix #1370 2017-04-02 14:58:59 -04:00
William Langford 405071337d Don't require java to build gh-pages 2017-03-31 18:48:28 -04:00
William Langford 151b494382 Add collect example with pipeline 2017-03-31 18:48:05 -04:00
William Langford 12f74b226e Add missing close-backtick in docs 2017-03-30 22:23:47 -04:00
Nicolas Williams 18753cb7a7 Also fix jn/2 and yn/2 2017-03-30 11:46:03 -05:00
Nicolas Williams 71d4ff6ed8 Fix frexp, modf, lgamma_r (fix #1374) 2017-03-29 00:07:42 -05:00
Nicolas Williams 7935d307f0 Allow . as {$a:$b} destructuring 2017-03-26 05:36:23 -05:00
Nicolas Williams 38bfec1594 Add flex/bison outputs 2017-03-26 05:36:23 -05:00
Nicolas Williams 2421dfb843 Add more destructuring tests 2017-03-26 05:36:22 -05:00
William Langford 94035be3fa Add --debug-trace=all for detailed debug output
When tracing execution, print the whole stack, not just the items used by the
current opcode
2017-03-26 05:36:22 -05:00
William Langford c8a2a0acc2 Fix a tripped assertion when generating reduces
A noop body, while useless, should still compile successfully
2017-03-26 05:36:22 -05:00
William Langford 3a8c8f4747 Add alternation destructuring operator ?//
This is a first pass to show the implementation.
It needs tests and evaluation, but doesn't break any existing tests.

NOT READY FOR MERGING
2017-03-26 05:36:22 -05:00
Nicolas Williams b142d484d5 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().

See also #1366.
2017-03-15 01:07:37 -05:00
Nicolas Williams 674e9fb7c2 Make and build dist in travis-CI (#1356) 2017-03-04 23:14:36 -06:00
Nicolas Williams 6878123202 Make configure.ac work for shallow clones 2017-03-04 22:57:35 -06:00
Nicolas Williams f7bf9a8e96 Make scripts/version work in shallow clones
Shallow clones don't have tags.  Use git describe --always --dirty in
such cases.

XXX Add branch name.
2017-03-03 14:30:58 -06:00
Nicolas Williams 89809a2d0f Fix make dist 2017-03-01 23:01:08 -06:00
Nicolas Williams 9df19f53e4 Fix off-by-one bug in #1108 fix 2017-03-01 22:45:02 -06:00
Nicolas Williams 65cbaac344 Array slice overflows (fix #1108) 2017-03-01 17:48:45 -06:00
Nicolas Williams 2fcb257168 getpath/1 should be a path expression (fix #1358)
It needs to be possible to do something like

    getpath($paths[]) += 1

meaning: increment all the paths in . that are listed in $paths[].

In order to do this getpath() needs to update the jq->path and
jq->value_at_path as necessary.
2017-02-28 21:54:30 -06:00
William Langford 63791b795a Fix name of builtins in the builtins/0 output 2017-02-26 19:50:10 -05:00
Nicolas Williams ea90b947b0 Fix warning about environ 2017-02-26 18:22:30 -06:00
Nicolas Williams 9a0d796298 Fix --without-oniguruma build 2017-02-26 18:22:23 -06:00
Nicolas Williams 0337027d54 Fix environ Win32 build problem 2017-02-26 18:06:35 -06:00
Nicolas Williams 8ea21a54ad Add halt, halt_error builtins (fix #386) 2017-02-26 16:34:56 -06:00
Nicolas Williams 6bac4ed059 Document stderr 2017-02-26 16:34:56 -06:00
Nicolas Williams a03ae02f44 Fix memory leak 2017-02-26 16:33:50 -06:00
Nicolas Williams 45f126514c Fix Appveyor for non-master branches 2017-02-26 16:13:22 -06:00
Nicolas Williams b279713e47 fixup 2017-02-26 16:12:57 -06:00
Nicolas Williams 3504bd9a2a Add $ENV builtin variable to access environment 2017-02-26 00:39:24 -06:00
Nicolas Williams 1a8a0ae0f5 Fix error message for undefined vars 2017-02-26 00:37:28 -06:00
Nicolas Williams 441b066dd8 Preserve precious vars in configure.ac (fix #795) 2017-02-25 21:49:38 -06:00
Nicolas Williams ef87010059 Document $ARGS and friends 2017-02-25 19:21:06 -06:00
Nicolas Williams 66fb962a66 Add $ARGS, --args and --jsonargs (fix #1345) 2017-02-25 19:13:28 -06:00
Nicolas Williams e8abc0a2f6 jq_compile_args(): allow object args to be object 2017-02-25 19:13:28 -06:00
Nicolas Williams 7b1bd99de6 Add jv_object_has() 2017-02-25 19:13:28 -06:00
Nicolas Williams 8619c6e060 Make test/shtest test of constant folding robust
Rather than testing that a constant expression produces so many
instructions, test that a variety of of such expressions produce the
same number of instructions.  This will make future changes in the
compiler less likely to break this test.
2017-02-25 19:13:28 -06:00
Nicolas Williams 2e1f2db8b5 Improve Appveyor build
Among other things, make TESTS=... breaks when using modules/oniguruma,
so set SUBDIRS= then.
2017-02-25 18:57:38 -06:00
Nicolas Williams ba32b33796 Windows: configure fails to detect missing math
For some reason AC_CHECK_MATH_FUNC() on Windows is not detecting a
handful of math functions as not being supported.  This commit is a bit
of a hack.
2017-02-25 18:51:09 -06:00
Nicolas Williams 6e77b017c5 Make comment consistent with code 2017-02-25 18:51:09 -06:00
Yasuhiro Matsumoto 5d058fa416 Don't call SetConsoleOutputCP
Should use wide-string function instead of SetConsoleOutputCP.

Fixes #1121
2017-02-25 18:51:04 -06:00
Yasuhiro Matsumoto 12c60b2f32 Quiet a compiler warning 2017-02-25 18:49:22 -06:00
Nicolas Williams 9801de6979 Windows: Also use -lshlwapi for jq(1) 2017-02-25 14:49:20 -06:00
Nicolas Williams c695f2cd9c When using builtin Oniguruma, set flags correctly
This should fix the Travis-CI build.
2017-02-25 14:11:42 -06:00
Nicolas Williams 27c29aeb7b Document localtime and strflocaltime 2017-02-23 23:39:24 -06:00
Nicolas Williams 06f20603f6 Add localtime and strflocaltime (fix #1349) 2017-02-23 22:26:53 -06:00
Nicolas Williams 607a9e3912 Improve manual section on assignment forms 2017-02-23 22:17:54 -06:00
Nicolas Williams d3b4ad04f5 Revert e7caf68 for Dockerfile 2017-02-23 22:01:43 -06:00
Nicolas Williams e7caf68edd Attempt to use builtin Oniguruma for CIs 2017-02-23 00:33:08 -06:00
Nicolas Williams c6374b6a1f Allow ./configure --with-oniguruma=builtin
This allows one to force the use of jq's builtin copy of Oniguruma
(builtin as a git submodule).

We still need to fix make dist to include that copy of Oniguruma.
2017-02-23 00:30:13 -06:00
Nicolas Williams 8cde328007 Allow var bindings in path expressions (#1347)
The expression in a variable binding is not and must not be seen as
being part of a path expression in which the variable binding appears.
2017-02-21 18:11:35 -06:00
Erik Brinkman 02bad4b298 Add local oniguruma submodule
Configure should still allow use of prebuilt onigurumas (whether
system-installed or in a special prefix).  If these are not found, and
configure was not called with `--without-oniguruma`, then use the vendored
oniguruma module.  If configure was called with `--without-oniguruma`, then we
do not build regex functionality into jq.
2017-02-18 21:34:26 -05:00
Nicolas Williams 9b2179089b Improve manual 2017-02-15 11:48:39 -06:00
William Langford 1c806b74ea Add builtins builtin 2017-02-13 11:36:20 -05:00
William Langford 8001955fb7 Fix memory leak in libm cfunctions 2017-02-13 11:36:20 -05:00
William Langford e6fa039f3f Merge pull request #1089 from l8nite/base64_decode 2017-02-12 16:25:44 -05:00
Shaun Guth e0b784ac6d Add @base64d for decoding base64 #47 2017-02-12 16:03:59 -05:00
J Phani Mahesh dc679081fa fix truncate_stream to match docs 2017-02-07 21:30:55 -06:00
Nicolas Williams 597c1f6667 Add more missing math functions 2017-02-04 00:11:46 -06:00
Nicolas Williams 125071cf00 Fix handling of unsupported math functions 2017-02-04 00:11:10 -06:00
Nicolas Williams 2fb099e4cf Promote wiki more in README 2017-01-31 16:13:32 -06:00
Nicolas Williams 6f9646a44f Improve docs somewhat, inspired by #1326 2017-01-30 14:11:05 -06:00
Nicolas Williams bd7b48c1b9 Make |= delete LHS when RHS is empty (Fix #1314)
Now that #1313 is fixed, |= no longer outputs null when the RHS update
expression outputs empty.

When a user wants to keep the current value of the LHS they would have
the RHS update expression output `.`, so having `empty` achieve the same
thing would be redundant.  The obvious thing to do is to delete the LHS
when the RHS update outputs `empty` (i.e., doesn't output any values).

It's reasonable to think that existing programs won't be broken by this
change, because reduce and |= not handling empty well is clearly a bug.
(Though it's possible that some programs were using empty to quickly
terminate reduce or |=, it's not likely.  They should use label/break
instead.)

Prior to this change |= would use the _last_ value output by the RHS
update expression.  With this change |= will use the _first_ value
instead.  This change _is_ a minor backwards-incompatible change.  It
may or may not be acceptable; we'll see.  It is a useful change in that
it makes |= faster when the update expression produces multiple values.
2017-01-30 14:11:05 -06:00
Nicolas Williams aac8132f47 recurse (i.e., ..) needs to find leaf nulls 2017-01-30 14:11:05 -06:00
Nicolas Williams 7bdf3a39ad Add SQL-style operators (#1322) 2017-01-30 14:11:05 -06:00
Nicolas Williams 396543191c Make first(g) more efficient: extract only 1 value
first(g) was extracting two values, which, if g is slow, made first(g)
slow.  And if the second extraction were to throw an error, then
first(g) would throw that error, which is clearly not the right thing to
do.  Besides that, first(g) was allocating garbage, which it no longer
does.
2017-01-30 14:11:05 -06:00
Nicolas Williams e24af3c78e reduce: handle empty updates (fix #1313) 2017-01-30 14:11:05 -06:00
Attila Fülöp e82147bbb8 Solaris needs XPG6 for c99 2017-01-28 19:16:23 -06:00
William Langford d2c3cf49e1 Merge pull request #1317 from wtlangford/dont-split-utf8-sequences
Handle cut-off UTF-8 sequences when reading files
2017-01-27 21:45:15 -05:00
William Langford e84d17196c Handle cut-off UTF-8 sequences when reading files
Read additional bytes from the file to complete the UTF-8 sequence so the bytes
in it don't get converted to U+FFFD replacement characters.
2017-01-27 21:04:26 -05:00
W-Mark Kubacki fd4ae8304e Parse no deeper than MAX_PARSING_DEPTH
while true; do printf '{"deeper": '; done | jq .
2017-01-27 09:59:44 -06:00
W-Mark Kubacki 83e2cf607f Skip printing what's below a MAX_PRINT_DEPTH
This addresses #1136, and mitigates a stack exhaustion when printing
a very deeply nested term.
2017-01-27 09:59:44 -06:00
Jakub Wilk 61b75639a7 gen_utf8_tables: remove unused variable 2017-01-26 13:15:59 -06:00
Jan Schulz 19d266b528 Revert "Disable appveyor build for now"
This reverts commit 0b8218515e.

There is a new oniguruma package which previously trashed the build.
2017-01-23 16:28:01 -06:00
Richard Groves 9c4238c2f6 Typo fixed
simply -> simple
2017-01-23 16:21:37 -06:00
Janne Cederberg 114ac72169 Documentation clarification suggestions 2017-01-23 15:48:44 -06:00
James Pearson Hughes a10d7fbb02 Update download instructions for Arch
jq has been in the community repo for [just over a year now][0].

[0]: https://projects.archlinux.org/svntogit/community.git/commit/trunk?h=packages/jq&id=8d5e06065bc92bf56ea651970c9bda07fb545554
2017-01-23 15:46:17 -06:00
Tim McCormack f33af0b16a Typo: s/more/mode/ in --seq 2017-01-23 15:45:07 -06:00
Clément MATHIEU eeba7b3167 Fix input_(line_number|filename) leak memory 2017-01-23 15:18:51 -06:00
Jay Satiro e5c30e6fae Fix cross-compile tmp dir removal
- cd out of the tmp dir before attempting to remove it.
2017-01-23 15:10:57 -06:00
Nicolas Williams 0b8218515e Disable appveyor build for now 2016-03-21 18:59:52 -05:00
David Tolnay 1a8a5ee000 Remove David from maintainers 2016-02-24 00:39:56 -08:00
Nicolas Williams 1740fd036d Travis-CI build for OSX (fix #1083) 2016-01-19 00:19:24 -06:00
Nicolas Williams 6c635998f8 Always test sort_by/group_by post-#1082 2016-01-18 12:17:58 -06:00
Stephen Dolan 7835a724d6 Make jv_sort stable regardless of qsort details. 2016-01-18 10:41:25 -06:00
Stephen Dolan 239c357af0 Add AppVeyor badge to README.md
Thanks @JanSchulz, @nicowilliams!
2016-01-18 10:15:43 +00:00
Nicolas Williams d228490162 Add --enable-ubsan (undefined behavior sanitizer) 2016-01-17 13:06:27 -06:00
Nicolas Williams b92a12cf6c Run failing tests on Windows; ignore failures 2016-01-17 12:46:57 -06:00
Nicolas Williams c514368f98 Make it possible to run tests with set -x
One can now run:

    make TRACE_TESTS=1 check

to get detailed output
2016-01-17 12:45:01 -06:00
Nicolas Williams 062f86a625 Enable more tests on Windows; move sort_by tests
Use %%FAIL IGNORE MSG for error messages that differ on Windows, and
move the sort_by/group_by tests that fail qhen qsort() is not stable.

Now only tests/sorttest and tests/shtest are disabled on Windows.
2016-01-17 12:45:01 -06:00
Nicolas Williams c3d13260a7 Tweak appveyor.yml; disable failing tests 2016-01-17 01:49:50 -06:00
Jan Schulz e6e07cd2c6 Upload build failure logs
Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2016-01-16 17:02:43 -06:00
Jan Schulz ec4dfd32cc Build a html help
Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2016-01-16 17:02:43 -06:00
Jan Schulz c0e01452f2 Run tests on appveyor
Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2016-01-16 17:02:43 -06:00
Jan Schulz 45260890f2 Add 32bit windows builds on appveyor
Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2016-01-16 17:02:43 -06:00
Jan Schulz 4337fc5fe0 Build on windows (mingw) on appveyor
For this to work, one of the core commiter should do:

* enable appveyor in the github project (grant access)
* Make an appveyor account and add the github jq repo as a new project

inspirations from:

appveyor, msys2, use bash environment to build...
* https://github.com/ariscop/elemental-ircd/blob/appveyor/appveyor.yml
* https://github.com/khaledhosny/ots/pull/67/files
* https://github.com/universal-ctags/ctags/blob/master/appveyor.yml
* https://github.com/universal-ctags/ctags/blob/master/win32/appveyor.bat

and with mvsc
* https://github.com/khaledhosny/ots/blob/master/.appveyor.yml

Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2016-01-16 17:02:43 -06:00
Nicolas Williams 093d20c3b9 Fix cross-compilation build 2016-01-16 16:51:06 -06:00
Nicolas Williams ec07936888 Fix Windows build (fix #911) 2016-01-16 16:51:01 -06:00
Nicolas Williams 8e4724e16c fixup non-maintainer build 2016-01-15 16:06:18 -06:00
Nicolas Williams 3afdbb7b7d Always build src/builtin.inc (fix #1069) 2016-01-15 11:59:14 -06:00
Nicolas Williams f217fa26ae MultiByteToWideChar() usage bug (fix #1072) 2016-01-15 11:58:41 -06:00
Nicolas Williams 8f6f28c8d3 Make it easier to use jq with shebangs (fix #1044)
Allow a continuation on a comment immediately after a shebang to make
this traditional hack possible:

    #!/bin/sh
    # this next line is ignored by jq \
    exec jq -f "$0" "$@"
    # jq code follows

But continue only on the first line following a shebang, and only if
it's a comment.
2015-12-14 22:08:17 -08:00
Nicolas Williams 856a4b2f3f Add note about IEEE754 to help msg 2015-12-15 00:00:03 -06:00
Cameron Sparr 6d76cd0a99 Change usage formatting 2015-12-14 23:58:28 -06:00
Romero Malaquias 6151f20477 Avoiding conditional directives that break statements 2015-12-09 15:29:35 -06:00
pkoppstein ad8d1a8cc8 Two sub bugs fixed; two new gsub tests have been added.
./jq --run-tests < tests/onig.test
has been run successfully:

...
Testing 'gsub("a";"b")' at line number 70
Testing 'gsub( "(.*)"; "";  "x")' at line number 74
...
22 of 22 tests passed (0 malformed)
2015-12-09 15:28:01 -06:00
Nicolas Williams ec583deefa Fix JV_OBJECT() and go up to 18 2015-12-01 23:27:19 -06:00
Nicolas Williams 5fe053671a Assume . if either stdin/on isatty() (fix #1028)
And move the #define of isatty on Windows up.
2015-12-01 23:27:19 -06:00
Mark McKinstry 0d177d240d yum has been replaced with dnf as of f22
https://fedoraproject.org/wiki/Changes/ReplaceYumWithDNF
2015-11-26 10:48:06 -05:00
David Tolnay 18b4b18b41 Support --without-oniguruma 2015-11-21 10:05:37 -08:00
David Tolnay befd192958 Oniguruma hash in dockerfile 2015-11-18 00:30:18 -08:00
Loamhoof 79f9ecd150 Fix manual signature for split (non-regex) 2015-11-15 21:43:38 +01:00
Nicolas Williams 8f115e9eed Add address sanitizer (ASAN) support (fix #1002) 2015-10-27 20:06:21 -05:00
David Tolnay e17ccf2297 Support numbers and boolean in join (fix #930) 2015-10-25 12:40:15 -07:00
Nicolas Williams 8eb1367ca4 Heap buffer overflow in tokenadd() (fix #105)
This was an off-by one: the NUL terminator byte was not allocated on
resize.  This was triggered by JSON-encoded numbers longer than 256
bytes.
2015-10-24 17:27:56 -05:00
David Tolnay 2f79004f85 strptime() on OpenBSD requires _XOPEN_SOURCE_EXTENDED 1 (fix #999)
strptime() is an XPG4v2 function, on OpenBSD the prototype
is not included in time.h unless visibility is set, it needs
either "#define _XOPEN_SOURCE_EXTENDED 1" or _XOPEN_SOURCE
>= 500. Without this the prototype isn't included and
strptime's returned pointer is truncated to an int, causing
SEGV on 64-bit arches when using it.

Thanks @sthen
2015-10-24 11:23:56 -07:00
David Tolnay b7a219a91d mktemp needs 6 or more X's (fix #1000)
mktemp(1) isn't posix specified, but it's reasonable to use
mktemp(3) to implement it which requires 6 trailing X's in
the format

Thanks @sthen
2015-10-24 11:21:18 -07:00
Nicolas Williams aa279ae7ac Fix builtin.o dependency (#992) 2015-10-22 22:33:47 -05:00
Nicolas Williams 4060535f9f Fix linux32 jq-1.5 executable (fix #935) 2015-10-22 22:07:34 -05:00
Nicolas Williams 1847333342 Rename sig/v1.5/jq-linux32.asc (prep for #935) 2015-10-22 22:06:27 -05:00
Nicolas Williams 87c278c8a5 Remove setup.sh (fix #993) 2015-10-22 21:53:53 -05:00
David Tolnay 143e8dc5e4 Move jq-coded builtins to non-C file (fix #424) 2015-10-22 19:26:00 -07:00
David Tolnay b80d58e167 Move docs for map earlier (fix #288) 2015-10-17 23:54:07 -07:00
David Tolnay 6c31850e86 If-then-else documentation for forking conditional (fix #942) 2015-10-17 21:15:24 -07:00
David Tolnay c8dc164566 Support lowercase name in from_entries (fix #990) 2015-10-17 20:50:40 -07:00
David Tolnay 32e5e6af4b Revert "Adjust spacing of section headers to account for nav bar (fix #986)"
This reverts commit 73b8413d10.

The fix for #986 caused #988.
2015-10-13 23:29:57 -07:00
David Tolnay 4a886f831c Autocomplete manual search to first result on submit 2015-10-13 10:48:06 -07:00
David Tolnay e3c36777ab Add background color to typeahead menu 2015-10-12 22:50:03 -07:00
David Tolnay c2395f0278 Sort manual search results shortest to longest 2015-10-12 22:35:37 -07:00
David Tolnay 0791261f07 Remove backticks from manual headers and search strings 2015-10-12 22:30:16 -07:00
David Tolnay 73b8413d10 Adjust spacing of section headers to account for nav bar (fix #986) 2015-10-12 22:12:37 -07:00
David Tolnay 664b8e26f0 Merge typeaheadjs.css into base.scss 2015-10-12 21:03:42 -07:00
David Tolnay 64ade137bc PGP signatures for release binaries (fix #889) 2015-10-12 20:57:53 -07:00
David Tolnay da15e10bd0 Accept only bitwise identical NaN values in jv_identical (fix #978) 2015-10-12 20:47:22 -07:00
David Tolnay 1f7c24fea7 Add signing key and dtolnay's key fingerprints to KEYS 2015-10-12 20:07:24 -07:00
Nicolas Williams 49b8382c5f Remove expired key from KEYS 2015-10-12 19:11:52 -05:00
Nicolas Williams 583ab589dc Add KEYS file 2015-10-12 19:01:02 -05:00
David Tolnay c80c07ab68 Link to BootstrapCDN for Bootstrap and Bootswatch (fix #985) 2015-10-12 12:19:25 -07:00
David Tolnay c5875504da Explicitly use current directory in Rakefile 2015-10-12 10:46:17 -07:00
David Tolnay 05d1c09cc1 Split up Rakefile to minimize dependencies (fix #435) 2015-10-12 10:42:15 -07:00
David Tolnay 9d6e91ea7b Add description for rake tasks
You can see the descriptions by running `rake --tasks`.
2015-10-12 10:21:18 -07:00
David Tolnay 4887cfd951 Remove duplicate yaml import in Rakefile 2015-10-12 10:10:56 -07:00
David Tolnay 9a51696bc0 Remove old Rakefile dist targets
Because binaries no longer go into the repo.
2015-10-12 10:03:18 -07:00
Simon Elsbrock bf271b8062 docs: jq 1.5 is now available in Debian unstable
It may take some time until it bubbles up into Ubuntu repositories.
2015-10-12 10:02:07 +02:00
David Tolnay 2864fb467e Bump fedora and chocolatey available version numbers 2015-10-02 19:19:36 -07:00
David Tolnay 4490d9d1f6 Support NaN in path expressions (fix #962) 2015-09-24 10:33:34 -07:00
Nicolas Williams c4524da3e0 EOF after newline in string mishandled (fix #951) 2015-09-22 20:11:54 -07:00
David Tolnay 58f082d74f Delete negative indices in array (fix #954) 2015-09-21 20:33:06 -07:00
David Tolnay 154d0ee4a8 Fix assert fail if object literal key is not a string (fix #953) 2015-09-21 12:47:06 -07:00
Roman Inflianskas 83ab4e273b Add openSUSE repository 2015-09-20 08:15:15 -07:00
David Tolnay dccda74062 Address comments on PR #950 2015-09-16 10:48:50 -07:00
David Tolnay b52bebfbe8 Improve invalid object key error message 2015-09-16 09:53:42 -07:00
David Tolnay 1758c1ba74 Remove "Requires 1.5" from manuals
No longer necessary now that manuals are versioned.
2015-09-13 18:57:11 -07:00
Joel Nothman 83e8ec587f utf8bytelength: count UTF8 string bytelength
[Builtin name changed, and it only works on string inputs. -Nico]
2015-09-13 01:01:24 -05:00
Steven Penny 63dd033da7 Fix segmentation fault on Windows with long paths (fix #939) 2015-09-10 21:29:34 -07:00
David Tolnay 91f0dcff5c Avoid passing '/bin/bash' as default argument to docker run
Previously:

```
$ docker run dbdc663dabc8
jq: error: syntax error, unexpected '/', expecting $end (Unix shell quoting issues?) at <top-level>, line 1:
/bin/bash
jq: 1 compile error
$ docker run --entrypoint /bin/echo dbdc663dabc8
/bin/bash
```

Now:

```
$ docker run e36393e8c15e
jq - commandline JSON processor [version 1.5rc2-77-g9a3fe9e]
Usage: /usr/local/bin/jq [options] <jq filter> [file...]

	jq is a tool for processing JSON inputs, applying the
...
```
2015-09-05 13:03:01 -07:00
David Tolnay 688bb1993f Get oniguruma from github instead of geocities 2015-09-05 12:40:42 -07:00
David Tolnay 94bda489ce Fix indentation in Dockerfile 2015-09-05 11:54:56 -07:00
David Tolnay c9003e521c Add travis and coveralls badges to readme 2015-08-25 08:48:40 -07:00
Stephen Dolan 8105255be2 No-op commit to trigger first run of Travis. 2015-08-25 15:36:54 +01:00
Nicolas Williams f57743eb37 Remove jq.1.default and related content 2015-08-23 23:08:11 -05:00
David Tolnay 0c93eb3379 Move source files to src/ 2015-08-23 20:36:11 -07:00
David Tolnay 891f28ef5e Copy gitignore in website update script 2015-08-22 17:26:58 -07:00
David Tolnay 371e74a25f Remove obsolete comment in Makefile.am 2015-08-22 16:27:06 -07:00
David Tolnay 9ec27fe362 Sort source file lists in Makefile.am 2015-08-22 16:20:21 -07:00
David Tolnay 75662a4b05 Standardize indentation in Makefile.am
This was being done 5 different way in 5 places:

- indent 3 spaces, then tabs to column 73
- indent 2 spaces, then tabs to column 73
- indent 2 spaces, then a single tab
- indent with spaces up to equal sign, then tabs to column 73
- indent 1 tab, then tabs to column 73

I standardized on 8 spaces, then spaces to column 73. The 8
spaces lines up with common browsers' indentation of the
rest of the makefile, which is indented by single tabs. The
spaces to column 73 make sure the trailing backslashes line
up regardless of the tabstop setting.
2015-08-22 15:31:50 -07:00
David Tolnay 4a993dff29 Add gcov output to gitignore 2015-08-22 14:47:07 -07:00
David Tolnay 516e79151f Include "jv.h" instead of <jv.h> 2015-08-22 13:53:44 -07:00
David Tolnay 6c3934de15 Fix decoding of UTF-8 sequence length (fix #922) 2015-08-22 12:31:36 -07:00
David Tolnay 370833d555 Sort libm functions 2015-08-22 10:54:35 -07:00
David Tolnay 302ae77712 Remove unused libm functions 2015-08-21 09:45:16 -07:00
Frederic Cambus 5d23c240b6 Use 'snprintf' instead of 'sprintf'
This gets rid of a linker warning when compiling on OpenBSD:

    ./.libs/libjq.a(jv_print.o)(.text+0x2fc): In function `jvp_dump_string':
    /root/jq-1.5/jv_print.c:118: warning: sprintf() is often misused, please use snprintf()
2015-08-20 14:48:58 -07:00
David Tolnay 7032228879 Hide manual jqplay button and navigation in print mode 2015-08-20 11:14:14 -07:00
David Tolnay 8932cf719f Hide tutorial "show result" button in print mode 2015-08-20 00:02:09 -07:00
David Tolnay 7668a4f255 Expand all manual examples in print mode 2015-08-19 23:27:10 -07:00
David Tolnay 2c6c521799 Add FreeBSD install instructions (fix #917) 2015-08-18 08:21:57 -07:00
David Tolnay 19577fcefa Link to correct 1.5 source tarball 2015-08-17 18:04:56 -07:00
David Tolnay b8f71d3659 Fix assert fail when delpaths is given non-array (fix #901) 2015-08-16 19:44:16 -07:00
David Tolnay 2d05b5475c Standardize on "color" to match what the flag has always been called 2015-08-16 19:19:29 -07:00
David Tolnay 44a5c4b0b1 Fix "the the" in manuals 2015-08-16 19:04:38 -07:00
David Tolnay a12b9102c7 Fix examples in 1.4 manual 2015-08-16 19:01:32 -07:00
David Tolnay b5f8cb2126 Fix spelling of getpath and setpath in manual 2015-08-16 18:43:12 -07:00
David Tolnay 31be4a0495 Remove duplicate author
They seem to be the same person based on this pull request:
https://github.com/stedolan/jq/pull/80

I am keeping the email tied to his GitHub account.
2015-08-16 18:41:00 -07:00
David Tolnay e785a17a5f Sort authors 2015-08-16 18:41:00 -07:00
Nicolas Williams b6e3657eda Document getpath/setpath 2015-08-16 20:32:01 -05:00
David Tolnay ec7c3cf9a7 Fix -Wzero-length-array 2015-08-16 09:11:23 -07:00
David Tolnay eb2fc1d27e Fix unnecessary use of BLOCK macro 2015-08-16 09:01:35 -07:00
David Tolnay 73b9e8dc99 Fix -Wgnu-zero-variadic-macro-arguments 2015-08-16 09:00:31 -07:00
David Tolnay 490a843947 Add sha1sum for jq-osx-amd64 1.5 2015-08-16 08:46:22 -07:00
David Tolnay 6fa1300d39 Link to 1.5 binary for OS X (fix #912) 2015-08-15 23:44:41 -07:00
David Tolnay ef0fb50c1c Fix 1.5 manual title 2015-08-15 23:19:13 -07:00
David Tolnay 3608341c53 Update website for jq 1.5 (fix #910) 2015-08-15 23:12:31 -07:00
David Tolnay 461f04bd4d Rename header template to navbar
To avoid the confusing similarity between _head and _header.
2015-08-15 14:15:19 -07:00
David Tolnay 161a6fa635 Update gems
I updated some of these gems for a different project, and
suddenly `rake build` was giving very different output
compared to the current gh-pages. This commit makes sure
everyone updating gh-pages is using reasonably similar
versions, so we avoid spurious diffs.
2015-08-15 13:23:19 -07:00
David Tolnay 6d2f917a3a Move footer content into template
This caused problems because liquid >=3.0.0 does not allow a
variable and a template with the same name. Here we had a
variable and a template both called footer.
2015-08-15 13:03:33 -07:00
David Tolnay 8f55d6d4ab Use https where possible 2015-08-15 12:23:16 -07:00
David Tolnay 2306795864 Canonical URL and redirect to https site (fix #908) 2015-08-15 12:23:13 -07:00
David Tolnay e0eb03b96d Update website footer links 2015-08-14 11:29:47 -07:00
David Tolnay b1083ab367 Use entry title without whitespace as section id 2015-08-14 00:33:55 -07:00
David Tolnay e3e7cea177 Fix some w3c validator complaints 2015-08-14 00:01:49 -07:00
David Tolnay d36a85a369 Consistent indentation of shared templates 2015-08-13 23:08:52 -07:00
David Tolnay bd46a5dd52 Move all javascript to end of body 2015-08-13 23:00:54 -07:00
David Tolnay 7f87785002 Group logically related parser rule names 2015-08-13 22:39:31 -07:00
David Tolnay 0f419563ea Remove all trailing whitespace 2015-08-13 22:39:23 -07:00
David Tolnay aff6f49990 Tiny margin on tutorial accordions 2015-08-13 22:18:01 -07:00
David Tolnay 58a053d7de Fix memory leak in non-constant module declaration 2015-08-13 21:42:35 -07:00
David Tolnay 7b5c6a9224 Fix assert fail on invalid import path (fix #899) 2015-08-13 21:42:35 -07:00
David Tolnay 5479d7f2dc Fix assert fail on non-object import metadata (fix #900) 2015-08-13 21:42:35 -07:00
Nicolas Williams a5b2c55a70 Fix streaming docs errors (fix #904) 2015-08-13 23:38:14 -05:00
Nicolas Williams b119853aef Test main.c fix for #817 2015-08-13 09:08:37 -07:00
Nicolas Williams 5d08d54636 Make search path expansion portable (fix #817)
This is part 2 of the fix to #817.  Part 1 is the previous commit.
2015-08-13 09:08:37 -07:00
Nicolas Williams 10df52efed Make all global module paths absolute (fix #817)
This is part 1 of the fix for #817.  The next commit is part 2.
2015-08-13 09:08:37 -07:00
David Tolnay 68f84659f3 Update site from bootstrap 2.1.1 to 3.3.5 2015-08-13 01:10:16 -07:00
David Tolnay 3ef92863f2 Update wording and json bodies in tutorial 2015-08-11 22:02:53 -07:00
pkoppstein dea7868f01 spelling corrections; untabify 2015-08-11 20:54:03 -07:00
pkoppstein 16d0e528aa walk/1 2015-08-11 20:54:03 -07:00
Nicolas Williams c426d494f0 Improve assignment docs (see #897) 2015-08-11 18:05:22 -05:00
Nicolas Williams 9a3f802d20 Fix #896, double-free in setpath 2015-08-11 17:46:15 -05:00
David Tolnay 89897b4bcd Change index page links to github releases 2015-08-08 10:35:18 -07:00
David Tolnay f1d1fea467 Add SHA-1 checksums of release binaries (fix #726) 2015-08-08 01:19:39 -07:00
David Tolnay e404a1a96d Script to update gh-pages from master 2015-08-08 00:29:22 -07:00
David Tolnay b23d07875e Remove obsolete gitignore entry 2015-08-08 00:26:32 -07:00
David Tolnay 9a68905228 Replace jq-1.4 source tarball link 2015-08-07 22:53:48 -07:00
David Tolnay 486c275885 Replace website download links with github releases 2015-08-07 22:23:08 -07:00
David Tolnay a864e848b5 Add jq-1.5rc2 to index page news 2015-08-07 22:11:09 -07:00
David Tolnay a4dc312eff Break long line on index page 2015-08-07 22:09:06 -07:00
David Tolnay 765f9ac74c Clean up download page and fix links 2015-08-07 21:40:19 -07:00
David Tolnay 3fae608b65 Copy over links to 1.5rc2 from gh-pages 2015-08-07 20:35:41 -07:00
David Tolnay a47b32999b Fix range(value;stream) (fix #886) 2015-08-06 23:05:03 -07:00
pkoppstein d66fbd218b Clarify documentation of STRING * INTEGER 2015-08-04 21:40:16 -04:00
Nicolas Williams b5edbf7ffa OS X's mktemp -d requires template (fix #876) 2015-07-28 00:28:54 -05:00
Nicolas Williams 6b55baa00f Add missing files (fix #875) 2015-07-28 00:09:46 -05:00
Nicolas Williams 7f251344b7 Fix make dist (fix #870) 2015-07-26 23:26:30 -05:00
David Tolnay 21309bc6d7 Error on bytecodes longer than 0xFFFF (fix #269)
This lets us use uint16_t for the program counter. JVM
languages have the same limit on method size so it is a
reasonable limit.
2015-07-26 16:19:20 -07:00
David Tolnay 8295baf284 Drop plus from "jq 1.5+" on download page
See https://github.com/stedolan/jq/issues/488#issuecomment-124998113
2015-07-26 09:37:34 -07:00
David Tolnay ec84f28630 News is not THIS important 2015-07-26 01:27:14 -07:00
David Tolnay 701a47c82e Add 1.4 and 1.3 manuals to website (fix #866) 2015-07-26 01:26:13 -07:00
David Tolnay 616f365e5a Suggest --disable-maintainer-mode on download page 2015-07-25 23:44:52 -07:00
David Tolnay ceb2684f2f Update setup.sh script
Adjust what gets cleaned up now that ChangeLog and
config/.gitignore are checked into the repo, and skip
install and distcheck steps.
2015-07-24 23:26:47 -07:00
David Tolnay b9c340a211 Change homepage .com -> .io
The .com redirects to .io, but might as well have the
correct one to begin with.
2015-07-24 22:55:58 -07:00
David Tolnay 3a964e2025 Change AC bug-report parameter to point to GitHub
This affects where `make check` tells you to report failures.
2015-07-24 22:48:03 -07:00
Santiago Lapresta 3d49fc59dd Implement flatten/0 in terms of flatten/1 2015-07-24 21:55:43 -07:00
David Tolnay 16e8d0b1ab detect invalid path expression (fix #862) 2015-07-24 20:23:07 -07:00
pkoppstein 5856a2d2c0 simplify implementation of bsearch to use "until" and avoid "last"; tested 2015-07-24 12:29:20 -07:00
David Tolnay 227f62e013 Rebuild jq.1.prebuilt 2015-07-24 09:01:21 -07:00
Evan Zacks 89244cc3ea fix references to --color-output 2015-07-24 10:18:12 -04:00
Thomas R. Hall 3a43e2ff07 Updated v1.3 filenames
The jq 1.3 filenames for Windows are jq-1.3.exe instead of jq.exe. Updated these so they no longer return a 404.
2015-07-23 22:24:39 -07:00
David Tolnay 81f328f1aa Copy over changes made to gh-pages directly
This includes the following commits from the gh-pages branch:

 - 63e80b8
 - d24a397
 - 9796cd6
 - ee21707
 - ccb0f1d
 - 200e6b3
 - 64134c0
 - 57152d2
 - 8ffbfa3
2015-07-23 21:51:30 -07:00
David Tolnay f5a7bba986 Resolve remaining shift/reduce conflicts involving '?'
By lowering the precedence of rules that should never use
the generic Exp '?' rule.
2015-07-19 09:43:10 -07:00
David Tolnay 66ef8e2c24 Resolve shift/reduce conflict of 'def' vs '|'
This was an important conflict. In the following expression:

    def a: 0; . | a

Bison needs to decide between these two equally valid
parses:

    (def a: 0; .) | a
    def a: 0; (. | a)

For jq we want the second one, because the first results in
"a/0 is not defined". In the current parser the first parse
is a reduce and the second parse is a shift. Since Bison
prefers to shift in shift/reduce conflicts, we accidentally
got the correct behavior.

This commit adds a precedence level FUNCDEF which is lower
precedence than '|', meaning we explicitly choose the
correct parse.

Of course many unit tests already cover this case, but I
added one specifically for it.
2015-07-19 09:42:01 -07:00
David Tolnay 1628bbf95f Clean up trailing whitespace 2015-07-19 09:38:50 -07:00
Nicolas Williams 812703139c Use =, not ==, for shell tests 2015-07-18 21:12:08 -05:00
David Tolnay 54add5ac9a travis has whitelisted libonig-dev
https://github.com/travis-ci/travis-ci/issues/4123
2015-07-10 13:21:00 -07:00
Nicolas Williams f183b57ed5 input_filename should never empty 2015-07-10 12:32:11 -05:00
Nicolas Williams dc4dfdff17 Update AUTHORS 2015-07-10 12:28:21 -05:00
Nicolas Williams f55034d314 Update NEWS 2015-07-10 11:26:29 -05:00
Nicolas Williams 930899e12d Update ChangeLog 2015-07-10 11:12:24 -05:00
Nicolas Williams 579518c78d Use include for import into namespace 2015-07-10 10:19:33 -05:00
Nicolas Williams fa45a5121c Simplify import docs 2015-07-10 10:11:30 -05:00
Nicolas Williams 862566a48f Fix typo in docs 2015-07-10 10:10:28 -05:00
James Andariese f9f4d2d1e5 Dockerfile reorganized
* Remove excess layer creation
  This is an antipattern in Docker.
* Remove build tools once build is complete
  Leaving them around is not necessary and expands the image size 5x
* Make check works with libonig installed
* Compiles statically (needs libonig to be built rather than installed)
* Valgrind doesn't work with the use of TLS in jq so it's disabled -- this
  might be a FIXME situation; I'm not familiar enough with valgrind to
  say whether this is expected
* Make entrypoint be the jq binary so that the image can also be used
  to run jq in environments where you don't want to or can't install
  jq (such as CoreOS).
2015-07-10 07:15:44 -07:00
Mike Fletcher b74379532d Fixing missing D in LIBM_DDD_NO macro name 2015-07-09 14:59:37 -04:00
David Tolnay 1e5e0c9fe2 Make jq.h usable from C++
Previously, with clang++:
jq.h:46:37: error: typedef redefinition with different
      types ('struct jq_util_input_state *' vs 'jq_util_input_state')

With g++:
jq.h:46:37: error: conflicting declaration
      ‘typedef struct jq_util_input_state* jq_util_input_state’

This typedef was added to libjq by commit 0d41447 which was
after the 1.4 release, so although it is a public API, this
is not a backcompat break because it has never been in a
release.

Specifying the "*" at all uses of jq_util_input_state is
slightly tedious, but jq_state already works that way, so at
least it will be consistent.
2015-07-04 15:08:01 -07:00
Nicolas Williams 05899f8b3e Fix Windows build 2015-07-04 13:45:24 -05:00
Nicolas Williams a2a6f2d896 Document math support 2015-07-03 21:19:01 -05:00
Nicolas Williams 1c350c67d7 Remove pow10 for now; CHECK_MATH_FUNC needs work
The CHECK_MATH_FUNC() m4 macro needs work.  It should use
AC_RUN_IFELSE(), not just AC_LINK_IFELSE(), and it should #define
_GNU_SOURCE and/or other such feature macros in the prologue to get
non-standard math functions (alternatvely jq should only support
standard math functions).
2015-07-03 21:13:13 -05:00
David Tolnay 2348b7245e docs and diagram for exec_stack 2015-07-02 23:58:07 -07:00
David Tolnay 6e27de4f74 strftime wrong day-of-week (fix #838) 2015-07-01 20:37:16 -07:00
Nicolas Williams e5dafaea44 Document --run-tests 2015-06-28 13:57:02 -05:00
Nicolas Williams fd4f4f2087 Make --run-tests' jv_test() quiet 2015-06-28 13:39:32 -05:00
Nicolas Williams 6c89186437 Make --run-tests less verbose by default
Adding --debug-trace or --debug-dump-disasm before --run-tests now makes
it verbose.
2015-06-27 23:31:44 -05:00
Nicolas Williams 32c4759e6b Add more basic number tests 2015-06-27 23:15:16 -05:00
Nicolas Williams 6366cfd7a4 Add pow, better libm detection (fix #443) 2015-06-27 23:14:46 -05:00
David Tolnay 9985c01975 gcov exclusions 2015-06-27 14:48:13 -07:00
David Tolnay e6371712ff flag to enable gcov and coveralls 2015-06-27 11:25:01 -07:00
David Tolnay d7e35101c5 add configure option to run tests without valgrind 2015-06-27 11:24:53 -07:00
Nicolas Williams 1defaa7b00 Fix braino in merging the previous commit
There's a mantest that shows how to use `env`.  Well, we need to set the
env var as expected then, else it will fail.
2015-06-27 13:00:41 -05:00
David Tolnay 815b4c9772 get Travis CI working 2015-06-27 12:40:01 -05:00
Nicolas Williams aaf305868c Restore import into caller's namespace 2015-06-26 23:40:37 -05:00
Nicolas Williams 8cc31f0f49 Slight re-phrasing of module docs 2015-06-26 23:38:24 -05:00
Nicolas Williams a011ac6392 Use set -u in tests/setup 2015-06-26 23:36:34 -05:00
Nicolas Williams 505e23124f Fix #830 2015-06-26 21:24:01 -05:00
Nicolas Williams e7f6d1e6d0 Update Adavanced section of manual 2015-06-26 21:19:29 -05:00
Nicolas Williams a220482de6 Document {$var} 2015-06-26 21:18:58 -05:00
Nicolas Williams e16bd17571 Add {$var} . as {$var} syntax (fix #831) 2015-06-26 20:45:14 -05:00
Nicolas Williams 25d47ca08e Add streaming utilities (fix #827) 2015-06-26 20:45:06 -05:00
Nicolas Williams 5108a451ca Alternative implementation of tovalues 2015-06-26 20:17:02 -05:00
Santiago Lapresta ec7647c4ab Add combinations/0 and combinations/1 2015-06-23 10:59:58 -05:00
Nicolas Williams 8aecf82bfe WriteFile() on WIN32 when stdout isatty (fix #824)
Use WriteFile() and bypass stdio IFF stdout isatty and we're on Windows.
2015-06-22 20:47:47 -05:00
Nicolas Williams 10cbb9b580 Fix test failure introduced by previous commit 2015-06-22 18:32:28 -05:00
David Tolnay 4a316fbb5a fix errors flagged by clang static analyzer
builtin.c: bug - free of uninitialized jv
compile.c: missing assertion
jq_test.c: buggy logic / unreachable code
jv.c: missing assertion
jv_alloc.c: false positive - intentional read of uninitialized memory
jv_file.c: dead code
2015-06-20 16:08:56 -05:00
Nicolas Williams 7811ef1e17 Fix #811: use CommandLineToArgvW() and _wfopen() 2015-06-19 18:54:44 -05:00
David Tolnay b04cd6aada fix use after free in f_strptime 2015-06-19 00:34:27 -05:00
David Tolnay 1146b8b84a separate jq, oniguruma, sh, and man tests 2015-06-18 23:55:43 -05:00
Nicolas Williams 292f2d3208 argv[] may not be UTF-8 (fix #811) 2015-06-18 21:31:22 -05:00
Doug Luce 3cbefde376 Add alloca() discovery to configure.ac
The build failed on FreeBSD as there is no alloca.h.  This patch is
lifted from the autoconf documentation.
2015-06-18 19:19:15 -05:00
Nicolas Williams 0b42457929 Fix finites 2015-06-18 10:14:52 -05:00
David Tolnay 51a81c96f1 fix broken tests in manual.yml 2015-06-18 00:06:52 -05:00
Nicolas Williams 6083581fea Fix #802 2015-06-18 00:03:46 -05:00
Nicolas Williams 164b877bfa Add isnormal and related, rename *inf 2015-06-17 23:14:26 -05:00
Nicolas Williams b9c2a326ba Fix #814: raise on div-0, add inf isinf nan isnan 2015-06-17 19:58:55 -05:00
Nicolas Williams bdc1feb50e Fix infinite loop on error in sequence parser 2015-06-17 19:58:49 -05:00
Nicolas Williams 4ef04e5b5c Sequence parser: wait for RS on startup (fix #687)
Per-RFC7464.
2015-06-17 11:24:34 -05:00
Nicolas Williams 0f5345e515 Fix infinite loop on EOF bug 2015-06-17 11:23:58 -05:00
Aaron Peschel c95b4a8ab4 Add Missing Makefile Dependency
main.c requires version.h, but there is no logic marking this dependency
in the Makefile. This commit adds the dependency to the Makefile
template.
2015-06-09 19:01:20 -05:00
Nicolas Williams 520b429ca0 Clarify array destructuring docs 2015-06-09 17:29:48 -05:00
David Tolnay d3343d5113 array and object destructuring (fix #533)
`. as [$i, $j, $k] | ...`
`. as {a: $i, b: $j} | ...`
`. as [[[$i]], {a: $j}] | ...`
`foreach . as [$i, $j, $k] (...)`
`reduce . as {a: $i, b: $j} (...)`
2015-06-09 17:29:48 -05:00
cdnbacon 2e96fb2c9b Remove extension from links
The downloads are available without an extension.
2015-06-08 21:30:40 -05:00
Nicolas Williams 24a5e5b1b1 Add --tab and -indent n options 2015-06-03 20:20:11 -05:00
Nicolas Williams 74ecb88935 Improve usage message 2015-05-29 15:35:30 -05:00
Nicolas Williams 33874eb513 Fixup --slurpfile/argile docs 2015-05-29 15:25:30 -05:00
Nicolas Williams 1de56bc5df Add --slurpfile 2015-05-29 14:24:33 -05:00
Nicolas Williams 8a79f1d0a3 Better handling of stdout errors 2015-05-29 11:50:08 -05:00
Nicolas Williams f4f5d8882d Fix --argfile memleak (fix #799 part 2) 2015-05-29 11:49:45 -05:00
Nicolas Williams 4451c08007 Fix jv_load_file() (partial fix #799) 2015-05-29 11:48:10 -05:00
Nicolas Williams 89c57f7936 Revert "Fix #705 (--argfile weirdness)"
This reverts commit 3d2ab93b11.
2015-05-29 10:38:08 -05:00
Nicolas Williams 6af7857ccd Revert "Better argfile fix (#705, fix #736)"
This reverts commit 4f8567476d.
2015-05-29 10:37:58 -05:00
Nicolas Williams dff96aebcf Add jv_mem_strdup*() and callocs too 2015-05-25 21:20:37 -05:00
Nicolas Williams 8af52aaf52 Add ./configure --enable-all-static instead 2015-05-25 21:19:56 -05:00
Nicolas Williams d66e434fb4 Always add -all-static when --enable-static 2015-05-25 14:14:53 -05:00
Nicolas Williams 3700b457aa Update parser.c 2015-05-25 13:35:23 -05:00
Nicolas Williams 11f084f9a7 Keywords should be OK as object keys (fix #794)
With this change it's now OK to use keywords as object keys like so:

    {if:0}
2015-05-25 13:34:07 -05:00
Nicolas Williams 454a9dc042 Fix Windows build: util.c 2015-05-25 02:06:44 -05:00
Steven Penny ff458803ce Fix #793 2015-05-25 02:05:07 -05:00
Travis Gockel 110e009996 Add wrapping and clamping to jv_array_slice
Fix #716.  Fix #717.
2015-05-21 19:17:16 -05:00
Assaf Gordon 7b6a018dff Print offending object in runtime error messages
When reporting an error to the user, add information about the offending
object/value (possibly truncated).

The goal is to give a user some context regarding which input object
caused the runtime error.

Examples:

    $ echo '"hello"' | ./jq '-.'
    jq: error: string ("hello") cannot be negated

    $ echo '"very-long-string"' | ./jq '-.'
    jq: error: string ("very-long-...) cannot be negated

    $ echo '["1",2]' | ./jq '.|join(",")'
    jq: error: string (",") and number (2) cannot be added

    $ echo '["1","2",{"a":{"b":{"c":33}}}]' | ./jq '.|join(",")'
    jq: error: string (",") and object ({"a":{"b":{...) cannot be added

    $ echo '{"a":{"b":{"c":33}}}' | ./jq '.a | @tsv'
    jq: error: object ({"b":{"c":33}}) cannot be tsv-formatted, only array

(Fix #754)
2015-05-21 18:49:24 -05:00
Nicolas Williams a50e548cc5 Fix error message for @tsv 2015-05-21 18:20:15 -05:00
Nicolas Williams 4b258f7d31 Don't test input_filename/line_number yet 2015-05-21 17:55:27 -05:00
Assaf Gordon d1cb8ee0ad Add filename/line functions to jq (fix #753)
This adds `input_filename` and `input_line_number` built-in functions
for use in, for example, `error` messages.

Example:

    $ printf '{"a":1}\n{"a":2}\n' > 4.json
    $ printf '{"a":"hello"}\n' > 5.json
    $ ./jq '{ "file":input_filename, "line":input_line_number, "value":.a }' 4.json 5.json
    {
      "file": "4.json",
      "line": 1,
      "value": 1
    }
    {
      "file": "4.json",
      "line": 2,
      "value": 2
    }
    {
      "file": "5.json",
      "line": 1,
      "value": "hello"
    }
2015-05-21 00:49:32 -05:00
Nicolas Williams c7f063188f Fix formatting error in manual.yml 2015-05-21 00:11:21 -05:00
Assaf Gordon a6460f4fe2 Report filename:line on runtime errors (fix #752)
With this patch, jq run-time errors printed to stderr will contain the
filename and line of the offending input.

But note that the JSON text parser does (yet) print the input filename
on parse error.  A jq run-time error is a jq program error, not
including syntax errors nor JSON text input format errors.

Examples:

With stdin and multiple lines:

    $ printf '{"a":43}\n{"a":{"b":66}}\n' | ./jq '.a+1'
    44
    jq: error (at stdin:2): object and number cannot be added

With multiple files:

    $ printf '{"a":43}' > 1.json
    $ printf '{"a":"hello"}\n' > 2.json
    $ printf '{"a":{"b":66}}\n' > 3.json
    $ ./jq '[.a]|@tsv' 1.json 2.json 3.json
    "43"
    "hello"
    jq: error (at 3.json:1): object is not valid in a csv row

With very long lines (spanning multiple `fgets` calls):

    $ (  printf '{"a":43}\n' ;
         printf '{"a":{"b":[' ; seq 10000 | paste -d, -s | tr -d '\n' ;
         printf ']}}\n' ;
         printf '{"a":"hello"}\n' ) | ./jq '[.a] | @tsv'
    "43"
    jq: error (at stdin:2): object is not valid in a csv row
    "hello"

With raw input:

    $ seq 1000 | ./jq --raw-input 'select(.=="700") | . + 10'
    jq: error (at stdin:700): string and number cannot be added

Caveat:
The reported line will be the last line of the (valid) parsed JSON data.
Example:

    $ printf '{\n"a":\n"hello"\n\n\n}\n' | ./jq '.a+4'
    jq: error (at stdin:6): string and number cannot be added
2015-05-20 23:38:22 -05:00
Nicolas Williams 2e257563a6 Fix spelling 2015-05-20 10:21:30 -05:00
Nicolas Williams ad0090964b Document gsub/3 2015-05-19 01:19:51 -05:00
Nicolas Williams cbdaeb4062 Fix gsub, add gsub/3 (fix #782) 2015-05-18 23:02:11 -05:00
Nicolas Williams cf1306f469 Add -all-static when --enable-static 2015-05-18 12:07:29 -05:00
Nicolas Williams 7675f7434a Fix --stream assertion 2015-05-11 21:36:47 -05:00
Nicolas Williams 821d6404b6 Add error injection library 2015-05-11 21:36:46 -05:00
Nicolas Williams e3cb1f76cd Report read errors too (and fix #772) 2015-05-11 21:36:26 -05:00
Nicolas Williams ef12efbf8c Fix README 2015-05-02 17:36:37 -05:00
Nicolas Williams adb9b9b8a7 README: send questions to SO and Freenode 2015-05-02 17:34:59 -05:00
Nicolas Williams 07f94f82a2 usage() should check fprintf() result (fix #771) 2015-04-28 10:39:34 -05:00
Nicolas Williams 215b4c0fe1 Use jv_mem_alloc() in compile.c (fix #771) 2015-04-28 10:37:37 -05:00
Nicolas Williams 89963e1370 Fix header guards (fix #770) 2015-04-28 10:36:21 -05:00
Nicolas Williams 5d40f3a7c0 --raw-input wrongly adds NULs (fix #761) 2015-04-24 10:42:19 -05:00
Nicolas Williams 5e0e7a7ebd With inputs builtin, -n and -R can now coexist 2015-04-23 23:43:44 -05:00
Nicolas Williams dad6e42934 --raw-input ought to read NULs (partial fix #760)
We can't know how many bytes fgets() read when we reach EOF and fgets()
didn't see a newline; we can only assume that at least strlen(buf) bytes
were read.  This is quite obnoxious if one wants to use NULs in raw
input, but at least we can make reading "a\0b\0c\0" with no newline
yield "a\0b\0c", losing only the final sequence of NULs.

We can't use getline() either, since it will want to allocate a buffer
big enough for an entire line, and we might not have any newlines in our
input.  A complete fix will have to use getc() or read(), preferably the
latter.
2015-04-23 23:43:44 -05:00
Nicolas Williams 7d938487dd --slurp --raw-input is broken (fix #761) 2015-04-23 18:26:57 -05:00
Nicolas Williams fcfacb932d from_entries is broken (fix #767) 2015-04-23 18:25:32 -05:00
Assaf Gordon 6906d291c5 regex functions: report informative error if not available.
When trying to use the new regex functions (match/test/sub/capture/etc)
in a JQ that was compiled without the ONIGURAMA regex library,
report an informative error message instead of a 'not defined' error.

Before:

    $ echo '"foo"' | ./jq-old 'test("foo")'
    jq: error: test/1 is not defined at <top-level>, line 1:
    test("foo")
    jq: 1 compile error

After:

    $ echo '"foo"' | ./jq 'test("foo")'
    jq: error: jq was compiled without ONIGURAMA regex libary. match/test/sub and related functions are not available.
2015-04-22 16:57:03 -05:00
Andrew O'Brien 943090846f Fixes manual generation with psych
When running `make` I ran into a couple of problems building the manual. While
I'm not entirely sure that this is the root cause, it appears to have been
related to the fact that ruby 2.0 dropped syck completely in favor of psych
(which was introduced in 1.9.2) for YAML processing. I'm currently using ruby
2.1.0p0.

I'm assuming that the fact that the YAML engine was explicitly set to syck in
the Rakefile was an attempt to work around some incompatibility between the two
libraries, so I looked into what would be necessary to get it to work with the
newer one. The changes to `manual.yml` ended up being pretty minor: I ran it
through `iconv` to convert some ISO-8859-1 characters to UTF-8 and added some
quotes in places (apparently you can't start a string value with '`').
2015-04-22 11:01:39 -05:00
Assaf Gordon 2dc8621d05 Handle NUL in escaped-string output
When escaping string (e.g. for `@tsv` or `@csv` outputs),
escape NULs as '\0'.

Existing behaviour, unchanged by this patch:

    $ echo '"a\u0000b"' | ./jq '.'
    "a\u0000b"
    $ echo '"a\u0000b"' | ./jq -r '.' | od -a
    0000000   a nul   b  nl
    0000004

When using `@tsv`, escape NUL to `\0`:

    $ echo '"a\u0000b"' | ./jq -r '[.]|@tsv'
    a\0b
    $ echo '"a\u0000b"' | ./jq '[.]|@tsv'
    "a\\0b"
2015-04-20 16:51:48 -04:00
tal@whatexit.org b6cc00fa71 manual.yml: Clarify how to specify keys with ":" and special chars.
Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2015-04-16 11:09:49 -05:00
Assaf Gordon 9e2d9b6419 docs: expand @tsv section - add escape sequences. 2015-04-15 23:24:24 -04:00
Assaf Gordon 3210b29bba @tsv: escape \r, \n, \\
When using '@tsv' output format with '-r' option,
escape \r, \n and \\ in addition to \t.

Example:
    $ printf '{"id":"hello\\ttab\\nworld","x":43 }' | jq .
    {
      "id": "hello\ttab\nworld",
      "x": 43
    }

Before: newlines are not escaped, generating invalid TSV output:

    $ printf '{"id":"hello\\ttab\\nworld","x":43 }' \
        | ./jq-old -r '[.id,.x] | @tsv'
    hello\ttab
    world	43

After: newlines are properly escaped:

    $ printf '{"id":"hello\\ttab\\nworld","x":43 }' \
        | ./jq-new -r '[.id, .x] | @tsv'
    hello\ttab\nworld	43

Before: backslashes themselves are not escaped, so there's no way to
distinguish between escaped characters and 'real' backslashes
(in the example below, there is should not be newline, despite the
output containing "\n".

    $ printf '{"x":"hello\\ttab\\\\new world"}' \
        | ./jq-old -r '[.x]|@tsv'
    hello\ttab\new world

After: backslashes are escaped:

    $ printf '{"x":"hello\\ttab\\\\new world"}' \
        | ./jq-new -r '[.x]|@tsv'
    hello\ttab\\new world
2015-04-15 16:11:58 -04:00
Nicolas Williams ddad9618dc Test fix for mktime 2015-03-31 10:03:35 -05:00
Nicolas Williams 24005287f4 Add $__loc__ (fix #740) 2015-03-30 22:36:04 -05:00
Nicolas Williams 1dcfc2f547 Include filename and lineno in error messages 2015-03-30 15:56:29 -05:00
Nicolas Williams 7d6d4066dd Tweak fix for #719 2015-03-24 15:05:06 -05:00
Assaf Gordon 4c22bda09b detect and report output writing errors
Detect output errors when the program exits.

Currently:
    $ echo '{}' | jq . > /dev/full && echo ok
    ok

with the patch:
    $ echo '{}' | jq . > /dev/full && echo ok
    Error: writing output failed: No space left on device

also apply to hardware/network/other I/O errors.

Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2015-03-24 15:01:32 -05:00
Santiago Lapresta 9d62c6fd0c Adds Dockerfile
Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2015-03-24 14:59:29 -05:00
Assaf Gordon 5e0db6dd65 partial handling of input errors
Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2015-03-24 14:56:46 -05:00
Assaf Gordon 551d875be1 always propagate input errors to exit code
Improve robustness in automated system when using exit code in shell scripts,
by exiting with code 2 if there was any input error (even overriding other
possible error exit codes).
Exit code 2 is already used to indicate system errors.

Without the patch:
   $ jq . no-such-file ; echo $?
   jq: no-such-file: No such file or directory
   0

With the patch:
   $ jq . no-such-file ; echo $?
   jq: no-such-file: No such file or directory
   2

Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2015-03-24 14:55:14 -05:00
Nicolas Williams 4f8567476d Better argfile fix (#705, fix #736) 2015-03-24 14:53:35 -05:00
Nicolas Williams ffa2832e33 Drop name-less label/break for now
See #734 and #658.
2015-03-24 01:21:17 -05:00
William Langford 0f7759f831 Fix #735 2015-03-23 22:11:55 -04:00
Nicolas Williams ccfba00178 Add more date builtins 2015-03-09 11:27:58 -05:00
Nico Williams 3e8183fcd5 Merge pull request #720 from agordon/exit-code-5-exceptions
exit with non-zero code on runtime exceptions
2015-03-08 17:09:07 -05:00
Nicolas Williams 0df387f6b5 Automake: jq depends on version.h (fix #721) 2015-03-08 16:52:08 -05:00
Assaf Gordon 4104c4fa1c exit with non-zero code on runtime exceptions
With this change, runtime exceptions are propagated to non-zero exit
code of 'jq', allow better scripting and automation. The new exit code
value is 5.

This allows using the shell's and/or operations ('&&' and '||') to
detect input runtime exceptions.

Before:
runtime exceptions are printed to STDERR, but not reported as non-zero exit-code:
    $ echo '"hello"' | jq '.|tonumber' ; echo $?
    jq: error: Invalid numeric literal at EOF at line 1, column 5 (while parsing 'hello')
    0

After:
    $ echo '"hello"' | ./jq '.|tonumber' ;  echo $?
    jq: error: Invalid numeric literal at EOF at line 1, column 5 (while parsing 'hello')
    5

Note that there's a subtle interplay when using "-e" option.
The value of the non-zero exit code changes from 4 to 5, but it still
indicates a 'failure' or non-true value.

Before:
    $ echo '"hello"' | jq -e '.|tonumber' ;  echo $?
    jq: error: Invalid numeric literal at EOF at line 1, column 5 (while parsing 'hello')
    4

After:
    $ echo '"hello"' | ./jq -e '.|tonumber' ;  echo $?
    jq: error: Invalid numeric literal at EOF at line 1, column 5 (while parsing 'hello')
    5
2015-03-06 18:50:58 -05:00
Nicolas Williams 33a85679b9 Fix #718 2015-03-06 00:18:45 -06:00
Nicolas Williams a4b9552c82 Add date builtins (fix #364)
Windows support for strptime() is missing.  We can add a copy of one
from a BSD later.
2015-03-06 00:14:15 -06:00
Nicolas Williams b82c231900 Remove -i option (#704)
In-place editing should be implemented with builtins for file I/O.
2015-03-05 21:52:02 -06:00
Nicolas Williams 3d2ab93b11 Fix #705 (--argfile weirdness) 2015-02-18 18:38:11 -06:00
Nicolas Williams c86ef36769 Test in-place functionality; fix #704 2015-02-18 18:01:12 -06:00
Nicolas Williams 3b8d08177f Fix #702 2015-02-18 10:21:21 -06:00
Nico Williams 0164ff0bbc Merge pull request #701 from sseemayer/master
Correct automake and autoconf version requirements
2015-02-18 10:00:23 -06:00
Stefan Seemayer a4baac2256 Correct automake and autoconf version requirements 2015-02-18 13:15:44 +01:00
Nicolas Williams 1e5e9f3ef8 Mention --disable-maintainer-mode in bison error 2015-02-17 11:00:07 -06:00
Nico Williams d58d85af9e Merge pull request #699 from hroptatyr/oniguruma-detection
Fix oniguruma detection logic
2015-02-16 10:54:33 -06:00
Sebastian Freundt 10e8d34fd3 Fix oniguruma detection logic
At the moment, a failed oniguruma header check would leave
HAVE_ONIGURUMA set to 1 still, resulting in a compiler error
in builtin.c.
2015-02-16 09:01:08 +00:00
Nicolas Williams ebc090ad15 README tweaks 2015-02-15 18:34:44 -06:00
Nicolas Williams 8cef5a37ab Add --disable-maintainer-mode; make bison optional
Also flex is now optional.

The outputs of flex and bison are now committed.  By default they get
built, but users who want to build from git can now

    ./configure --disable-maintainer-mode

to turn off the dependency on bison and flex.

Maintainers must, of course, commit the bison and/or flex outputs when
they make changes to parser.y and/or lexer.l, respectively.
2015-02-15 18:34:44 -06:00
Nicolas Williams 8afdeee785 Make Oniguruma/regexp optional
Tests won't pass if built without Oniguruma.  We don't have a way to
make a test optional yet.  That will come later.  For now the ability to
reduce build-time dependencies could really help some users.
2015-02-15 18:32:01 -06:00
Nicolas Williams a83a9e0bc2 Reduce number of msg callback typedefs 2015-02-13 15:58:02 -06:00
Nicolas Williams 0d414471bb Refactor moar: move parts of main.c into libjq
This adds utility functions for reading and parsing files that should be
easy to use by other apps, together with jq_start()/jq_next().
2015-02-13 15:58:02 -06:00
Nicolas Williams 91fb3df495 Refactor handling of inputs in main() (fix #667)
Much of this could be in libjq.  Eventually all of the work of reading
from files and looping over `jq_next()` should move into libjq, with
`main()` mostly doing all the command-line option processing.
2015-02-13 15:55:31 -06:00
Nico Williams 373ef71feb Merge pull request #692 from kim-toms/enhance-from_entries
Enhance from_entries to better deal with Amazon AWS Tags
2015-02-10 10:49:35 -06:00
Kim Toms ca78a746e6 Enhance from_entries to better deal with Amazon AWS Tags 2015-02-10 08:33:56 -05:00
Nicolas Williams 1e13e1e06e Fix sequence warnings (fix #686) 2015-01-30 17:21:50 -06:00
Nicolas Williams 42ff8a6959 Usage message for -h should go to stdout 2015-01-30 10:27:46 -06:00
William Langford 2e92c3e568 Merge pull request #678 from isomorphisms/patch-1
readability
2015-01-27 14:15:07 -05:00
i 5389fdb651 readability
Easier to read dashes than hyphens imho.
2015-01-27 13:32:15 -05:00
Nicolas Williams 7a295b30e0 Fix --raw-input 2015-01-20 00:22:24 -06:00
Nico Williams cca3e92854 Merge pull request #669 from joelpurra/join-empty-array-668
Empty arrays join/1 to an empty string, fixes #668 bug introduced by 9760245
2015-01-14 15:50:15 -06:00
Joel Purra 4d05dc55a3 Empty arrays join/1 to an empty string, fixes #668 bug introduced by 9760245 2015-01-14 12:27:55 +01:00
Nicolas Williams aeb52e29d6 Add debug and stderr builtins
And refactor setup of jv dump flags.
2015-01-14 01:39:13 -06:00
Nicolas Williams 97602456e3 join/1: respect empty strings (fix #668) 2015-01-14 01:32:25 -06:00
Nicolas Williams 8b5ff40402 Split on empty sep: fix #552 moar 2015-01-14 01:32:11 -06:00
Nicolas Williams d630597e87 Fix docs for split/0 2015-01-12 10:47:43 -06:00
Nicolas Williams 60d1ecb58a Fix #552 2015-01-12 10:44:44 -06:00
Nicolas Williams d927a2c185 Fix --run-tests arg handling 2015-01-12 10:43:06 -06:00
Nicolas Williams 6e7cf81d74 Look for jq/main.jq for imports 2015-01-02 19:16:43 -06:00
Nicolas Williams 736f1751ee Add comments to tests/run 2015-01-02 19:15:57 -06:00
Nicolas Williams 28aab9ca79 Fix tests/run in from-tar-ball case
Drop useless use of scripts/version
2015-01-02 19:15:11 -06:00
Nicolas Williams 972c048149 Add static build instructions (fix #294) 2015-01-01 16:26:55 -06:00
Nicolas Williams 902aa39fce Fix warning in util.c 2015-01-01 15:15:10 -06:00
Nicolas Williams 22f55aa585 Include missing EXTRA_DIST items; fix #661 2015-01-01 15:14:49 -06:00
Nicolas Williams 157c95b988 Add mkstemp() for mingw build 2015-01-01 03:14:55 -06:00
Nicolas Williams 426913f127 Fix memleak introduced run-tests enhancement 2015-01-01 02:12:08 -06:00
Nicolas Williams c4cc62a053 Add more missing test files 2015-01-01 01:49:40 -06:00
Nicolas Williams 862696a778 Add missing test file 2015-01-01 01:39:50 -06:00
Nicolas Williams 86bc662bd2 Move some module tests into all.test 2014-12-31 20:09:53 -06:00
Nicolas Williams ae7f8d6ab9 Further module system revamp (fix #659)
To import a module now use:

    # Import module.jq file:
    import "relative/path/to/module" as foo;

    # Use the module's defs as foo::<def-name>

To import a JSON file:

    # Read file.json:
    import "relative/path/to/file" as $foo;
    #
    # Use as $foo::foo

Using `-L` now drops the builtin library path and appends the requested
path to the empty array (or the result of an earlier `-L`).

Support for the `$JQ_LIBRARY_PATH` environment variable has been
removed.
2014-12-31 20:09:53 -06:00
Nicolas Williams 7dc34b92af Add label $name | EXP; fix break
This is to fix the problem where `break` is dynamic, not lexical.

With this it should be possible to do this sort of thing:

    label $break | inputs | if ... then $break|error else . end

This is a backwards-incompatible change for master, but the previous
`break` hadn't shipped yet.

Still needed:

 - testing
2014-12-30 11:42:45 -06:00
Nicolas Williams cbfc0d6130 Remove string indexing by string (fix #454)
This turns out to have been a bad idea:

    "foo"|.["o"]

it interacts badly with `path()`.

See #454 for the gory details.
2014-12-30 11:31:52 -06:00
Nicolas Williams c308b2881f Fix parser leak (fuzzing) 2014-12-30 11:31:52 -06:00
Nicolas Williams c959d1fca1 Fix lineno counting in jq_test.c 2014-12-30 11:28:50 -06:00
Nicolas Williams 63511a874f Add support for testing erroneous programs
This will allow moving tests of some tests from tests/run to
tests/all.test.  It will also be useful for more extensive testing of
language features where we want nice error messages, or errors at all,
to be produced, particularly language features where the errors arise at
compile-, codegen-, or link-time rather than parse-time.

This does not check for run-time errors though -- those we can already
check for with try/catch.

    $ jq --run-tests
    %%FAIL
    break
    jq: error: break used outside labeled control structure
    ^D
    1 of 1 tests passed (0 malformed)
    $
2014-12-30 10:55:30 -06:00
Nicolas Williams 90c705f138 Make --run-tests more informative
Print the line number and program text on the same output line where a
failure is reported, for all failures that were already reported on
lines starting with '***'.  This makes poring over test logs with
failures much easier.
2014-12-30 10:55:30 -06:00
Nicolas Williams b67bad82cb Allow resetting of jq err callback
This will be useful for the upcoming test-erroneous-programs improvement
to --run-tests, so we can switch between the default error reporting
method (print to stderr) to a method internal to --run-tests, and back.

The idea is that when testing programs that are expected to compile (and
link), it'd be nice if errors continue going to stderr, while when
testing programs that must fail to compile (or link), the error has to
be captured so it can be compared to the error expected by the test.
2014-12-30 10:52:38 -06:00
Nicolas Williams 6981b46338 Fix streaming bug (fuzzing) 2014-12-30 01:35:22 -06:00
pkoppstein 752e00bc66 transpose/0 for possibly jagged matrices 2014-12-27 18:52:36 -06:00
pkoppstein 00f018a054 bsearch(x) (binary search): builtin.c (tested), with documentation and test case. Always yields an integer (even if input is unsorted); returns (-1 - ix) if x is not in input array. 2014-12-27 18:44:20 -06:00
pkoppstein 56344670f4 ascii_upcase/0 and ascii_downcase/0 2014-12-27 18:38:52 -06:00
Nicolas Williams 5df20f4954 Add debug builtin
And refactor setup of jv dump flags.
2014-12-27 18:25:34 -06:00
Nicolas Williams a9c613e87d Don't force C API users to set input cb 2014-12-27 18:15:10 -06:00
Nicolas Williams 7538ef34be Make jq --run-tests show test line numbers 2014-12-27 18:15:10 -06:00
Nicolas Williams 5c62a4b805 Fix uninitialized struct field 2014-12-27 18:09:28 -06:00
Nicolas Williams 559863ca68 Streaming parser torture tests 2014-12-26 23:18:07 -06:00
Nicolas Williams 845ad5e969 Fuzz JSON parser 2014-12-26 23:05:57 -06:00
Nicolas Williams 243b1f8e5e Better quoting in tests/run 2014-12-26 23:05:56 -06:00
Nicolas Williams 5bfb9781f7 Add Streaming parser (--stream)
Streaming means that outputs are produced as soon as possible.  With the
`foreach` syntax one can write programs which reduce portions of the
streaming parse of a large input (reduce into proper JSON values, for
example), and discard the rest, processing incrementally.

This:

    $ jq -c --stream .

should produce the same output as this:

    $ jq -c '. as $dot | path(..) as $p | $dot | getpath($p) | [$p,.]'

The output of `jq --stream .` should be a sequence of`[[<path>],<leaf>]`
and `[[<path>]]` values.  The latter indicate that the array/object at
that path ended.

Scalars and empty arrays and objects are leaf values for this purpose.

For example, a truncated input produces a path as soon as possible, then
later the error:

    $ printf '[0,\n'|./jq -c --stream .
    [[0],0]
    parse error: Unfinished JSON term at EOF at line 3, column 0
    $
2014-12-26 23:05:56 -06:00
Nicolas Williams 906d2537b9 Allow C-coded functions to empty
Just return a jv_invalid() without a message.
2014-12-26 23:05:56 -06:00
Nicolas Williams bbb287f54b Add BLOCK_8() macro 2014-12-26 23:05:56 -06:00
Nicolas Williams e51e916e31 Fix foreach non-progation of errors
Errors were being re-propagated as "break".

Also add `error/0` builtin, which made this fix easier.
2014-12-26 23:05:20 -06:00
Nicolas Williams 46e3125e26 Allow zero-length buffers in jv_parser_set_buf()
If the caller is at EOF and has no more bytes to feed the parser, how is
the parser to be told about the EOF condition?  A small fix to allow
zero-length buffers in jv_parser_set_buf() fixes this problem (it also
makes it easier to deal with async I/O: feed the parser whatever is
available, including nothing).
2014-12-26 22:56:48 -06:00
Nicolas Williams c02fcc8fef Fix in and inside 2014-12-26 22:56:48 -06:00
Nico Williams 25d4cbd1b3 Merge pull request #624 from Janrain-Colin/patch-1
Doc correction
2014-12-26 22:14:17 -06:00
Nico Williams 3234a7681e Merge pull request #366 from slapresta/inversed-contains
Added `in` command
2014-12-26 22:00:41 -06:00
Nico Williams 36077da66a Merge pull request #628 from slapresta/map-on-objects
Modify map\1 so that it works on objects
2014-12-26 21:50:11 -06:00
Nicolas Williams 9e1fd8cf4d Fix infinite loop in read_more() (fix #656) 2014-12-24 16:49:55 -06:00
Nicolas Williams a55085b662 Fix EOF handling; fix #656 2014-12-24 16:07:36 -06:00
Nico Williams e0f9b6a5cd Merge pull request #651 from eiiches/fix-examples
Fix several errors in the manual
2014-12-24 11:29:29 -06:00
Nicolas Williams 0053aa868c Add @tsv; fix #645 2014-12-24 11:21:18 -06:00
Nico Williams fab2048648 Merge pull request #653 from msabramo/patch-1
.travis.yml: Set sudo false; use containers
2014-12-24 11:20:47 -06:00
Nicolas Williams 56ae88d9d5 Module search revamp for pkg managers
The search path listed in an import directive can now be an array.  The
top-level search path is appended.  Null and empty strings in the path
terminate any search.  The "." in "." and "./*" is replaced with the
directory containing the file doing the import (for command-line
programs this is the current directory, though that may be a bad idea).

No version numbers or anything of the sort are gratuitously added to the
search paths.

All this makes external package managers possible by allowing
dependencies to be installed local to dependents.
2014-12-24 02:31:51 -06:00
Nicolas Williams 1cdcff1c01 Fix bug caused by 8ca07a0 2014-12-24 02:25:11 -06:00
Nicolas Williams 8ca07a08c3 Fix #348: reject unescaped control chars 2014-12-24 00:01:43 -06:00
Nico Williams 2775b90b20 Merge pull request #601 from slapresta/redefine-any-all
Define {any,all}/0,1 in terms of {any,all}/2
2014-12-23 23:37:25 -06:00
Nicolas Williams ae312bd7fe Use __attribute__ __printf__ with GCC 2014-12-23 23:22:57 -06:00
Nicolas Williams 9017b83d4e Make values faster (fix #652) 2014-12-23 23:22:57 -06:00
Nicolas Williams 02cf1831e9 Fix #649 2014-12-23 18:16:21 -06:00
Marc Abramowitz d237de7b30 .travis.yml: Set sudo false; use containers
This is the way to enable Travis's fancy new containers, which should result in faster builds.
2014-12-22 21:37:23 -08:00
Santiago Lapresta 84d3203dd1 Define map_values 2014-12-22 23:05:35 +01:00
Santiago Lapresta a3234034b5 in is now inside, added in as inverse of has 2014-12-22 22:17:53 +01:00
Santiago Lapresta b748eae035 Added in command 2014-12-22 22:14:06 +01:00
Eiichi Sato a6656edc7c Fix examples in manual 2014-12-21 03:26:04 +09:00
Eiichi Sato b4a9ea56ae Fix indents in manual.yml 2014-12-21 03:24:45 +09:00
Eiichi Sato fdbc91e3c4 HTML-escape jq programs in manual 2014-12-21 03:24:41 +09:00
Eiichi Sato bd67bb8273 Fix examples in manual 2014-12-21 03:24:38 +09:00
Nico Williams 54a0470c42 Merge pull request #611 from StevenMaude/tutorial-typo-fixes
Fix typos in tutorial
2014-12-12 17:46:17 -06:00
Nico Williams 3dd790c408 Merge pull request #616 from ianmiell/ianmiell_requirements
Requirements made slightly more complete
2014-12-12 17:45:17 -06:00
Nicolas Williams be11b2768f Add until(cond; next); fix #639 2014-12-12 17:35:59 -06:00
Nicolas Williams 2075bec60f Fix #647, but caused by 89791a0 2014-12-12 17:05:16 -06:00
Nicolas Williams 44c2382402 Add --argjson, fix #648 2014-12-12 16:40:07 -06:00
Nico Williams fd041c2064 Merge pull request #642 from Janrain-Colin/patch-3
fix typo in manual
2014-12-12 16:03:18 -06:00
Colin von Heuring c6495f6632 fix typo in manual 2014-12-06 16:27:43 -08:00
Nicolas Williams 7243989c52 Fix refcount leak, fix #618 2014-11-29 15:24:43 -06:00
Nicolas Williams 46613af64c STOREV/LOADV* should also print refcnts 2014-11-28 20:52:22 -06:00
Nicolas Williams 79000644c6 Enable printing of stack val refcnts 2014-11-28 19:35:29 -06:00
Nicolas Williams b349e7d9a8 Print stack value refcounts when tracing (#636) 2014-11-28 19:26:41 -06:00
Colin von Heuring 6c8882caf3 Doc correction 2014-11-23 11:37:50 -08:00
William Langford 30e00820a7 Fix #600. Add regression test 2014-11-12 20:46:34 -05:00
Ian Miell 0f81e1bcd0 Requirements made slightly more complete: cf https://github.com/ianmiell/shutit/blob/master/library/jq/jq.py 2014-11-11 23:02:31 +00:00
Steven Maude cb376b27f8 Fix typos in tutorial
parrent > parent, url > URL
2014-11-05 10:47:37 +00:00
Santiago Lapresta dc5e77ef8e Define {any,all}/2 independently from {any,all}/0 2014-10-21 13:00:38 +02:00
Santiago Lapresta 72735167f9 Define {any,all}/{0,1} in terms of {any,all}/2 2014-10-20 22:01:25 +02:00
Nicolas Williams 89791a000b Add support for JSON sequence MIME type
Per draft-ietf-json-text-sequence-07 (which soon will be published as an
RFC).
2014-10-12 08:44:40 -05:00
William Langford 3411167c03 Properly call onig_error_code_to_str
Fix #585
2014-10-06 21:48:56 -04:00
pkoppstein 85f0e30c81 fix sub (#586); add gsub/3; add transpose/0.
Signed-off-by: William Langford <wlangfor@gmail.com>
2014-10-06 21:32:07 -04:00
Nicolas Williams 1796a716ea Restore split/1; don't use regexp (fix #576) 2014-10-03 17:58:45 -05:00
Nicolas Williams 07d8d5c5ef Update docs about sort/group/min/max/unique 2014-10-03 17:58:44 -05:00
Nicolas Williams 0b29b44cab from-entries should work with EC2 (fix #592) 2014-10-03 17:47:13 -05:00
Nicolas Williams a0a350f468 Remove sort/1 and group/1
Reserve these for sorting with jq-coded comparators.
2014-10-03 17:47:13 -05:00
Nicolas Williams 4a57b84db0 to_entries should not sort keys (fix #561) 2014-09-30 21:52:30 -05:00
William Langford f7a2af7052 Properly handle when objects cannot be folded
Fix #579.
2014-09-22 20:14:46 -04:00
Nicolas Williams 456bafa82f Drop the jq version directory from search path 2014-08-30 00:58:24 -05:00
Nicolas Williams 7a8e3c759e Never close stdin; allow multiple - arguments 2014-08-30 00:40:03 -05:00
Nicolas Williams b70bea8d34 Handle invalid inputs in argument files (fix #562) 2014-08-30 00:40:03 -05:00
William Langford d177944b75 Properly handle incomplete json when input is file
Fix #562
2014-08-28 21:52:45 -04:00
Nicolas Williams 9bd55487ea C-coded builtins should not assert (fix #553) 2014-08-21 00:12:29 -05:00
Nicolas Williams 23e2e2eab3 Quiet warning about freopen() of stdout 2014-08-20 20:49:30 -05:00
Nicolas Williams 8d2d5e37e5 Drop "any/" in module search; use 1.x-master 2014-08-20 20:48:48 -05:00
Nicolas Williams 287e2c96ed BSD sed lacks -r; fix #551 2014-08-14 03:31:25 -05:00
Nicolas Williams f8d9478517 Document module system
Fix #511.
2014-08-14 03:26:28 -05:00
Nicolas Williams 1ba8c2cfa6 Add module directive, modulemeta builtin
Fix #425.
2014-08-14 03:26:26 -05:00
Nicolas Williams d654724fef Add JV_OBJECT() macro 2014-08-14 03:21:38 -05:00
Nicolas Williams 3375089013 Add JV_ARRAY() macro 2014-08-14 03:21:38 -05:00
Nicolas Williams 9f13afa20f Add jq_report_error() function; use it
Put a stop to fprintf(stderr, ...) where we shouldn't.
2014-08-14 03:21:35 -05:00
Nicolas Williams 908c10928b Fix #549 2014-08-11 14:58:44 -05:00
Nicolas Williams c321c3b86b Constant fold objects 2014-08-09 20:47:03 -05:00
Nicolas Williams f87521183f Fold constant arrays 2014-08-09 20:27:08 -05:00
Nicolas Williams 8a561120c4 More constant folding: null, true, and false
A step towards doing constant folding for arrays and objects.
2014-08-09 19:15:50 -05:00
Nicolas Williams 20ca21cb0d Out of bounds negative array indices should raise 2014-08-09 19:15:50 -05:00
Nicolas Williams 2d1a75f550 .foo[-1] = ... trips assertion (fix #490) 2014-08-09 13:10:41 -05:00
Nicolas Williams 8cddb7c681 Allow any number of jq-coded function arguments 2014-08-09 12:42:39 -05:00
Nicolas Williams 4249bbf0d5 Make nwise private 2014-08-08 19:36:43 -05:00
Nicolas Williams 8a57c27e92 Make regexp builtins and range/3 use #524 too 2014-08-08 19:31:11 -05:00
Nicolas Williams 8706b6b16a Use def f($a): ...; syntax for builtins 2014-08-08 19:23:46 -05:00
Nicolas Williams 32c08d48f3 Add def f($arg): syntax (fix #524) 2014-08-08 19:16:01 -05:00
Nicolas Williams fc52e78ed4 Fix tests for #432 2014-08-08 18:17:58 -05:00
Nicolas Williams eb12f0358e Fix docs YAML (introduced in #432) 2014-08-08 18:01:42 -05:00
pkoppstein a696c6b551 regex filters (#432): scan, splits, split, sub, gsub 2014-08-08 17:00:14 -05:00
Nicolas Williams 0d437e25de Better error msg for bad shell quoting (fix #538) 2014-08-06 17:51:53 -05:00
William Langford 6744664ff4 Actually check version for bison.
Clean up oniguruma checks.
2014-08-06 12:26:34 -04:00
William Langford ef5bd5a6de Merge pull request #532 from wtlangford/top-removal
Remove duplicate TOP insertions, drop unused defs.
2014-08-05 13:41:59 -04:00
Nicolas Williams 2159f9f5e0 Document TCO a bit more 2014-08-05 01:15:33 -05:00
Nicolas Williams 2518b3a34f Fix docs (missing backquotes) 2014-08-05 01:15:33 -05:00
William Langford c3d6d5fd37 Merge pull request #523 from eproxus/patch-1
Add example of selecting object with keys
2014-08-05 00:50:21 -04:00
William Langford a25950a58c Remove duplicate TOP insertions, drop unused defs. 2014-08-05 00:46:10 -04:00
pkoppstein f8fed0f0bc Apply TCO to recurse/1, add recurse/2; tweak docs
Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2014-08-04 21:11:01 -05:00
Adam Lindberg 89545ea9d0 Add example of selecting object with keys
It is not very straight forward how to select objects by their attributes from an array. This example provides the basic use case of how to select some objects based key values.
2014-08-01 12:13:35 +02:00
Nicolas Williams a2f99d43c3 Some builtins are unnecessarily special (fix #521) 2014-08-01 00:20:30 -05:00
Nicolas Williams a7878a8d1a Correct @wtlangford's address 2014-07-30 13:19:46 -05:00
Nicolas Williams c73ad74be0 Add @wtlangford to the AUTHORS list 2014-07-30 13:02:34 -05:00
pkoppstein 53993a9942 Add capture; document regular expression filters
Fix #493.
2014-07-28 19:41:21 -05:00
Nicolas Williams e1b20b48f0 Add first, nth, last (fix #510) 2014-07-28 13:18:58 -05:00
William Langford 14bc1f6526 Fixing crash when a library's dependency could not be loaded.
Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2014-07-27 17:51:48 -05:00
Nicolas Williams 2e2538ccb8 Fold constants (fix #504) 2014-07-27 17:48:49 -05:00
Nicolas Williams ae27178352 Fix #499, #500 2014-07-27 17:41:40 -05:00
William Langford 0f89270d08 Changing color codes to fix #495 2014-07-22 23:05:43 -05:00
Nicolas Williams 10f5a3448d Do fix remaining bison warning (fix #433) 2014-07-22 22:51:11 -05:00
Nicolas Williams 50b85c2911 Rename jq_memmem() to _jq_memmem() 2014-07-22 22:51:11 -05:00
William Langford 38b939688a Added library system with -l, -L, and JQ_LIBRARY_PATH
Created util.[ch] to hold common utilities.
2014-07-22 22:51:11 -05:00
Nicolas Williams 01fc8168e9 Add -i option to edit files in place (fix #105) 2014-07-20 00:11:23 -05:00
Nicolas Williams 3362fb3406 Add -n to short usage msg; fix --arg msg 2014-07-20 00:04:24 -05:00
Nicolas Williams 8c3d503d54 Fix bison empty rule warnings (#433, partial fix) 2014-07-14 16:41:48 -05:00
Nicolas Williams 2bb9fc5dda Fix #484, try/catch syntax has conflicts 2014-07-14 16:41:48 -05:00
Nico Williams ea3e947b50 Merge pull request #483 from else/master
jq 1.4 is in Debian
2014-07-14 09:16:01 -05:00
Simon Elsbrock 538e012e85 jq 1.4 is in Debian
jq 1.4 is in Debian, please see https://tracker.debian.org/pkg/jq
2014-07-14 11:24:47 +02:00
Nico Williams 918ada06dc Merge pull request #482 from mbruggmann/manual-fixes
Fix manual example for `endswith`.
2014-07-13 19:01:57 -05:00
Nicolas Williams cb2737a433 Add regression test for #479 2014-07-13 19:00:37 -05:00
Nicolas Williams c38e5b1b2c Lib defs don't bind to each other; fix #479 again 2014-07-13 18:36:27 -05:00
Marc Bruggmann 089041b090 Fix manual example for endswith. 2014-07-13 19:02:21 +02:00
Nicolas Williams cadf8c3cb0 Revert "Library defs don't bind to each other; fix #479"
This reverts commit 6b6e3f4262.  It was
the wrong fix.
2014-07-13 02:04:27 -05:00
Nicolas Williams 6b6e3f4262 Library defs don't bind to each other; fix #479 2014-07-12 18:38:55 -05:00
Nicolas Williams 6e88d419ba Fix #478 assertion failure 2014-07-10 19:23:02 -05:00
Nico Williams ab4bf05300 Merge pull request #475 from qqshfox/patch-1
Fix examples for `del` in manual
2014-07-09 10:09:28 -05:00
Hanfei Shen ecac7bd3a1 Fix examples for del in manual 2014-07-09 16:37:17 +08:00
Zhiming Wang 1d620c0de3 Fix invalid YAML in manual.yml
Grave accent "`" is a reserved indicator in YAML per
http://www.yaml.org/spec/1.2/spec.html#id2774228, so it can't start a
plain scalar. This commit applies quoting to titles beginning with
grave accents.

Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2014-07-09 01:12:23 -05:00
Zhiming Wang f68815d5ad Add tests/all.trs to .gitignore
tests/all.trs is auto generated during make check.

Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2014-07-09 01:11:41 -05:00
Nicolas Williams 666aeda82c Better document path()'s power; also |= 2014-07-09 01:05:06 -05:00
Nicolas Williams 5be80b81eb Add foreach EXP as $var (INIT; UPDATE) form 2014-07-09 00:43:06 -05:00
Nicolas Williams 10477fc2d4 Make while() handle break 2014-07-09 00:39:25 -05:00
Nicolas Williams d8672e1b2a Make C-coded built-ins take jq_state * argument 2014-07-07 23:37:42 -05:00
Nicolas Williams a68958e5dc error(x) should not tostring its arg; fix #466 2014-07-07 22:26:53 -05:00
Nicolas Williams 824f7df404 limit should use break 2014-07-07 22:26:07 -05:00
Nicolas Williams 4bcff40828 Make any/2 and all/2 efficient using foreach 2014-07-07 22:25:34 -05:00
Nicolas Williams 80a9937e48 exec_stack.h was not using jv_mem_realloc() 2014-07-07 19:33:19 -05:00
Nicolas Williams b963ebaf1d jv_invalid() shouldn't allocate
jv_invalid() should behave like jv_invalid_with_msg(jv_null()), and
neither should allocate memory, because neither ought to need to.
2014-07-07 19:33:18 -05:00
Nicolas Williams eb45372414 jv_show() should be able to display invalid values 2014-07-07 19:33:18 -05:00
Nicolas Williams 539dccae90 Add break builtin for foreach 2014-07-07 19:33:17 -05:00
Nicolas Williams 6458910ba3 Explain foreach's powers a bit more 2014-07-07 17:22:53 -05:00
Nicolas Williams ef9b591215 Document path(path_expression) builtin 2014-07-07 17:13:51 -05:00
Nicolas Williams f845808813 Add missing backtick in manual 2014-07-07 17:13:48 -05:00
Nicolas Williams 25719b5596 $var["foo"]=1 can't work as expected; doc fix #236 2014-07-07 16:56:14 -05:00
Nicolas Williams 8780bc0b8e Better check for lib has only functions (fix #138) 2014-07-07 16:03:32 -05:00
Nicolas Williams 821cd31e67 Add any/N and all/N x N in (1, 2) (fix #455)
Contributed by @pkoppstein.
2014-07-06 20:08:06 -05:00
Nicolas Williams 5a863bf010 Add foreach and limit 2014-07-06 19:40:05 -05:00
William Langford d0ca11d665 Add support for negative indices for .[]; fix #462
Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2014-07-06 01:40:22 -05:00
Nicolas Williams 7d3a44a1e2 Add general ? operator 2014-07-06 01:29:43 -05:00
Nicolas Williams 7fce34292e Add try EXP catch EXP 2014-07-06 01:29:42 -05:00
Nicolas Williams 9113282c27 Document error/1 2014-07-06 00:27:05 -05:00
Nicolas Williams 78a8419428 Add while(cond; update) (fix #314) 2014-07-02 22:05:33 -05:00
Nicolas Williams ff9a61ead2 Add range(init;upto;by) (fix #317) 2014-07-02 22:05:33 -05:00
Nicolas Williams 3a647d3e47 Multi-arity needs better errors (fix #438) 2014-07-02 02:18:10 -05:00
Nicolas Williams 1f17ef3623 Descrive generators, range() with by to manual 2014-07-01 23:32:44 -05:00
Nicolas Williams a6030ab374 Fix typo in manual 2014-07-01 23:32:40 -05:00
William Langford 9f4d7e2fb8 Fixed base64 issue with UTF-8 strings
Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2014-07-01 22:56:13 -05:00
Nicolas Williams ba1acbe961 Teach disassembler about TAIL_CALL_JQ 2014-07-01 22:49:25 -05:00
Nicolas Williams 9deee38dc8 Fix off-by-one in TCO
Now we have the ability to define a generator in jq:

        def for(cond; update):
            def _for:
                if cond then ., (update | _for) else . end;
            _for;

        for(. < 10; . + 1) # generates numbers between `.` and 10

    Running this by hand with --debug-dump-disasm (with a fix for that
    coming up next) we can see that the call to _for is optimized:

        _for:0:
          0000 DUP
          0001 CALL_JQ cond:0^1
          0005 JUMP_F 0022
          0007 POP
          0008 FORK 0012
          0010 JUMP 0020
          0012 CALL_JQ update:1^1
          0016 TAIL_CALL_JQ _for:0^1
          0020 JUMP 0023
          0022 POP
          0023 RET

    And timing this with 1000, 10000, 100000 iterations shows that
    indeed we must be applying TCO; otherwise, without TCO, this gets
    very slow very quickly.
2014-07-01 22:40:40 -05:00
Nicolas Williams 436941d48b TCO to the max!
Close #446.

    Currently tested by disassembling and tracing various recursive jq
    programs by hand under valgrind.  An improved test framework that
    can test for errors and specific bytecode patterns is in
    development.
2014-06-30 23:41:20 -05:00
William Langford e1c5a2f575 Added cross-compilation script to build libjq for iOS.
Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2014-06-30 20:02:19 -05:00
Zhiming Wang a5e9086676 Let @uri produce uppercase hexadecimal digits...
instead of lowercase ones.

According to RFC 3986,

   The uppercase hexadecimal digits 'A' through 'F' are equivalent to
   the lowercase digits 'a' through 'f', respectively.  If two URIs
   differ only in the case of hexadecimal digits used in percent-encoded
   octets, they are equivalent.  For consistency, URI producers and
   normalizers should use uppercase hexadecimal digits for all percent-
   encodings.

See https://github.com/stedolan/jq/issues/451 for details.

Test suite and manual are also updated to reflect this change.

Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2014-06-30 19:52:42 -05:00
Nicolas Williams 1204e328df Add much commentary about CALL_JQ and call frames 2014-06-30 19:40:56 -05:00
Nicolas Williams 3e1baf5916 Get "Try Online" button working (fix #440) 2014-06-24 00:39:00 -05:00
Nicolas Williams beb0d081bb Improve TCO
Instead of checking for self-recursion check that the thing we're
calling is a function and not a closure, therefore the new frame will
have the same env as the current frame.
2014-06-23 19:59:00 -05:00
Nicolas Williams 4b7c701fdd Tail call optimization (close #437) 2014-06-22 00:24:02 -05:00
Nicolas Williams 233e32208c Fix option stacking bug 2014-06-21 18:01:00 -05:00
Nicolas Williams 63e31c2a35 Remove stray fprintf() from last commit 2014-06-20 23:29:53 -05:00
Nicolas Williams f9349becab Allow stacking of short options (fix #346) 2014-06-20 23:26:54 -05:00
Nicolas Williams ff5cf0abc7 Remove extra free of testmode
I added a jv_free() too many while rebasing @wtlangford's contribution.
It could only be triggered by calling `_match_impl` directly.
2014-06-18 21:11:06 -05:00
William Langford 8ff935c01a Added regex support as per issue #164.
jq now depends on oniguruma for regex support.
Modified configure.ac accordingly.

Added valgrind suppression file for oniguruma to prevent one-time and bounded
leaks from causing tests to fail.

Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2014-06-18 21:02:47 -05:00
Nicolas Williams 5d9d1b1020 Partial revamp of scripts/crosscompile
Fix #430.
2014-06-18 16:29:37 -05:00
Nicolas Williams 8725d9fa3e Minor style cleanup in main.c 2014-06-17 19:04:55 -05:00
Nicolas Williams 9ae2d66d21 Remove remnants of --online-input option 2014-06-17 19:02:23 -05:00
Nicolas Williams 0c762925b2 Add -j / --join-output option, similar to -r
Fix #215.
2014-06-17 18:59:35 -05:00
David Haguenauer ad52026550 Fixed typo.
Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2014-06-17 18:47:27 -05:00
Nicolas Williams cf7895876b Rebuild jq.1.prebuilt 2014-06-17 18:17:50 -05:00
Nicolas Williams f902d5fae6 Remove trailing whitespace from manual.yml 2014-06-17 18:17:50 -05:00
Nicolas Williams 98e3ebc378 Use new style in manual for defs with args 2014-06-17 18:17:50 -05:00
Santiago Lapresta dde43f796e Simplified standard library
Close #426.

Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2014-06-17 18:17:50 -05:00
Nicolas Williams 7ee3b724d1 Fix #419, improve Cannot index message (sortof)
jv_get() doesn't know if it's being called in the context of a jq
program or not, so it can't produce a very useful error message when the
types of the to-be-indexed value and the key don't agree.  For now,
including the key (when it is a short string) in the error message is as
significant an improvement as is easy to make.
2014-06-17 17:00:23 -05:00
Nicolas Williams e151a300d0 Fix #266; make help message more useful 2014-06-17 16:47:12 -05:00
Nicolas Williams f58f771660 Fix #280: from_entries of [] is null, should be {} 2014-06-16 22:40:44 -05:00
Nicolas Williams ea63d5d3c2 No args default w/ tty stdout, not tty stdin #220 2014-06-16 22:34:50 -05:00
Nicolas Williams ea0ffe24f8 Don't declare environ on WIN32 2014-06-16 22:34:37 -05:00
Santiago Lapresta 061a604a2a Added flatten and flatten(x) functions
Fix #415.
2014-06-16 17:03:05 -05:00
Nicolas Williams f741074267 Remove download 1.3 button; reposition try online 2014-06-16 17:01:09 -05:00
Nicolas Williams de5952d67e Add ChangeLog and NEWS files 2014-06-16 15:29:48 -05:00
Nicolas Williams a03f4802ef Add missing contributors to AUTHORS 2014-06-16 15:29:31 -05:00
Nicolas Williams 778ba9f7ab Update AUTHORS 2014-06-16 13:25:50 -05:00
Nicolas Williams 676e0ce38e Fix Win64 jq.exe link on main page 2014-06-16 11:13:55 -05:00
Nicolas Williams 088a42fc53 Allow multiple functions with different arities 2014-06-16 00:05:30 -05:00
Nicolas Williams 63dbac28ad Fix typo; rename jq.1-prebuit to jq.1.prebuilt 2014-06-13 19:04:06 -05:00
Nicolas Williams e9a1de47b4 Add env builtin 2014-06-13 17:51:41 -05:00
Nicolas Williams d14fca0cc6 Document the lambda nature of function args #391 2014-06-13 17:22:43 -05:00
Nicolas Williams bb83813f51 Automatically update jq.1.prebuilt 2014-06-13 17:22:17 -05:00
Nicolas Williams 8225d4e0c5 Add jqplay link to the site 2014-06-13 17:21:56 -05:00
Jingwen Owen Ou d45195ab5c jqplay has a domain now 2014-06-12 18:17:39 -07:00
Nicolas Williams 73bd347fcf Add links to Solaris 11+ executables 2014-06-12 19:26:05 -05:00
Nicolas Williams c9dbe090c5 Include links to 1.3 executables in gh-pages 2014-06-12 17:30:30 -05:00
Nicolas Williams 61cc0d4fb1 Make a better jq.1 when Ruby deps missing 2014-06-12 17:30:09 -05:00
Nico Williams 15c4a7f95f Merge pull request #400 from kdeme/master
Heuristic IEEE754 endianness autoconf detection

Use AC_C_BIGENDIAN, though it's not really the correct approach.  Autoconf ought to have provided a test specifically for IEEE754 endianness, since it can differ from integer/pointer endianness!
2014-06-12 15:55:41 -05:00
Kim De Mey 20e629284f Detect endianness at configuration with Autoconf AC_C_BIGENDIAN feature 2014-06-11 10:37:32 +02:00
Nicolas Williams e73951f3d1 Add lib.h to dist file list 2014-06-09 18:58:46 -05:00
Nicolas Williams fdf843c08b Make the note about shell quoting appear on site 2014-06-09 17:43:17 -05:00
Nicolas Williams cf145ec65e Add note about cmd.exe quoting 2014-06-09 10:22:55 -05:00
Nicolas Williams 4889844d0c Building docs fails on powerpc (#349)
Thanks @shym!!
2014-06-09 09:39:02 -05:00
Nicolas Williams dc7857c585 Update site news 2014-06-08 20:45:06 -05:00
Nicolas Williams d65dbf89c9 Also fix configure.ac to use git describe --tags 2014-06-08 19:36:06 -05:00
Nicolas Williams ed2b3e26fb Fix scripts/version: use git describe --tags ...
After tagging as 1.4 scripts/version was still producing jq-1.3-....
2014-06-08 19:31:21 -05:00
Nicolas Williams 46436bd870 Add test of indices with short input 2014-06-08 02:27:27 -05:00
Nicolas Williams 1dbe9317bc Add indices(s), improve index(s), rindex(s)
Now these deal with arrays as input and `s` being an array or a scalar.
2014-06-08 02:01:44 -05:00
Nicolas Williams ef4f3a54fe Improve index and rindex examples 2014-06-08 02:01:21 -05:00
Nicolas Williams 9af03c2562 Remove reference to getpath from docs 2014-06-08 01:35:03 -05:00
Nicolas Williams c10e5f4e73 Document index and rindex (#389) 2014-06-08 00:00:17 -05:00
Santiago Lapresta 01f676041d Added join function
Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2014-06-07 21:53:03 -05:00
Nicolas Williams 6856ab8a69 String * number should be commutative 2014-06-07 21:43:30 -05:00
Nicolas Williams 8212750fe9 Add cross-compilation notes to README
A detailed set of instruction as to how to setup a cross-compilation
environment for OS X and Win32/64 would be nice.
2014-06-04 18:36:30 -05:00
Nicolas Williams 35b6b949e3 Add -j option to scripts/crosscompile 2014-06-04 18:36:30 -05:00
Nicolas Williams d1ea3ab89d Add flags argument to jv_parser_new()
For extensibility.  We might add streaming parser options, even binary
JSON encoding options.
2014-06-04 18:35:30 -05:00
Nicolas Williams ae625d0de7 Revert "Add -I / --online-input for huge top-level arrays"
This reverts commit 77936a594d.

There are too many odd bugs in this mode, and it turns out to be a bad
idea anyways.  Instead, in the future a better option will be to pursue
alternative parsers, such as:

 - streaming parser that outputs only when a new leaf value is added or
   an array/object is opened/closed; options here include whether to
   include a path in each output;

 - parsers for binary JSON encodings (there's a variety of them).

Then one might run jq with a streaming parser and use `reduce` to
coalesce inputs from some depth down (instead of from one level down as
the reverted commit had intended).

Besides, a fully streaming parser is desirable in some cases, therefore
we should have such a thing as an option.

I've explored modifying the current parser to support a streaming
option, but it only makes the code very difficult to follow, which is
one reason that alternate parsers makes sense.  At any rate, this is all
for the future.  For now there's no streaming of individual texts, just
text sequences.
2014-06-04 18:15:58 -05:00
Nicolas Williams 5fb82d1018 Fix tests failures on Windows
And Solaris 8 and 9 too, no doubt.  The problem was that non-standard
vsnprintf()s that return -1 when the buffer is too small were not
properly supported.
2014-06-02 00:56:01 -05:00
Nicolas Williams f9d1b94496 Update .gitignore and config/.gitignore 2014-06-01 22:32:53 -05:00
Nico Williams 854ff5643a Merge pull request #367 from slapresta/del-docs
Documented `del` command
2014-05-20 22:11:01 -05:00
Santiago Lapresta 072ebb911b Documented del command 2014-05-21 01:23:28 +02:00
Nico Williams d46f5d29fa Merge pull request #360 from slapresta/275-unique-by
unique_by(.foo) function
2014-05-12 00:30:55 -05:00
Santiago Lapresta 69aa0003af Added texts/examples to unique_by function 2014-05-12 01:44:53 +02:00
Santiago Lapresta 41a093c1f2 Added unique_by function 2014-05-12 01:37:27 +02:00
Nicolas Williams 022a418894 Make pthread tls configurable for Mingw build
For the Mingw build we don't want to pull in the pthread DLL just
because we can autodetect pthread support.  That would make the jq.exe
binary not self-contained.
2014-04-17 20:17:06 -05:00
Nicolas Williams d056668f4f Add autoconf checks for pthreads; fix #340 2014-04-16 18:42:36 -05:00
Nico Williams 917334d18a Merge pull request #332 from jingweno/master
Add link to jq playground
2014-03-20 23:47:40 -05:00
Jingwen Owen Ou 7a83f1c416 Add link to jqplay 2014-03-20 15:49:59 -07:00
Nico Williams 6f0a9521e1 Merge pull request #176 from pearkes/new-tutorial
Docs: Update the tutorial to use GitHub's API
2014-03-13 00:57:54 -05:00
Nicolas Williams aee5c3ecb0 Fix for #303 in the sources 2014-03-13 00:57:33 -05:00
Nico Williams da0d575649 Merge pull request #278 from polyester/master
work with newer versions of automake
2014-03-13 00:52:58 -05:00
Nicolas Williams 74d2216da2 Test arrays and friend filters 2014-03-13 00:29:53 -05:00
Nicolas Williams 769314a8a2 Document scalars 2014-03-13 00:29:53 -05:00
Nicolas Williams 831be04027 Also add scalars 2014-03-13 00:29:53 -05:00
Nicolas Williams 1a1adf73e8 Document arrays, objects, ... 2014-03-13 00:29:53 -05:00
Santiago Lapresta 68f41097b9 Added arrays and other filters
Arrays, objects, numbers, strings, booleans, nulls, values (non-nulls)
-- these builtins filter out those inputs that don't match the name of
the builtin.

This fixes #322 and #324.
2014-03-13 00:27:56 -05:00
Nicolas Williams 4402c6d806 One more recursive merge test 2014-03-12 23:44:21 -05:00
Filippo Valsorda 2aa8a43c5b Add a recursive object merge strategy and bind it to *
This commit adds a jv_object_merge_recursive function, that performs
recursive object merging, and binds it to multiply when applied to
two objects.

Added docs and tests.

Closes #320
2014-03-08 03:56:05 +01:00
Nicolas Williams 219bb9ecb7 Make libm tests more portable 2014-03-06 21:38:10 -06:00
Nico Williams 88fd2ee4f2 Merge pull request #310 from arodland/master
Make jq --raw-output --unbuffered work
2014-03-03 13:46:38 -06:00
Andrew Rodland 6c3683dfe9 Repair jv_show 2014-02-26 01:43:00 -06:00
Andrew Rodland 36e495da1e Make jq --raw-output --unbuffered work
--unbuffered was only affecting the normal output case, not the --raw-output case. Make the two of them play together.

This also makes sure that the output is flushed *after* printing the newline, so a consumer doesn't lag a line behind.
2014-02-26 01:42:29 -06:00
Nicolas Williams 15faf9dc3b Add cbrt (cube root) 2014-02-21 10:51:16 -06:00
Nicolas Williams 59302fd208 Add missing trig functions and barebones test 2014-02-21 10:49:21 -06:00
Nicolas Williams 24202d1ecf Remove non-standard exp10() 2014-02-21 10:49:10 -06:00
Mike McCabe 336f4e27e6 Initial add of math functions. 2014-02-21 08:46:56 +00:00
Nicolas Williams fe29d3d3fa Add ?, .[]?, and .. operators
Make XPath-like `//a/b` recursive structure traversal easier in jq,
which then becomes:

    ..|.a?.b?

The `?` operator suppresses errors about . not being an array or object.
The `..` operator is equivalent to calling the new `recurse_down`
built-in, which in turn is equivalent to

    recurse(.[]?)

Note that `..a` is not supported; neither is `...a`.  That could be add
added, but it doesn't seem worth the trouble of saving the need to type
a '|'.
2014-02-20 15:33:07 -06:00
Nico Williams 3d33412e9a Merge pull request #300 from lcd047/master
Fix building of the manual
2014-02-19 11:21:04 -06:00
LCD 47 fb9196021e manual.yml: fix indent for the new any and all commands. 2014-02-19 15:10:32 +02:00
Nico Williams b23fae9ee3 Merge pull request #296 from slapresta/all-any
Added `all` and `any` builtins
2014-02-16 22:45:49 -06:00
Santiago Lapresta 8b41415b07 Added all and any builtins 2014-02-17 04:01:32 +01:00
Nicolas Williams 1fa55a3fae Fix cut-n-paste in leaf_paths; doc and test 'em 2014-02-05 23:14:05 -06:00
Nicolas Williams a45c937f80 #285 add and builtins 2014-02-05 15:23:32 -06:00
polyester 6ed3adb091 work with newer versions of automake
when using a newer automake, the autoreconf step fails with warnings:
"linking libtool libraries using a non-POSIX archiver requires 'AM_PROG_AR' in 'configure.ac' "

This happens for instance on ubuntu 13.10. 
Doing just that, adding 'AM_PROG_AR' to configure.ac fixes the problem.
2014-01-25 18:55:58 +01:00
Nicolas Williams 106fdf5114 Fix #201; check that bison accepts --warnings 2014-01-01 23:10:00 -06:00
Nicolas Williams 99f170adc3 Fix version for make dist on master
- Re-remove VERSION file and all traces of it
 - Pass a decent version indicator to AC_INIT (using git describe)

When we tag 1.4 this will produce 1.4 as the version string when
building on the HEAD of that tag.
2013-12-31 17:19:40 -06:00
Joe Littlejohn f60d83c15f Fix rpm build (make rpm)
* Re-add VERSION as it's required for `./setup superclean`
  and `make rpm`.
* Add *.rpm to git ignore, we never want them under version control.
2013-12-27 13:01:14 -06:00
Filippo Giunchedi 36a47bae56 include additional files in jq.spec
this will probably need changing upon SONAME bump
2013-12-27 12:49:15 -06:00
Filippo Giunchedi dc8528af0f fix rpm Makefile target and prerequisites
depend on dist and the specfile, plus use automake's variables
2013-12-27 12:49:15 -06:00
Nicolas Williams e12d0ffd1e Document --version 2013-12-26 18:48:51 -06:00
Nicolas Williams a71138a43a Add jv_dumpf() and jv_show()
jv_dumpf() takes a FILE *.

jv_show() is intended for use in debuggers, so it dumps the jv to stderr
and it does not jv_free() the jv, so it's safe to
"call jv_show(some_jv, -1)" in a debugger.  If flags == -1 then the jv
will be shown pretty-printed and in color.
2013-12-26 18:40:34 -06:00
Nicolas Williams cb976b9a50 Document .foo.bar in manual 2013-12-26 18:25:31 -06:00
Nicolas Williams 060eb39bf9 Document exit numbers 2013-12-26 12:54:07 -06:00
Nicolas Williams ab363e9e50 Normalize errors for -e 2013-12-26 12:54:03 -06:00
Nicolas Williams 41a8ae7557 Fix doc typos (.[foo] wanted to be .["foo"]) 2013-12-25 17:09:27 -06:00
Nicolas Williams 1956abbedf Add note to jq.1 about shell quoting 2013-12-25 17:05:32 -06:00
Stephen Dolan 2003a0440f Merge pull request #251 from phihag/fix-uri-in-manual
Fix @uri example
2013-12-21 11:47:24 -08:00
Stephen Dolan a0274cc46e Merge pull request #252 from phihag/ignore-config-test-driver
Ignore the config/test-driver file
2013-12-21 11:46:53 -08:00
Philipp Hagemeister 3b384740b9 Ignore the config/test-driver file
This file is automatically generated and does not need to be committed.
2013-12-20 11:36:52 +01:00
Philipp Hagemeister 4d40a47eab Fix @uri example
Previously, the @uri example didn't match the actual behavior of the current jq, as exclamation marks do not need to be encoded in URIs.
Replace the example with an input that needs encoding, and is encoded by jq.
2013-12-20 11:32:53 +01:00
Stephen Dolan 18e828f17c Allow negated object values without parens. Fixes #247 2013-12-17 22:28:31 +00:00
Nicolas Williams 0966230ba8 Fix memmem() error 2013-12-17 08:40:03 -06:00
Stephen Dolan 669f4ab4c3 Merge pull request #242 from sieben/travis-ci
Adding a .travis.yml file to use the travis-ci.org
2013-12-15 12:54:17 -08:00
Rémy Léone 3455714410 Adding a .travis.yml file to use the travis-ci.org
From wikipedia:

Travis CI is a hosted, distributed continuous integration service used
to build and test projects hosted at GitHub.

Travis CI is configured by adding a file named .travis.yml, which is a
YAML format text file, to the root directory of the GitHub repository.

Travis CI automatically detects when a commit has been made and pushed
to a GitHub repository that is using Travis CI, and each time this
happens, it will try to build the project and run tests. This includes
commits to all branches, not just to the master branch. When that
process has completed, it will notify a developer in the way it has been
configured to do so — for example, by sending an email containing the
test results (showing success or failure), or by posting a message on an
IRC channel. It can be configured to run the tests on a range of
different machines, with different software installed (such as older
versions of a programming language, to test for compatibility).
2013-12-13 17:14:37 +01:00
Stephen Dolan 32ea50d336 Make the testsuite run on machines without valgrind 2013-12-13 15:22:17 +00:00
Stephen Dolan 5ac6a460fa Format more integers as integers, not scientific notation.
jq is now willing to put up to 15 zeros after an integer before
moving to scientific notation.
2013-12-13 15:22:17 +00:00
Stephen Dolan f147b7fae5 Merge pull request #239 from DRMacIver/overflows
Avoid undefined behaviour with large array indices
2013-12-12 16:38:14 -08:00
Nicolas Williams 474386a1d9 Complete more-arity feature not complete
And test
2013-12-11 14:14:26 -06:00
Stephen Dolan 7fd2c2d08b Merge pull request #235 from DRMacIver/prototypes
some functions were missing proper prototypes
2013-12-10 03:56:02 -08:00
David R. MacIver 5412f3f1c1 convert range bounds to integers in a way that avoids undefined behaviour 2013-12-10 09:20:13 +00:00
David R. MacIver 014b45b4a9 add checking of numeric indices to an array to see if they can reasonably be considered integers. Avoid undefined behaviour if out of bounds 2013-12-10 09:20:12 +00:00
David R. MacIver 30ea390b77 some functions were missing prototypes. Add them 2013-12-10 00:07:08 +00:00
Stephen Dolan 00f244385b Merge pull request #232 from DRMacIver/teardown_on_error
consistent use of goto out in main
2013-12-08 16:41:16 -08:00
David R. MacIver 7b671b95d2 don't need to check for NULL there 2013-12-08 23:52:07 +00:00
Stephen Dolan 1535f23455 Merge pull request #233 from DRMacIver/printf
Fix warnings about vprintf
2013-12-08 15:44:33 -08:00
Stephen Dolan 4ba0c8baef Merge pull request #231 from DRMacIver/fix_mem_leak_in_compile
args to jq_compile_args were not getting freed when there were errors in the compile
2013-12-08 15:17:20 -08:00
Stephen Dolan a7dd3ab793 Clean up string/object interactions in jv. 2013-12-08 22:49:28 +00:00
David R. MacIver f6f7d4d973 These vfprintfs are being used as if they were printfs. Fix that 2013-12-08 20:08:04 +00:00
David R. MacIver f4ae5c883b consistent use of goto out in main 2013-12-08 19:22:18 +00:00
Stephen Dolan 74a14f5de7 Refactor jv structure.
New structure layout is simpler and also faster.  In particular, it's
now small enough to be passed in registers on amd64.
2013-12-08 17:46:23 +00:00
Stephen Dolan fee21c959a Make testsuite not leak when compiled with -DNDEBUG. 2013-12-08 17:44:54 +00:00
David R. MacIver 4b48054f41 test for losing memory on compile errors 2013-12-08 16:19:12 +00:00
David R. MacIver 17a319d120 args to jq_compile_args were not getting freed when there were errors in the compile 2013-12-08 15:28:29 +00:00
Nicolas Williams 3a1dab5396 Fix double-free typo in print_error() 2013-12-06 23:25:06 -06:00
Nicolas Williams dac081e183 Fix manual.yml 2013-12-06 11:58:55 -06:00
Stephen Dolan 489fcdc089 Merge pull request #224 from nicowilliams/features
Features: more arity, string ops
2013-12-04 17:36:08 -08:00
Nicolas Williams 3ba7c97b2a Add self to AUTHORS 2013-12-04 18:21:42 -06:00
Nicolas Williams 54635000c5 Conditionally #define _GNU_SOURCE in compile.c 2013-12-04 18:21:42 -06:00
Nicolas Williams 426edff09c Add tests for string index by string and builtins 2013-12-04 18:21:42 -06:00
Nicolas Williams b37ce20c2a Add index and rindex builtins 2013-12-04 18:21:42 -06:00
Nicolas Williams cac14a531d Add index strings by string; return string indexes
% jq '.[","]'
    "a,bc,def,ghij,klmno"
    [1,4,8,13]
    %
2013-12-04 18:21:42 -06:00
Nicolas Williams ae7a042876 Make length return abs value of numeric inputs 2013-12-04 18:21:42 -06:00
Nicolas Williams eb165459aa Add callback interface for errors
Printing to stderr is not the right answer for a library.
2013-12-04 18:21:41 -06:00
Nicolas Williams 04bc2ef7cf Add jv_string_vfmt() 2013-12-04 18:21:41 -06:00
Nicolas Williams 09104ce531 Document ltrimstr and rtrimstr 2013-12-04 18:21:41 -06:00
Nicolas Williams 9fa2173825 Test ltrimstr and rtrimstr functions 2013-12-04 18:21:41 -06:00
Nicolas Williams 346da34432 Add ltrimstr and rtrimstr functions 2013-12-04 18:21:41 -06:00
Nicolas Williams fa316ac430 Document -u / --unslurp option 2013-12-04 18:21:41 -06:00
Nicolas Williams 77936a594d Add -I / --online-input for huge top-level arrays 2013-12-04 18:21:41 -06:00
Nicolas Williams 4e07eac356 Document -e / --exit-status argument 2013-12-04 18:21:40 -06:00
Nicolas Williams d018e43ddc Add -e | --exit-status CLI option 2013-12-04 18:21:40 -06:00
Nicolas Williams 8cee66e609 Document tojson and fromjson builtins 2013-12-04 18:21:40 -06:00
Nicolas Williams 3c4248192d Test tojson and fromjson 2013-12-04 18:21:40 -06:00
Nicolas Williams 255f8ef5be Add tojson and fromjson builtins 2013-12-04 18:21:40 -06:00
Nicolas Williams 20b32db5af Document split function 2013-12-04 18:21:40 -06:00
Nicolas Williams b634722c8a Document string multiplication and division 2013-12-04 18:21:40 -06:00
Nicolas Williams c9e8581f45 Document string functions and slicing 2013-12-04 18:21:39 -06:00
Nicolas Williams da129f6664 Test string slicing 2013-12-04 18:21:39 -06:00
Nicolas Williams 884e6c7d8b Add string slicing 2013-12-04 18:21:39 -06:00
Nicolas Williams 5aadaa79eb Add tests for string division/splitting 2013-12-04 18:21:39 -06:00
Nicolas Williams cf562961b7 Add string division by string (split on separator) 2013-12-04 18:21:39 -06:00
Nicolas Williams 63bed9bdf1 Test starts/endswith and string multiplication 2013-12-04 18:21:39 -06:00
Nicolas Williams 5989dbdfcf Add string multiplication by number 2013-12-04 18:21:39 -06:00
Nicolas Williams db19a11399 Add startswith/endswith 2013-12-04 18:21:38 -06:00
Nicolas Williams 6c734cb609 Add explode/implode jq functions to match jv API 2013-12-04 18:21:38 -06:00
Nicolas Williams ef41d1cb57 Use uint32_t for codepoint in jv_string_append_codepoint() 2013-12-04 18:21:38 -06:00
Nicolas Williams 08b4a34a8e Add jv string utility functions
jv_string_empty()
        -> return an empty string with given allocated length (for fast
           appends)
    jv_string_append_codepoint
        -> append a single codepoint (int) to the given string
    jv_string_explode
        -> return an array of codepoints making up a string
    jv_string_implode
        -> return the UTF-8 encoding of an array of codepoint numbers
2013-12-04 18:21:38 -06:00
Nicolas Williams 1fc5656762 Support more arguments for defs 2013-12-04 18:21:38 -06:00
Stephen Dolan 91cfc34ae4 Preserve insertion order in objects. Closes #169. 2013-12-04 22:30:39 +00:00
Nicolas Pouillard a0b942a7f5 Add a few more test cases (from the man page)
Signed-off-by: Nicolas Williams <nico@cryptonector.com>
2013-11-30 00:55:26 -06:00
Stephen Dolan 6a401c8262 Add a --unbuffered option. Closes #206 2013-11-08 12:21:45 +00:00
Stephen Dolan d235f32bc9 Merge pull request #210 from Habbie/patch-1
count should be length
2013-11-08 03:43:57 -08:00
Peter van Dijk bdbfa7e32c count should be length
Example refers to a count function, which does not exist. Replacing it with length works.
2013-11-07 16:39:44 +01:00
Stephen Dolan 78976b3504 Merge pull request #193 from ryo1kato/fix-docs
Docs: add description of --from-file option
2013-11-07 04:41:01 -08:00
Stephen Dolan 8d4748c8df Fix a crash on group_by of empty list. Fixes #208. 2013-11-07 12:18:48 +00:00
Ryoichi KATO da723d3e11 Docs: add description of --from-file option 2013-10-16 21:42:29 +09:00
Stephen Dolan 0feeb7d0d4 Merge pull request #188 from Juanxo/patch-1
Fix typo on error message
2013-10-07 06:59:50 -07:00
Juan Guerrero 9e53f36a74 Fix typo on error message 2013-10-06 17:52:04 +02:00
Stephen Dolan 7e7c08da47 Merge pull request #185 from qoelet/master
Add missing -i flag in build instructions
2013-09-20 06:05:42 -07:00
Kenny Shen 2f6b89ef70 Add missing -i flag in build instructions 2013-09-20 10:34:57 +08:00
Stephen Dolan 4e3024cb61 Merge pull request #182 from mdaines/sqrt-builtin
Add builtin for calculating square root
2013-09-14 16:34:52 -07:00
Michael Daines c427bf6a94 Add test showing calculation of standard deviation 2013-09-14 17:48:19 -04:00
Stephen Dolan dae2422fd1 Merge branch 'libjq'
Conflicts:
	Makefile.am
	configure.ac
2013-09-14 19:30:39 +01:00
Stephen Dolan f98e3e6c26 Merge pull request #181 from mdaines/patch-1
Fix typo
2013-09-13 15:24:22 -07:00
Mike Daines fe99532f8b Fix typo 2013-09-13 12:15:52 -04:00
Stephen Dolan 41a4968c90 Merge pull request #171 from joelittlejohn/fix-makefile
Fix Makefile after refactoring of stacks in 05d90517b0
2013-09-13 09:02:42 -07:00
Stephen Dolan 1cdaabf2dd Merge pull request #175 from lipidity/fix-build
Call AM_INIT_AUTOMAKE once only
2013-09-13 09:02:24 -07:00
Michael Daines 82d8253c19 Add sqrt operator 2013-09-11 20:24:41 -04:00
Jack Pearkes c1717d6e12 docs: update the tutorial to use GitHub's API 2013-09-04 11:42:40 +02:00
Ankur f0d1c39b5b Call AM_INIT_AUTOMAKE once only
Fixes build with automake-1.14
2013-09-01 18:58:26 +10:00
Joe Littlejohn 111aea3f0a Fix Makefile after refactoring of stacks in 05d90517b0 2013-08-19 13:40:08 +01:00
Stephen Dolan 37cfc912c1 Remove #includes from jv.h 2013-06-23 14:23:07 +01:00
Stephen Dolan 8c2e228c74 Fix the jv_parser interface. 2013-06-23 12:26:49 +01:00
Stephen Dolan 8630fb02bb Use libtool's built-in symbol exporting rather than a mapfile. 2013-06-23 12:10:58 +01:00
Stephen Dolan 5052ab4e2b Move gen_utf8_tables to scripts 2013-06-23 12:08:22 +01:00
Stephen Dolan a44f739356 Move libtool m4 junk to config/ and delete some autogenerated files. 2013-06-23 12:01:58 +01:00
Stephen Dolan f44ecf3872 Remove Autoconf-generated config.h. 2013-06-23 12:01:58 +01:00
Stephen Dolan 1c9e03f800 Merge branch 'header-cleanup' into libjq
Conflicts:
	Makefile.am
2013-06-22 23:27:16 +01:00
Stephen Dolan 5d9ec83805 Build libjq only once, and link it statically to ./jq
This means ./jq is a real binary rather than a libtool turd.
2013-06-22 20:53:28 +01:00
Stephen Dolan 3a295c659b Fix distcheck.
Update list of files to be distributed.
2013-06-22 20:53:03 +01:00
Stephen Dolan d253414783 Merge pull request #162 from stedolan/utf8-fixes
Utf8 fixes. Closes #161
2013-06-22 09:30:59 -07:00
Stephen Dolan 8b1b503609 Reject all overlong UTF8 sequences. 2013-06-22 13:43:46 +01:00
Stephen Dolan ff48bd6ec5 Fix various UTF8 parsing bugs.
In particular, parse bad UTF8 by replacing the broken bits with U+FFFD
and resychronise correctly after broken sequences.
2013-06-22 13:34:24 +01:00
Stephen Dolan 54b9c9bdb2 Fix example in manual for floor. See #155. 2013-06-22 12:17:28 +01:00
Nicolas Williams 3dcdc582ea Document floor 2013-06-21 15:27:34 -05:00
Nicolas Williams 7c4171d414 Add floor operator 2013-06-21 15:27:34 -05:00
Nicolas Williams 1d839ff9df Document mod 2013-06-21 15:27:34 -05:00
Nicolas Williams 3403d07912 Add mod (and setmod) operators 2013-06-21 15:27:34 -05:00
Nicolas Williams e8643787cf Update .gitignore 2013-06-21 12:41:57 -05:00
Nicolas Williams 298b2a6033 Add libjq autoconf goo 2013-06-21 11:57:12 -05:00
Nicolas Williams c791428905 Quiet setup.sh re: tmp dir 2013-06-21 11:57:11 -05:00
Stephen Dolan dc2fe63e42 Merge pull request #157 from nicowilliams/argfile-fixes
Argfile fixes
2013-06-21 09:40:32 -07:00
Stephen Dolan 7af88962ee Move cfunction invocation code to the interpreter loop. 2013-06-21 12:06:28 +01:00
Nicolas Williams 3216d7683a Fix serious bug in handling of --argfile 2013-06-18 19:05:52 -05:00
Nicolas Williams e4094c8664 Fix leaks in jv_load_file() 2013-06-18 19:05:52 -05:00
Stephen Dolan b49d65a276 Fold opcode.{c,h} into bytecode.{c,h} 2013-06-18 01:36:18 +01:00
Stephen Dolan 824ce76cec Simplify block functions for variables 2013-06-18 01:07:18 +01:00
Stephen Dolan 2a18f97d12 Saner build instructions in README.md
Closes #144
2013-06-18 00:29:05 +01:00
Stephen Dolan 8c4d29ee38 Remove some initialise-to-zero code.
This lets valgrind find more bugs - if a field isn't given a
well-defined value valgrind will now find it instead of seeing it
set to zero with memset.
2013-06-18 00:17:20 +01:00
Stephen Dolan 2c13f4fe72 Merge branch 'stack-refactor-merge' 2013-06-18 00:13:44 +01:00
Stephen Dolan 94931040a8 Merge branch 'stack-refactor'
Conflicts:
	execute.c
2013-06-18 00:06:00 +01:00
Stephen Dolan b78a4cdc93 Merge pull request #154 from nicowilliams/no-fopen-re
Remove accidentally introduced use of fopen "e"
2013-06-17 15:34:01 -07:00
Nicolas Williams da09544bb0 Remove accidentally introduced use of fopen "e" 2013-06-17 17:27:25 -05:00
Stephen Dolan ce17b6bd53 Merge pull request #114 from nicowilliams/nomem_handler
Add jv_nomem_handler()
2013-06-16 06:20:27 -07:00
Nicolas Williams fe03bea191 Remove last remnant of main.h 2013-06-16 08:06:52 -05:00
Nicolas Williams 0ed6347d47 Allow --run-tests to take a file argument 2013-06-15 17:37:15 -05:00
Nicolas Williams 3f86e97f70 Fixup API to get closer to a libjq 2013-06-15 17:37:15 -05:00
Stephen Dolan 69fa279e3c Merge pull request #150 from nicowilliams/jv_load_file
Move slurp_file() into library as jv_load_file()
2013-06-15 05:29:17 -07:00
Nicolas Williams bbf4e05fde Move slurp_file() into library as jv_load_file()
Needed as part of creating a libjq.
2013-06-15 00:08:59 -05:00
Stephen Dolan 05d90517b0 Clean up lots of stack and frame logic.
Move frame defs to execute.c
2013-06-14 22:08:18 +01:00
Stephen Dolan 5f5c1dc5a6 Simplify frame logic. 2013-06-14 01:20:24 +01:00
Stephen Dolan e0524644f8 Unify all stacks. Passes tests, but needs cleanup. 2013-06-13 21:50:32 +01:00
Stephen Dolan 81e2336ace Support ."foo" syntax for accessing fields. See #141. 2013-06-11 22:26:39 +01:00
Stephen Dolan 25bf1a0169 Unify frame and data stacks 2013-06-10 01:17:58 +01:00
Stephen Dolan c8ab67be27 Speed up cached configure (./configure -C) 2013-06-05 16:40:01 +01:00
Stephen Dolan 6c34288ebf Clean up flex lines in build 2013-06-05 13:43:23 +01:00
Stephen Dolan 2ffbb9d6b7 Lex and parse .foo better.
'.as' is now valid, '. foo' is now invalid. See #141.
2013-06-05 13:41:56 +01:00
Stephen Dolan dad608d5c0 Merge pull request #142 from lanthaler/master
Update README.md
2013-06-04 04:13:24 -07:00
Markus Lanthaler 04b939625b Update README.md
Update the link to the documentation. All GitHub pages are now using the github.io domain.
2013-06-04 13:04:42 +02:00
Stephen Dolan 5dac485458 Make jq --version print to stdout, not stderr 2013-06-03 23:22:59 +01:00
Stephen Dolan 2c4ccd122e Better error handling for .foo case in parser. See #141. 2013-06-03 23:12:31 +01:00
Stephen Dolan b90ae078b8 Let the parser rather than the lexer handle invalid characters. 2013-06-03 23:12:31 +01:00
Stephen Dolan cc8761dbde Add command-line option to sort object keys.
Closes #79.
2013-06-03 23:12:31 +01:00
Stephen Dolan 08cc591884 Clean up Makefile.am (distcheck, rebuild version.h less often) 2013-06-03 23:12:31 +01:00
Stephen Dolan 1bc4d04f43 Merge pull request #139 from 13ren/stopwarning
Stop warning on fgets, jq_test.c:42
2013-06-01 07:30:15 -07:00
Brendan Macmillan d4018192a9 Stop warning on fgets, simple version 2013-06-01 11:12:28 +10:00
Brendan Macmillan 19ddbfeca9 Stop warning on fgets, complex version 2013-06-01 11:03:15 +10:00
Stephen Dolan 4fed6763fc Squash a warning on some GCC versions 2013-05-31 12:15:58 +01:00
Stephen Dolan 73446a9cce Support for printing object keys in sorted order.
No command-line option to enable this yet. See #79.
2013-05-29 11:47:12 +01:00
Stephen Dolan dcf1ac0d1f Merge pull request #135 from 13ren/locfile_bugfix
Locfile bugfix
2013-05-29 03:38:15 -07:00
Stephen Dolan 364c58d13f Merge pull request #130 from 13ren/libload_2
libload_2 (update to pull request #126, for issue  #112)
2013-05-29 03:37:36 -07:00
Brendan Macmillan 8cfe11e4e2 Bugfix multiline off-by-one (locfile.c) 2013-05-29 15:23:08 +10:00
Brendan Macmillan 40378a18f7 locfile.h -> locfile.h + locfile.c
clean up includes of a few files
2013-05-29 15:17:01 +10:00
Brendan Macmillan 7fb5d8c973 Hack bugfix for multiline off-by-one (locfile.c) 2013-05-29 15:16:45 +10:00
Brendan Macmillan 6e373942e5 Load library from ~/.jq 2013-05-29 15:05:40 +10:00
Stephen Dolan f0b982795c Make jq --version report an actual git revision.
Closes #129.
2013-05-24 23:35:38 +01:00
Stephen Dolan cbd422d56e Merge pull request #133 from nicowilliams/option_argfile-rebase0
Add --argfile variant of --arg (issue #117)
2013-05-24 04:13:45 -07:00
Nicolas Williams 03598bb5d6 Add --argfile variant of --arg (issue #117)
This is useful when one has a database (in JSON form) to query using jq
input data.

    % echo '{"a":1, "c":5}' > db.json
    % echo '"c"'|./jq --argfile f /tmp/a '$f[.]'
    5
    % echo '"a"'|./jq --argfile f /tmp/a '$f[.]'
    1
    % echo '"b"'|./jq --argfile f /tmp/a '$f[.]'
    null
    %
2013-05-23 13:52:06 -05:00
Stephen Dolan 983a53a643 'make clean' won't delete jq.1 if it can't be rebuilt.
See #131
2013-05-23 19:20:19 +01:00
Stephen Dolan 0535e724a2 jq 1.3 release 2013-05-19 11:48:18 +01:00
Stephen Dolan fd1ac5dd79 EACH need not make a backtrack point on the last iteration 2013-05-17 22:49:08 +01:00
Stephen Dolan 9b91eafac4 Make array construction use LOADVN (slightly faster) 2013-05-16 15:09:59 +01:00
Stephen Dolan bc42812715 Remove the insane "fold" operation, replace with saner "reduce". 2013-05-16 15:07:53 +01:00
Stephen Dolan 8fbee891b3 Add LOADVN opcode.
Does a variable load, but sets the variable to be null afterwards.
2013-05-16 15:02:18 +01:00
Stephen Dolan 919292764a Reverse function. Closes #94. 2013-05-16 14:25:28 +01:00
Stephen Dolan a1e4dfa324 Better debug info for struct bytecode.
--debug-dump-disasm produces more comprehensible output now.
2013-05-16 00:51:17 +01:00
Stephen Dolan f8644c31a3 Only generate code for those builtin functions actually used.
Makes output of --debug-dump-disasm much simpler.
2013-05-15 01:37:15 +01:00
Stephen Dolan 1e2851cdb3 Remove the YIELD opcode (use RET instead) 2013-05-15 01:23:06 +01:00
Stephen Dolan e83e51eb56 'length' function now measures string length in codepoints, not bytes. 2013-05-15 00:37:38 +01:00
Stephen Dolan c496a924ce Bugfix for array slices. 2013-05-15 00:22:44 +01:00
Stephen Dolan 81be37b236 Add the range function 2013-05-14 16:09:10 +01:00
Stephen Dolan 4d540b7102 Fix some documentation bugs 2013-05-13 20:26:44 +01:00
Stephen Dolan 33901b74b1 Array slicing. Closes #2. 2013-05-13 20:16:19 +01:00
Stephen Dolan a47cfa4757 Delete unnecessary _POSIX_SOURCE. Closes #89 2013-05-13 16:41:11 +01:00
Stephen Dolan a625d2821e Add to_entries, from_entries and with_entries functions.
Closes #97.
2013-05-13 16:15:49 +01:00
Stephen Dolan d8706fd460 Fix the //= operator.
Closes #62.
2013-05-13 16:04:30 +01:00
Stephen Dolan e13f24ab45 Better error handling for INSERT opcode
jq 'null | {(.a): 1}' no longer crashes.
2013-05-13 15:42:57 +01:00
Stephen Dolan 34a63246ab Remove the is_backtrack_frame special case hack. 2013-05-13 15:37:57 +01:00
Stephen Dolan 8c708f3c7a Refactor path logic. 2013-05-13 15:00:05 +01:00
Stephen Dolan b0e65d149f Fix a bug triggered by jv_array_slice. 2013-05-13 14:10:39 +01:00
Stephen Dolan e29db8d272 Fix bug with path handling (used in assignments).
Closes #67
2013-05-11 18:10:21 +01:00
Stephen Dolan 7ca5127fcc Merge branch 'autotools' 2013-05-11 15:21:23 +01:00
Stephen Dolan 7813f363a2 Merge pull request #115 from nicowilliams/complex
Rename complex to nontrivial for safety (#113)
2013-05-08 07:07:31 -07:00
Nicolas Williams fb3c124af1 Rename complex to nontrivial for safety (#113) 2013-05-07 18:46:13 -05:00
Stephen Dolan 46814da91a Merge pull request #119 from 13ren/master
tiny typo fix in manual
2013-05-07 03:57:47 -07:00
13ren d0cd26cd8e Update docs/content/3.manual/manual.yml
There's a , after map ; should be .
#65
2013-01-13 17:33:01 +11:00
201 changed files with 37306 additions and 17602 deletions

No files matched your search

+29
View File
@@ -0,0 +1,29 @@
---
name: Bug report
about: Create a report to help us improve
---
<!--
READ THIS FIRST!
If you have a usage question, please ask us on either Stack Overflow (https://stackoverflow.com/questions/tagged/jq) or in the #jq channel (http://irc.lc/freenode/%23jq/) on Freenode (https://webchat.freenode.net/).
-->
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Provide a minimal test case to reproduce the behavior.
If the input is large, either attach it as a file, or [create a gist](https://gist.github.com) and link to it here.
**Expected behavior**
A clear and concise description of what you expected to happen.
**Environment (please complete the following information):**
- OS and Version: [e.g. macOS, Windows, Linux (please specify distro)]
- jq version [e.g. 1.5]
**Additional context**
Add any other context about the problem here.
+32 -9
View File
@@ -1,28 +1,51 @@
*.o
*.a
*.lo
*.la
*.lai
*.so
*.so.*
*.gcda
*.gcno
*.gcov
*~
.*.sw[a-p]
tags
jq
!tests/modules/lib/jq/
jq.1
# Something delightfully recursive happens otherwise
docs/content/2.download/source/*
# Autogenerated
lexer.c
lexer.h
parser.c
parser.h
# Generated source
src/builtin.inc
# Autotools junk
.libs
.deps
.dirstamp
libtool
*.log
stamp-h1
config.log
config.status
autom4te.cache
config.h
INSTALL
Makefile
jq-*.tar.gz
configure
aclocal.m4
Makefile.in
version.h
.remake-version-h
config.cache
*.rpm
m4/libtool.m4
m4/ltoptions.m4
m4/ltsugar.m4
m4/ltversion.m4
m4/lt~obsolete.m4
tests/*.trs
cscope.in.out
cscope.out
cscope.po.out
+3
View File
@@ -0,0 +1,3 @@
[submodule "modules/oniguruma"]
path = modules/oniguruma
url = https://github.com/kkos/oniguruma.git
+202
View File
@@ -0,0 +1,202 @@
sudo: false
language: c
stages:
- name: test
- name: build
# Don't run build stage for pull requests to save time and resources.
if: type != pull_request
jobs:
include:
# Build with gcc and run tests on Ubuntu.
- &test-ubuntu
stage: test
os: linux
compiler: gcc
addons:
apt:
packages:
- valgrind
- bison
- automake
before_install:
- uname -s
- rvm install ruby-1.9.3-p551
- rvm use 1.9.3
- rm src/{lexer,parser}.{c,h}
- sed -i.bak '/^AM_INIT_AUTOMAKE(\[-Wno-portability 1\.14\])$/s/14/11/' modules/oniguruma/configure.ac
install:
- bundle install --gemfile=docs/Gemfile
- wget http://ftp.debian.org/debian/pool/main/b/bison/bison_3.0.2.dfsg-2_amd64.deb
- ar p bison_3.0.2.dfsg-2_amd64.deb data.tar.xz | tar xJ
- if [ -n "$COVERAGE" ]; then pip install --user cpp-coveralls; fi
before_script:
# If this is OS X we'll get bison from brew, else we'll get bison
# from the .deb unpacked above in the install section.
- PATH=/usr/local/opt/bison/bin:$PWD/usr/bin:$PATH
- echo SHELL=$SHELL
- echo PATH=$PATH
- which bison
- bison --version
- autoreconf -if
- ./configure --with-oniguruma=builtin YACC="$(which bison) -y" $COVERAGE
script:
# When using the bison from Debian we need to tell that bison where
# to find its data. Yay non-relocatable code. Not.
- echo PATH=$PATH
- which bison
- make BISON_PKGDATADIR=$PWD/usr/share/bison src/parser.c || make src/parser.c
# Make dist!
#
# Make it first to fail the build early, before we test with
# valgrind.
- make dist
# Build and test the dist (without valgrind)
- |
(
tar xvf jq-`scripts/version`.tar.gz &&
cd jq-`scripts/version` &&
pwd &&
./configure --disable-valgrind --with-oniguruma=builtin YACC="$(which bison) -y" $COVERAGE &&
make BISON_PKGDATADIR=$PWD/usr/share/bison src/parser.c || make src/parser.c &&
make -j4 &&
make check -j4 || true
)
# Build and test the HEAD
- make -j4
- make check -j4
after_failure:
- cat test-suite.log
- cat tests/*.log
# Build with clang and run tests on Ubuntu.
- <<: *test-ubuntu
compiler: clang
# Build with gcc and run tests with gcov on Ubuntu.
- <<: *test-ubuntu
env: COVERAGE="--disable-valgrind --enable-gcov"
after_script:
- rm -rf src/.libs # don't care about coverage for libjq
- coveralls --gcov-options '\-lp'
-e src/lexer.c -e src/parser.c -e src/jv_dtoa.c
# Build with gcc and run tests on macOS.
- &test-osx
<<: *test-ubuntu
os: osx
before_install:
- uname -s
- brew update
- brew install flex
- brew install bison
- rvm install ruby-1.9.3-p551
- rvm use 1.9.3
- rm src/{lexer,parser}.{c,h}
- sed -i.bak '/^AM_INIT_AUTOMAKE(\[-Wno-portability 1\.14\])$/s/14/11/' modules/oniguruma/configure.ac
install:
- bundle install --gemfile=docs/Gemfile
- if [ -n "$COVERAGE" ]; then pip install --user cpp-coveralls; fi
# Build with clang and run tests on macOS.
- <<: *test-osx
compiler: clang
# Build with gcc and run tests on Alpine Linux v3.7 (inside chroot).
# Note: Alpine uses musl libc.
- &test-alpine
stage: test
os: linux
language: minimal
compiler: gcc
sudo: true
before_install:
- "wget 'https://raw.githubusercontent.com/alpinelinux/alpine-chroot-install/v0.7.0/alpine-chroot-install' \
&& echo '090d323d887ef3a2fd4e752428553f22a52b87bb alpine-chroot-install' | sha1sum -c || travis_terminate 1"
- alpine() { /alpine/enter-chroot -u "$USER" "$@"; }
install:
- sudo sh alpine-chroot-install -b v3.7 -a "$ARCH"
-p 'build-base automake autoconf bison libtool oniguruma-dev'
before_script:
- autoreconf -if
script:
- alpine ./configure --disable-docs
- alpine make
- alpine make check
# Build release binary statically linked with musl libc on Alpine Linux
# (inside chroot). If building a tagged commit, then deploy release
# tarball to GitHub Releases.
- &build-alpine
<<: *test-alpine
stage: build
env: ARCH=x86_64
script:
- alpine ./configure --disable-docs --enable-all-static
CFLAGS='-Os -static -no-pie' CXXFLAGS='-Os -static -no-pie'
- alpine make
- alpine strip jq
- jq -V
- ls -lah jq
- file jq
# Ensure that the built executable is really statically linked.
- file jq | grep -Fw 'statically linked'
before_deploy:
- PKGNAME="jq-$TRAVIS_TAG-$ARCH-linux"
- mkdir $PKGNAME && mv jq $PKGNAME/
- tar -czf $PKGNAME.tar.gz $PKGNAME/
- sha256sum $PKGNAME.tar.gz > $PKGNAME.tar.gz.sha256
deploy:
provider: releases
api_key:
secure: # TODO: put encrypted GitHub token here!
file: jq-$TRAVIS_TAG-*.tar.gz*
file_glob: true
skip_cleanup: true
on:
tags: true
# Build binaries for other architectures using QEMU user-mode emulation.
- <<: *build-alpine
env: ARCH=x86
- <<: *build-alpine
env: ARCH=aarch64
- <<: *build-alpine
env: ARCH=armhf
- <<: *build-alpine
env: ARCH=ppc64le
notifications:
email: false
+71 -3
View File
@@ -1,6 +1,74 @@
Created By:
Stephen Dolan <mu@netsoc.tcd.ie>
Contributions by
Anthony Shortland <anthony.shortland@me.com> - rpmbuild target
Lee Thompson <stagr.lee@gmail.com> - autoconf stuff
Maintained by:
Nicolas Williams <nico@cryptonector.com>
William Langford <wlangfor@gmail.com>
Contributions by:
Aaron Peschel <apeschel@zendesk.com>
Adam Lindberg <hello@alind.io>
Alex Chamberlain <alex@alexchamberlain.co.uk>
Andrew O'Brien <obrien.andrew@gmail.com> - docs build
Andrew Rodland <andrew@cleverdomain.org> - bug fixes
Ankur <ankz.kothari@gmail.com> - bug fixes
Anthony Shortland <anthony.shortland@me.com> - rpmbuild target
Assaf Gordon <assafgordon@gmail.com> - error handling
Brendan Macmillan <melbourne.research@gmail.com> - bug fixes, load library from ~/.jq
cdnbacon <mike@busbud.com>
Charles Merriam <charles.merriam@gmail.com>
Colin von Heuring <colin@janrain.com>
Damian Gryski <damian@gryski.com>
David Fetter <david@fetter.org> - added --rawfile
David Haguenauer <ml@kurokatta.org>
David R. MacIver <david@drmaciver.com> - bug fixes
David Tolnay <dtolnay@gmail.com> - destructuring, build improvements
Doug Luce <doug@github.con.com> - build
Eiichi Sato <sato.eiichi@gmail.com>
Eric Bréchemier <eric@egull.co> - bug fix
Filippo Giunchedi <fgiunchedi@gmail.com> - bug fixes
Filippo Valsorda <filippo.valsorda@gmail.com> - recursive object merge (`*`)
Hanfei Shen <qqshfox@gmail.com>
i <isomorphisms@sdf.org>
Ian Miell <ian.miell@gmail.com>
Jack Pearkes <jackpearkes@gmail.com> - update tutorial
James Andariese <james.andariese@locationlabs.com> - Dockerfile
Jingwen Owen Ou <jingweno@gmail.com> - jqplay.org and link to it
jkleint <jkleint@gmail.com>
Joe Littlejohn <joe.littlejohn@nokia.com> - bug fixes
Joel Purra <code+github@joelpurra.com>
Juan Guerrero <juan.guerrero.lozano@gmail.com> - bug fixes
Kenny Shen <kenny.shen@zalora.com> - doc fixes
Kim De Mey <kim.demey@gmail.com> - build
Kim Toms <kim.toms@bplglobal.net>
LCD 47 <lcd047@gmail.com>
Lee Thompson <stagr.lee@gmail.com> - autoconf stuff, rpm
Marc Abramowitz <marc@marc-abramowitz.com>
Marc Bruggmann <marcbr@spotify.com>
Markus Lanthaler <mark_lanthaler@gmx.net> - doc fixes
Maxime Biais <maxime.biais@gmail.com> - build
Michael Daines <michael@mdaines.com> - add sqrt; doc fixes
Mike Fletcher <john.m.fletcher@bankofamerica.com>
Mike McCabe <mccabe@archive.org> - math (libm) functions
Nicolas Pouillard <nicolas.pouillard@gmail.com> - add tests
Nicolas Williams <nico@cryptonector.com> - library-fication, autoconf stuff, exception handling, various
Peter van Dijk <peter@7bits.nl> - doc fixes
Philipp Hagemeister <phihag@phihag.de> - doc fixes
pkoppstein <pkoppstein@gmail.com> - various builtins, improvements
polyester <paul@cleanclothes.org> - automake version update
Ryoichi KATO <ryo1kato@gmail.com> - doc fixes
Rémy Léone <remy.leone@gmail.com> - add .travis.yml
Santiago Lapresta <santiago.lapresta@gmail.com> - join, arrays, all, any, other filters
Sebastian Freundt <freundt@ga-group.nl> - build
Shaun Guth <shaun.guth@gmail.com> - base64d
Shay Elkin <shay@everything.me>
Simon Elsbrock <simon@iodev.org> - Debian
Stefan Seemayer <stefan@seemayer.de>
Stephen Roantree <stroantree@gmail.com>
Stephen Shaw <stesh@netsoc.tcd.ie>
Steven Maude <StevenMaude@users.noreply.github.com>
Steven Penny <svnpenn@gmail.com> - Windows bug fixes
tal@whatexit.org <tal@whatexit.org>
Travis Gockel <travis@gockelhut.com>
Zhiming Wang <zmwangx@gmail.com>
13ren <melbourne.research@gmail.com>
+3 -3
View File
@@ -25,14 +25,14 @@ jq's documentation (everything found under the docs/ subdirectory in
the source tree) is licensed under the Creative Commons CC BY 3.0
license, which can be found at:
http://creativecommons.org/licenses/by/3.0/
https://creativecommons.org/licenses/by/3.0/
The documentation website includes a copy of Twitter's Boostrap and
relies on Bonsai, Liquid templates and various other projects, look
them up for detailed licensing conditions.
jq incorporates David M. Gay's dtoa.c and g_fmt.c, which bear the
following notices:
+1349
View File
File diff suppressed because it is too large. Load diff
+53
View File
@@ -0,0 +1,53 @@
FROM debian:8
COPY . /app
# get dependencies, build, and remove anything we don't need for running jq.
# valgrind seems to have trouble with pthreads TLS so it's off.
RUN apt-get update && \
apt-get install -y \
build-essential \
autoconf \
libtool \
git \
bison \
flex \
ruby \
wget \
ruby-dev && \
wget https://github.com/kkos/oniguruma/archive/v5.9.6.tar.gz -O onig-5.9.6.tar.gz && \
sha512sum onig-5.9.6.tar.gz | grep 6b048d345e148c9da38af7a8df76d4a358eb3d4db91fa7834076e511f526a63544284f212b0d56badbbd33112c8b458a5fff02bfbbda012ecfe478bc436ea679 && \
tar zxvf onig-5.9.6.tar.gz && \
(cd oniguruma-5.9.6 && \
touch NEWS ChangeLog && \
autoreconf -i && \
./configure --prefix=/usr/local && \
make && \
make install ) && \
gem install bundler && \
(cd /app/docs && bundle install) && \
(cd /app && \
autoreconf -i && \
./configure --disable-valgrind --enable-all-static --prefix=/usr/local && \
make -j8 && \
make check && \
make install && \
make distclean ) && \
(cd oniguruma-5.9.6 && \
make uninstall ) && \
apt-get purge -y \
build-essential \
autoconf \
libtool \
bison \
git \
flex \
ruby \
ruby-dev && \
apt-get autoremove -y && \
rm -rf oniguruma-5.9.6 && \
rm -rf /var/lib/apt/lists/* /var/lib/gems
ENTRYPOINT ["/usr/local/bin/jq"]
CMD []
+8
View File
@@ -0,0 +1,8 @@
pub 4096R/71523402 2015-10-11
Key fingerprint = 4FD7 01D6 FA9B 3D2D F5AC 935D AF19 040C 7152 3402
uid jq Release Signing Key <jq@stedolan.github.io>
pub 2048R/D15684DB 2015-10-12 [expires: 2017-10-11]
Key fingerprint = 7F6C 7BD3 0412 AFD5 8C1A 5007 EB26 A4F8 D156 84DB
uid Nicolas Williams <nico@cryptonector.com>
sub 2048R/9C9CCD6A 2015-10-12 [expires: 2017-10-11]
+148 -58
View File
@@ -1,116 +1,195 @@
### C source files to be built and distributed.
JQ_INCS = jq_parser.h builtin.h bytecode.h compile.h execute.h \
forkable_stack.h frame_layout.h jv.h jv_alloc.h jv_aux.h jv_dtoa.h \
jv_parse.h jv_unicode.h locfile.h opcode.h opcode_list.h parser.y \
jv_utf8_tables.h lexer.l
JQ_SRC = opcode.c bytecode.c compile.c execute.c builtin.c jv.c \
jv_parse.c jv_print.c jv_dtoa.c jv_unicode.c jv_aux.c jv_alloc.c \
jq_test.c ${JQ_INCS}
LIBJQ_INCS = src/builtin.h src/bytecode.h src/compile.h \
src/exec_stack.h src/jq_parser.h src/jv_alloc.h src/jv_dtoa.h \
src/jv_unicode.h src/jv_utf8_tables.h src/lexer.l src/libm.h \
src/linker.h src/locfile.h src/opcode_list.h src/parser.y \
src/util.h
LIBJQ_SRC = src/builtin.c src/bytecode.c src/compile.c src/execute.c \
src/jq_test.c src/jv.c src/jv_alloc.c src/jv_aux.c \
src/jv_dtoa.c src/jv_file.c src/jv_parse.c src/jv_print.c \
src/jv_unicode.c src/linker.c src/locfile.c src/util.c \
${LIBJQ_INCS}
### C build options
AM_CFLAGS = -Wextra -Wall -Wno-missing-field-initializers \
-Wno-unused-parameter -Wno-unused-function
AM_CFLAGS = -Wextra -Wall -Wno-missing-field-initializers \
-Wno-unused-parameter -Wno-unused-function
ACLOCAL_AMFLAGS = -I config/m4
### Generating the lexer and parser
# While there is some autoconf macro support for lex/flex, it doesn't support
# header file creation so we'll use good old make
BUILT_SOURCES = lexer.h lexer.c parser.h parser.c
lexer.c: lexer.l
flex -o lexer.c --header-file=lexer.h $<
lexer.h: lexer.c
if MAINTAINER_MODE
BUILT_SOURCES = src/lexer.h src/lexer.c src/parser.h src/parser.c \
src/builtin.inc src/version.h
src/lexer.c: src/lexer.l
$(AM_V_LEX) flex -o src/lexer.c --header-file=src/lexer.h $<
src/lexer.h: src/lexer.c
else
BUILT_SOURCES = src/builtin.inc src/version.h
.y.c:
$(AM_V_YACC) echo "NOT building parser.c!"
.l.c:
$(AM_V_LEX) echo "NOT building lexer.c!"
endif
# Tell YACC (bison) autoconf macros that you want a header file created.
# If the --warnings=all fails, you probably have an old version of bison
# OSX ships an old bison, so update with homebrew or macports
AM_YFLAGS = --warnings=all -d
### libjq
lib_LTLIBRARIES = libjq.la
libjq_la_SOURCES = ${LIBJQ_SRC}
libjq_la_LIBADD = -lm
libjq_la_LDFLAGS = $(onig_LDFLAGS) -export-symbols-regex '^j[qv]_' -version-info 1:4:0
if WIN32
libjq_la_LIBADD += -lshlwapi
endif
include_HEADERS = src/jv.h src/jq.h
if ENABLE_UBSAN
AM_CFLAGS += -fsanitize=undefined
endif
### Running tests under Valgrind
if ENABLE_ASAN
AM_CFLAGS += -fsanitize=address
NO_VALGRIND = 1
else
if ENABLE_VALGRIND
NO_VALGRIND =
else
NO_VALGRIND = 1
endif
endif
### Code coverage with gcov
if ENABLE_GCOV
AM_CFLAGS += --coverage --no-inline
endif
### Error injection for testing
if ENABLE_ERROR_INJECTION
lib_LTLIBRARIES += libinject_errors.la
libinject_errors_la_SOURCES = src/inject_errors.c
libinject_errors_la_LIBADD = -ldl
libinject_errors_la_LDFLAGS = -module
endif
### Building the jq binary
main.c: config.h
# Remake the version.h header file if, and only if, the git ID has changed
.PHONY: .FORCE
.FORCE:
generate_ver = ver="`{ $(srcdir)/scripts/version || echo '$(VERSION)' ; } | sed 's/.*/\#define JQ_VERSION \"&\"/'`"
.remake-version-h: .FORCE
@ $(generate_ver); test "x`cat src/version.h 2>/dev/null`" = "x$$ver" || touch .remake-version-h
src/version.h: .remake-version-h
$(AM_V_GEN) $(generate_ver); echo "$$ver" > $@
src/main.c: src/version.h
src/builtin.inc: src/builtin.jq
$(AM_V_GEN) sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/\\n"/' $^ > $@
src/builtin.o: src/builtin.inc
bin_PROGRAMS = jq
jq_SOURCES = ${JQ_SRC} main.c
jq_SOURCES = src/main.c src/version.h
jq_LDFLAGS = -static-libtool-libs
jq_LDADD = libjq.la -lm
if WIN32
jq_LDADD += -lshlwapi
endif
if ENABLE_ALL_STATIC
jq_LDFLAGS += -all-static
endif
### Tests (make check)
TESTS = tests/all.test
TEST_LOG_COMPILER = ${srcdir}/tests/run
TESTS = tests/optionaltest tests/mantest tests/jqtest tests/onigtest tests/shtest tests/utf8test tests/base64test
TESTS_ENVIRONMENT = NO_VALGRIND=$(NO_VALGRIND)
### Building the manpage
# If ENABLE_DOCS is not set, just copy jq.1.default to jq.1
# The real_docs target succeeds (possibly after building jq.1) only if ENABLE_DOCS is set
# Thus, making "dist" depend on "real_docs" ensures that we never build a tarball with
# a stub manpage.
man_MANS = jq.1
.PHONY: real_docs
if ENABLE_DOCS
jq.1: $(srcdir)/docs/content/3.manual/manual.yml
( cd ${abs_srcdir}/docs; '$(BUNDLER)' exec rake manpage ) > $@ || { rm -f $@; false; }
jq.1.default: $(srcdir)/docs/default_manpage.md
( cd ${abs_srcdir}/docs; '$(BUNDLER)' exec rake manpage_default ) > $@ || { rm -f $@; false; }
real_docs: jq.1
if cmp jq.1 $(srcdir)/jq.1.default > /dev/null; then\
rm -f jq.1; $(MAKE) $(AM_MAKEFLAGS) jq.1;\
fi
$(AM_V_GEN) ( cd ${abs_srcdir}/docs; '$(BUNDLER)' exec rake manpage ) > $@ || { rm -f $@; false; }
jq.1.prebuilt: jq.1
$(AM_V_GEN) cp $^ $@ || { rm -f $@; false; }
else
jq.1: $(srcdir)/jq.1.default
cp $^ $@
real_docs:
@echo "Ruby dependencies not found, cannot build manpage." > /dev/stderr
@echo "Follow the instructions in docs/README.md to install them" > /dev/stderr
@echo "and then rerun ./configure" > /dev/stderr
false
jq.1: $(srcdir)/jq.1.prebuilt
$(AM_V_GEN) cp $^ $@
endif
### Build oniguruma
if BUILD_ONIGURUMA
libjq_la_LIBADD += modules/oniguruma/src/.libs/libonig.la
SUBDIRS = modules/oniguruma
endif
AM_CFLAGS += $(onig_CFLAGS)
### Packaging
docs/site.yml: configure.ac
sed 's/^jq_version: .*/jq_version: $(VERSION)/' $@ > $@.new
sed 's/^jq_version: .*/jq_version: "$(VERSION)"/' $@ > $@.new
mv $@.new $@
install-binaries: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) install-exec
# Ensure "make dist" fails when we can't build the real manpage
dist-hook: real_docs
DOC_FILES = docs/content docs/public docs/templates docs/site.yml \
docs/Gemfile docs/Gemfile.lock docs/Rakefile docs/README.md \
jq.1.prebuilt
DOC_FILES = docs/content docs/public docs/templates docs/site.yml \
docs/Gemfile docs/Gemfile.lock docs/Rakefile docs/README.md \
docs/default_manpage.md jq.1.default
EXTRA_DIST = $(DOC_FILES) $(man_MANS) $(TESTS) $(TEST_LOG_COMPILER) \
jq.1.prebuilt jq.spec src/lexer.c src/lexer.h src/parser.c \
src/parser.h src/version.h src/builtin.jq \
scripts/version tests/jq.test tests/modules/.jq \
tests/modules/a.jq tests/modules/b/b.jq tests/modules/c/c.jq \
tests/modules/c/d.jq tests/modules/data.json \
tests/modules/lib/jq/e/e.jq tests/modules/lib/jq/f.jq \
tests/modules/syntaxerror/syntaxerror.jq \
tests/modules/test_bind_order.jq \
tests/modules/test_bind_order0.jq \
tests/modules/test_bind_order1.jq \
tests/modules/test_bind_order2.jq tests/onig.supp \
tests/onig.test tests/setup tests/torture/input0.json \
tests/optional.test tests/optionaltest \
tests/utf8-truncate.jq tests/utf8test \
tests/base64.test tests/base64test \
tests/jq-f-test.sh tests/shtest
# setup is only used by distribution developers, not package developers.
# Still, as a matter of allowing patching, its not a bad idea to distribute
# the developer setup script in the tarball.
EXTRA_DIST = config.h.in $(BUILT_SOURCES) $(man_MANS) $(TESTS) \
$(TEST_LOG_COMPILER) gen_utf8_tables.py jq.spec \
$(DOC_FILES)
# README.md is expected in Github projects, good stuff in it, so we'll
# README.md is expected in Github projects, good stuff in it, so we'll
# distribute it and install it with the package in the doc directory.
docdir = ${datadir}/doc/${PACKAGE}
dist_doc_DATA = README.md COPYING AUTHORS README
releasetag:
git tag -s "jq-$$(cat VERSION)" -m "jq release $$(cat VERSION)"
RELEASE ?= 1
rpm: jq
rpm: dist jq.spec
@echo "Packaging jq as an RPM ..."
mkdir -p rpm/SOURCES rpm/BUILD rpm/BUILDROOT rpm/RPMS rpm/SPECS
cp jq-$$(cat VERSION).tar.gz rpm/SOURCES/
rpmbuild -tb --define "_topdir ${PWD}/rpm" --define "_prefix /usr" --define "myver $$(cat VERSION)" --define "myrel ${RELEASE}" rpm/SOURCES/jq-$$(cat VERSION).tar.gz
cp jq-$(VERSION).tar.gz rpm/SOURCES/
rpmbuild -tb --define "_topdir ${PWD}/rpm" --define "_prefix /usr" --define "myver $(VERSION)" --define "myrel ${RELEASE}" rpm/SOURCES/jq-$(VERSION).tar.gz
find rpm/RPMS/ -name "*.rpm" -exec mv {} ./ \;
rm -rf rpm
@@ -119,5 +198,16 @@ dist-clean-local:
# Not sure why this doesn't get cleaned up automatically, guess
# automake used to man pages which are hand coded?
clean-local:
# 'make clean' doesn't delete the manpage if it can't be rebuilt
clean-local-docs:
if ENABLE_DOCS
rm -f jq.1
endif
clean-local-gcov:
rm -f src/*.gcno src/*.gcda src/*.gcov
clean-local: clean-local-docs clean-local-gcov
rm -f src/version.h .remake-version-h
.PHONY: clean-local-docs clean-local-gcov
+89
View File
@@ -0,0 +1,89 @@
Release history
* jq version 1.5 was released on Sat Aug 15 2015
* jq version 1.4 was released on Mon Jun 9 2014
* jq version 1.3 was released on Sun May 19 2013
* jq version 1.2 was released on Thu Dec 20 2012
* jq version 1.1 was released on Sun Oct 21 2012
* jq version 1.0 was released on Sun Oct 21 2012
New features in 1.5 since 1.4:
- regular expressions (with Oniguruma)
- a library/module system
- many new builtins
- datetime builtins
- math builtins
- regexp-related builtins
- stream-related builtins (e.g., all/1, any/1)
- minimal I/O builtins (`inputs`, `debug`)
- new syntactic features, including:
- destructuring (`. as [$first, $second] | ...`)
- try/catch, generalized `?` operator, and label/break
- `foreach`
- multiple definitions of a function with different numbers of
arguments
- command-line arguments
- --join-lines / -j for raw output
- --argjson and --slurpfile
- --tab and --indent
- --stream (streaming JSON parser)
- --seq (RFC7464 JSON text sequence)
- --run-tests improvements
- optimizations:
- tail-call optimization
- reduce and foreach no longer leak a reference to .
New features in 1.4 since 1.3:
- command-line arguments
- jq --arg-file variable file
- jq --unbuffered
- jq -e / --exit-status (set exit status based on outputs)
- jq -S / --sort-keys (now jq no longer sorts object keys by
default
- syntax
- .. -> like // in XPath (recursive traversal)
- question mark (e.g., .a?) to suppress errors
- ."foo" syntax (equivalent to .["foo"])
- better error handling for .foo
- added % operator (modulo)
- allow negation without requiring extra parenthesis
- more function arguments (up to six)
- filters:
- any, all
- iterables, arrays, objects, scalars, nulls, booleans, numbers,
strings, values
- string built-ins:
- split
- join (join an array of strings with a given separator string)
- ltrimstr, rtrimstr
- startswith, endswith
- explode, implode
- fromjson, tojson
- index, rindex, indices
- math functions
- floor, sqrt, cbrt, etetera (depends on what's available from libm)
- libjq -- a C API interface to jq's JSON representation and for
running jq programs from C applications
+59 -9
View File
@@ -1,23 +1,73 @@
jq
==
jq is a command-line JSON processor.
jq is a lightweight and flexible command-line JSON processor.
[![Coverage Status](https://coveralls.io/repos/stedolan/jq/badge.svg?branch=master&service=github)](https://coveralls.io/github/stedolan/jq?branch=master),
Unix: [![Build Status](https://travis-ci.org/stedolan/jq.svg?branch=master)](https://travis-ci.org/stedolan/jq),
Windows: [![Windows build status](https://ci.appveyor.com/api/projects/status/mi816811c9e9mx29?svg=true)](https://ci.appveyor.com/project/stedolan/jq)
If you want to learn to use jq, read the documentation at
[http://stedolan.github.com/jq](http://stedolan.github.com/jq). This
[https://stedolan.github.io/jq](https://stedolan.github.io/jq). This
documentation is generated from the docs/ folder of this repository.
You can also try it online at [jqplay.org](https://jqplay.org).
If you want to hack on jq, feel free, but be warned that its internals
are not well-documented at the moment. Bring a hard hat and a
shovel. Also, read the wiki: http://github.com/stedolan/jq/wiki
shovel. Also, read the wiki: https://github.com/stedolan/jq/wiki, where
you will find cookbooks, discussion of advanced topics, internals,
release engineering, and more.
To build jq, run
Source tarball and built executable releases can be found on the
homepage and on the github release page, https://github.com/stedolan/jq/releases
If you're building directly from the latest git, you'll need flex,
bison (3.0 or newer), libtool, make, and autoconf installed.
To get regexp support you'll also need to install Oniguruma or clone it as a
git submodule as per the instructions below.
(note that jq's tests require regexp support to pass). To build, run:
git submodule update --init # if building from git to get oniguruma
autoreconf -fi # if building from git
./configure --with-oniguruma=builtin
make -j8
make check
To build without bison or flex, add `--disable-maintainer-mode` to the
./configure invocation:
./configure --with-oniguruma=builtin --disable-maintainer-mode
(Developers must not use `--disable-maintainer-mode`, not when making
changes to the jq parser and/or lexer.)
To build a statically linked version of jq, run:
make LDFLAGS=-all-static
After make finishes, you'll be able to use `./jq`. You can also
install it using:
sudo make install
If you're not using the latest git version but instead building a
released tarball (available on the website), then you won't need to
run `autoreconf` (and shouldn't), and you won't need flex or bison.
To cross-compile for OS X and Windows, see docs/Rakefile's build task
and scripts/crosscompile. You'll need a cross-compilation environment,
such as Mingw for cross-compiling for Windows.
Cross-compilation requires a clean workspace, then:
# git clean ...
autoreconf -i
./configure
make
sudo make install (optionally)
make distclean
scripts/crosscompile <name-of-build> <configure-options>
If you've just checked out the latest version from git (rather than
using a released source tarball) then you'll need to run this first:
Use the --host= and --target= ./configure options to select a
cross-compilation environment. See also the wiki.
autoreconf
Send questions to https://stackoverflow.com/questions/tagged/jq or to the #jq channel (http://irc.lc/freenode/%23jq/) on Freenode (https://webchat.freenode.net/).
+53
View File
@@ -0,0 +1,53 @@
environment:
matrix:
- MSYSTEM: MINGW64
PATH: C:\msys64\usr\bin;C:\msys64\mingw64\bin;C:\Windows\System32;C:\Windows;%PATH%
- MSYSTEM: MINGW32
PATH: C:\msys64\usr\bin;C:\msys64\mingw32\bin;C:\Windows\System32;C:\Windows;%PATH%
clone_script:
- bash -lc "git clone -q --branch=$APPVEYOR_REPO_BRANCH https://github.com/${APPVEYOR_REPO_NAME}.git $APPVEYOR_BUILD_FOLDER"
- bash -lc "cd $APPVEYOR_BUILD_FOLDER && git checkout -qf $APPVEYOR_REPO_BRANCH"
- bash -lc "cd $APPVEYOR_BUILD_FOLDER && git submodule update --init --recursive"
install:
# update mysy2
- C:\msys64\usr\bin\bash -lc "pacman --needed --noconfirm -Sy pacman-mirrors"
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Sy"
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S autoconf automake bison flex"
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S git"
build_script:
- bash -lc "exec 0</dev/null && cd $APPVEYOR_BUILD_FOLDER && autoreconf -i"
- bash -lc "exec 0</dev/null && cd $APPVEYOR_BUILD_FOLDER && ./configure --with-oniguruma=builtin --disable-shared --enable-static --enable-all-static"
- bash -lc "exec 0</dev/null && cd $APPVEYOR_BUILD_FOLDER && make -j8"
- bash -lc "exec 0</dev/null && cd $APPVEYOR_BUILD_FOLDER && cat jq.1 | groff -mandoc -Thtml > jq.html"
- 7z a jq-package.zip jq.1 jq.html jq.exe
- bash -lc "exec 0</dev/null && cd $APPVEYOR_BUILD_FOLDER && pwd && ls -la"
- file jq.exe
test_script:
# tests/optionaltest and tests/shtest fail on Windows; run them
# anyways but ignore their failures. Also, trace shtest.
- bash -lc "exec 0</dev/null && cd $APPVEYOR_BUILD_FOLDER && make -j3 SUBDIRS= 'TESTS=tests/mantest tests/jqtest tests/onigtest tests/base64test' check"
- bash -lc "exec 0</dev/null && cd $APPVEYOR_BUILD_FOLDER && make SUBDIRS= TESTS=tests/optionaltest check || true"
- bash -lc "exec 0</dev/null && cd $APPVEYOR_BUILD_FOLDER && make SUBDIRS= TRACE_TESTS=1 TESTS=tests/shtest check || true"
artifacts:
- path: jq-package.zip
name: jq-package
- path: jq.exe
name: jq-exe
- path: test-suite.log
name: logs
on_failure:
- cat config.log
- cat test-suite.log
- appveyor PushArtifact test-suite.log
# also push the jq.exe so that someone can download it anyways...
- appveyor PushArtifact jq-package.zip
-565
View File
@@ -1,565 +0,0 @@
#include <string.h>
#include "builtin.h"
#include "compile.h"
#include "jq_parser.h"
#include "locfile.h"
#include "jv_aux.h"
#include "jv_unicode.h"
typedef jv (*func_1)(jv);
typedef jv (*func_2)(jv,jv);
typedef jv (*func_3)(jv,jv,jv);
typedef jv (*func_4)(jv,jv,jv,jv);
typedef jv (*func_5)(jv,jv,jv,jv,jv);
jv cfunction_invoke(struct cfunction* function, jv input[]) {
switch (function->nargs) {
case 1: return ((func_1)function->fptr)(input[0]);
case 2: return ((func_2)function->fptr)(input[0], input[1]);
case 3: return ((func_3)function->fptr)(input[0], input[1], input[2]);
case 4: return ((func_4)function->fptr)(input[0], input[1], input[2], input[3]);
case 5: return ((func_5)function->fptr)(input[0], input[1], input[2], input[3], input[4]);
default: return jv_invalid_with_msg(jv_string("Function takes too many arguments"));
}
}
static jv type_error(jv bad, const char* msg) {
jv err = jv_invalid_with_msg(jv_string_fmt("%s %s",
jv_kind_name(jv_get_kind(bad)),
msg));
jv_free(bad);
return err;
}
static jv type_error2(jv bad1, jv bad2, const char* msg) {
jv err = jv_invalid_with_msg(jv_string_fmt("%s and %s %s",
jv_kind_name(jv_get_kind(bad1)),
jv_kind_name(jv_get_kind(bad2)),
msg));
jv_free(bad1);
jv_free(bad2);
return err;
}
static jv f_plus(jv input, jv a, jv b) {
jv_free(input);
if (jv_get_kind(a) == JV_KIND_NULL) {
jv_free(a);
return b;
} else if (jv_get_kind(b) == JV_KIND_NULL) {
jv_free(b);
return a;
} else if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) {
return jv_number(jv_number_value(a) +
jv_number_value(b));
} else if (jv_get_kind(a) == JV_KIND_STRING && jv_get_kind(b) == JV_KIND_STRING) {
return jv_string_concat(a, b);
} else if (jv_get_kind(a) == JV_KIND_ARRAY && jv_get_kind(b) == JV_KIND_ARRAY) {
return jv_array_concat(a, b);
} else if (jv_get_kind(a) == JV_KIND_OBJECT && jv_get_kind(b) == JV_KIND_OBJECT) {
return jv_object_merge(a, b);
} else {
return type_error2(a, b, "cannot be added");
}
}
static jv f_negate(jv input) {
if (jv_get_kind(input) != JV_KIND_NUMBER) {
return type_error(input, "cannot be negated");
}
jv ret = jv_number(-jv_number_value(input));
jv_free(input);
return ret;
}
static jv f_minus(jv input, jv a, jv b) {
jv_free(input);
if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) {
return jv_number(jv_number_value(a) - jv_number_value(b));
} else if (jv_get_kind(a) == JV_KIND_ARRAY && jv_get_kind(b) == JV_KIND_ARRAY) {
jv out = jv_array();
jv_array_foreach(a, i, x) {
int include = 1;
jv_array_foreach(b, j, y) {
if (jv_equal(jv_copy(x), y)) {
include = 0;
break;
}
}
if (include)
out = jv_array_append(out, jv_copy(x));
jv_free(x);
}
jv_free(a);
jv_free(b);
return out;
} else {
return type_error2(a, b, "cannot be subtracted");
}
}
static jv f_multiply(jv input, jv a, jv b) {
jv_free(input);
if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) {
return jv_number(jv_number_value(a) * jv_number_value(b));
} else {
return type_error2(a, b, "cannot be multiplied");
}
}
static jv f_divide(jv input, jv a, jv b) {
jv_free(input);
if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) {
return jv_number(jv_number_value(a) / jv_number_value(b));
} else {
return type_error2(a, b, "cannot be divided");
}
}
static jv f_equal(jv input, jv a, jv b) {
jv_free(input);
return jv_bool(jv_equal(a, b));
}
static jv f_notequal(jv input, jv a, jv b) {
jv_free(input);
return jv_bool(!jv_equal(a, b));
}
enum cmp_op {
CMP_OP_LESS,
CMP_OP_GREATER,
CMP_OP_LESSEQ,
CMP_OP_GREATEREQ
};
static jv order_cmp(jv input, jv a, jv b, enum cmp_op op) {
jv_free(input);
int r = jv_cmp(a, b);
return jv_bool((op == CMP_OP_LESS && r < 0) ||
(op == CMP_OP_LESSEQ && r <= 0) ||
(op == CMP_OP_GREATEREQ && r >= 0) ||
(op == CMP_OP_GREATER && r > 0));
}
static jv f_less(jv input, jv a, jv b) {
return order_cmp(input, a, b, CMP_OP_LESS);
}
static jv f_greater(jv input, jv a, jv b) {
return order_cmp(input, a, b, CMP_OP_GREATER);
}
static jv f_lesseq(jv input, jv a, jv b) {
return order_cmp(input, a, b, CMP_OP_LESSEQ);
}
static jv f_greatereq(jv input, jv a, jv b) {
return order_cmp(input, a, b, CMP_OP_GREATEREQ);
}
static jv f_contains(jv a, jv b) {
if (jv_get_kind(a) == jv_get_kind(b)) {
return jv_bool(jv_contains(a, b));
} else {
return type_error2(a, b, "cannot have their containment checked");
}
}
static jv f_tonumber(jv input) {
if (jv_get_kind(input) == JV_KIND_NUMBER) {
return input;
}
if (jv_get_kind(input) == JV_KIND_STRING) {
jv parsed = jv_parse(jv_string_value(input));
if (!jv_is_valid(parsed) || jv_get_kind(parsed) == JV_KIND_NUMBER) {
jv_free(input);
return parsed;
}
}
return type_error(input, "cannot be parsed as a number");
}
static jv f_length(jv input) {
if (jv_get_kind(input) == JV_KIND_ARRAY) {
return jv_number(jv_array_length(input));
} else if (jv_get_kind(input) == JV_KIND_OBJECT) {
return jv_number(jv_object_length(input));
} else if (jv_get_kind(input) == JV_KIND_STRING) {
return jv_number(jv_string_length(input));
} else if (jv_get_kind(input) == JV_KIND_NULL) {
jv_free(input);
return jv_number(0);
} else {
return type_error(input, "has no length");
}
}
static jv f_tostring(jv input) {
if (jv_get_kind(input) == JV_KIND_STRING) {
return input;
} else {
return jv_dump_string(input, 0);
}
}
#define CHARS_ALPHANUM "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
static jv escape_string(jv input, const char* escapings) {
assert(jv_get_kind(input) == JV_KIND_STRING);
const char* lookup[128] = {0};
const char* p = escapings;
while (*p) {
lookup[(int)*p] = p+1;
p++;
p += strlen(p);
p++;
}
jv ret = jv_string("");
const char* i = jv_string_value(input);
const char* end = i + jv_string_length(jv_copy(input));
const char* cstart;
int c = 0;
while ((i = jvp_utf8_next((cstart = i), end, &c))) {
assert(c != -1);
if (c < 128 && lookup[c]) {
ret = jv_string_append_str(ret, lookup[c]);
} else {
ret = jv_string_append_buf(ret, cstart, i - cstart);
}
}
jv_free(input);
return ret;
}
static jv f_format(jv input, jv fmt) {
if (jv_get_kind(fmt) != JV_KIND_STRING) {
jv_free(input);
return type_error(fmt, "is not a valid format");
}
const char* fmt_s = jv_string_value(fmt);
if (!strcmp(fmt_s, "json")) {
jv_free(fmt);
return jv_dump_string(input, 0);
} else if (!strcmp(fmt_s, "text")) {
jv_free(fmt);
return f_tostring(input);
} else if (!strcmp(fmt_s, "csv")) {
jv_free(fmt);
if (jv_get_kind(input) != JV_KIND_ARRAY)
return type_error(input, "cannot be csv-formatted, only array");
jv line = jv_string("");
jv_array_foreach(input, i, x) {
if (i) line = jv_string_append_str(line, ",");
switch (jv_get_kind(x)) {
case JV_KIND_NULL:
/* null rendered as empty string */
jv_free(x);
break;
case JV_KIND_TRUE:
case JV_KIND_FALSE:
line = jv_string_concat(line, jv_dump_string(x, 0));
break;
case JV_KIND_NUMBER:
if (jv_number_value(x) != jv_number_value(x)) {
/* NaN, render as empty string */
jv_free(x);
} else {
line = jv_string_concat(line, jv_dump_string(x, 0));
}
break;
case JV_KIND_STRING: {
line = jv_string_append_str(line, "\"");
line = jv_string_concat(line, escape_string(x, "\"\"\"\0"));
line = jv_string_append_str(line, "\"");
break;
}
default:
jv_free(input);
jv_free(line);
return type_error(x, "is not valid in a csv row");
}
}
jv_free(input);
return line;
} else if (!strcmp(fmt_s, "html")) {
jv_free(fmt);
return escape_string(f_tostring(input), "&&amp;\0<&lt;\0>&gt;\0'&apos;\0\"&quot;\0");
} else if (!strcmp(fmt_s, "uri")) {
jv_free(fmt);
input = f_tostring(input);
int unreserved[128] = {0};
const char* p = CHARS_ALPHANUM "-_.!~*'()";
while (*p) unreserved[(int)*p++] = 1;
jv line = jv_string("");
const char* s = jv_string_value(input);
for (int i=0; i<jv_string_length(jv_copy(input)); i++) {
unsigned ch = (unsigned)(unsigned char)*s;
if (ch < 128 && unreserved[ch]) {
line = jv_string_append_buf(line, s, 1);
} else {
line = jv_string_concat(line, jv_string_fmt("%%%02x", ch));
}
s++;
}
jv_free(input);
return line;
} else if (!strcmp(fmt_s, "sh")) {
jv_free(fmt);
if (jv_get_kind(input) != JV_KIND_ARRAY)
input = jv_array_set(jv_array(), 0, input);
jv line = jv_string("");
jv_array_foreach(input, i, x) {
if (i) line = jv_string_append_str(line, " ");
switch (jv_get_kind(x)) {
case JV_KIND_NULL:
case JV_KIND_TRUE:
case JV_KIND_FALSE:
case JV_KIND_NUMBER:
line = jv_string_concat(line, jv_dump_string(x, 0));
break;
case JV_KIND_STRING: {
line = jv_string_append_str(line, "'");
line = jv_string_concat(line, escape_string(x, "''\\''\0"));
line = jv_string_append_str(line, "'");
break;
}
default:
jv_free(input);
jv_free(line);
return type_error(x, "can not be escaped for shell");
}
}
jv_free(input);
return line;
} else if (!strcmp(fmt_s, "base64")) {
jv_free(fmt);
input = f_tostring(input);
jv line = jv_string("");
const char b64[64 + 1] = CHARS_ALPHANUM "+/";
const char* data = jv_string_value(input);
int len = jv_string_length(jv_copy(input));
for (int i=0; i<len; i+=3) {
uint32_t code = 0;
int n = len - i >= 3 ? 3 : len-i;
for (int j=0; j<3; j++) {
code <<= 8;
code |= j < n ? (unsigned)data[i+j] : 0;
}
char buf[4];
for (int j=0; j<4; j++) {
buf[j] = b64[(code >> (18 - j*6)) & 0x3f];
}
if (n < 3) buf[3] = '=';
if (n < 2) buf[2] = '=';
line = jv_string_append_buf(line, buf, sizeof(buf));
}
jv_free(input);
return line;
} else {
jv_free(input);
return jv_invalid_with_msg(jv_string_concat(fmt, jv_string(" is not a valid format")));
}
}
static jv f_keys(jv input) {
if (jv_get_kind(input) == JV_KIND_OBJECT || jv_get_kind(input) == JV_KIND_ARRAY) {
return jv_keys(input);
} else {
return type_error(input, "has no keys");
}
}
static jv f_sort(jv input){
if (jv_get_kind(input) == JV_KIND_ARRAY) {
return jv_sort(input, jv_copy(input));
} else {
return type_error(input, "cannot be sorted, as it is not an array");
}
}
static jv f_sort_by_impl(jv input, jv keys) {
if (jv_get_kind(input) == JV_KIND_ARRAY &&
jv_get_kind(keys) == JV_KIND_ARRAY &&
jv_array_length(jv_copy(input)) == jv_array_length(jv_copy(keys))) {
return jv_sort(input, keys);
} else {
return type_error2(input, keys, "cannot be sorted, as they are not both arrays");
}
}
static jv f_group_by_impl(jv input, jv keys) {
if (jv_get_kind(input) == JV_KIND_ARRAY &&
jv_get_kind(keys) == JV_KIND_ARRAY &&
jv_array_length(jv_copy(input)) == jv_array_length(jv_copy(keys))) {
return jv_group(input, keys);
} else {
return type_error2(input, keys, "cannot be sorted, as they are not both arrays");
}
}
static jv minmax_by(jv values, jv keys, int is_min) {
if (jv_get_kind(values) != JV_KIND_ARRAY)
return type_error2(values, keys, "cannot be iterated over");
if (jv_get_kind(keys) != JV_KIND_ARRAY)
return type_error2(values, keys, "cannot be iterated over");
if (jv_array_length(jv_copy(values)) != jv_array_length(jv_copy(keys)))
return type_error2(values, keys, "have wrong length");
if (jv_array_length(jv_copy(values)) == 0) {
jv_free(values);
jv_free(keys);
return jv_null();
}
jv ret = jv_array_get(jv_copy(values), 0);
jv retkey = jv_array_get(jv_copy(keys), 0);
for (int i=1; i<jv_array_length(jv_copy(values)); i++) {
jv item = jv_array_get(jv_copy(keys), i);
int cmp = jv_cmp(jv_copy(item), jv_copy(retkey));
if ((cmp < 0) == (is_min == 1)) {
jv_free(retkey);
retkey = item;
jv_free(ret);
ret = jv_array_get(jv_copy(values), i);
} else {
jv_free(item);
}
}
jv_free(values);
jv_free(keys);
jv_free(retkey);
return ret;
}
static jv f_min(jv x) {
return minmax_by(x, jv_copy(x), 1);
}
static jv f_max(jv x) {
return minmax_by(x, jv_copy(x), 0);
}
static jv f_min_by_impl(jv x, jv y) {
return minmax_by(x, y, 1);
}
static jv f_max_by_impl(jv x, jv y) {
return minmax_by(x, y, 0);
}
static jv f_type(jv input) {
jv out = jv_string(jv_kind_name(jv_get_kind(input)));
jv_free(input);
return out;
}
static jv f_error(jv input, jv msg) {
jv_free(input);
msg = f_tostring(msg);
return jv_invalid_with_msg(msg);
}
static const struct cfunction function_list[] = {
{(cfunction_ptr)f_plus, "_plus", 3},
{(cfunction_ptr)f_negate, "_negate", 1},
{(cfunction_ptr)f_minus, "_minus", 3},
{(cfunction_ptr)f_multiply, "_multiply", 3},
{(cfunction_ptr)f_divide, "_divide", 3},
{(cfunction_ptr)f_tonumber, "tonumber", 1},
{(cfunction_ptr)f_tostring, "tostring", 1},
{(cfunction_ptr)f_keys, "keys", 1},
{(cfunction_ptr)jv_setpath, "setpath", 3}, // FIXME typechecking
{(cfunction_ptr)jv_getpath, "getpath", 2},
{(cfunction_ptr)jv_delpaths, "delpaths", 2},
{(cfunction_ptr)jv_has, "has", 2},
{(cfunction_ptr)f_equal, "_equal", 3},
{(cfunction_ptr)f_notequal, "_notequal", 3},
{(cfunction_ptr)f_less, "_less", 3},
{(cfunction_ptr)f_greater, "_greater", 3},
{(cfunction_ptr)f_lesseq, "_lesseq", 3},
{(cfunction_ptr)f_greatereq, "_greatereq", 3},
{(cfunction_ptr)f_contains, "contains", 2},
{(cfunction_ptr)f_length, "length", 1},
{(cfunction_ptr)f_type, "type", 1},
{(cfunction_ptr)f_sort, "sort", 1},
{(cfunction_ptr)f_sort_by_impl, "_sort_by_impl", 2},
{(cfunction_ptr)f_group_by_impl, "_group_by_impl", 2},
{(cfunction_ptr)f_min, "min", 1},
{(cfunction_ptr)f_max, "max", 1},
{(cfunction_ptr)f_min_by_impl, "_min_by_impl", 2},
{(cfunction_ptr)f_max_by_impl, "_max_by_impl", 2},
{(cfunction_ptr)f_error, "error", 2},
{(cfunction_ptr)f_format, "format", 2},
};
struct bytecoded_builtin { const char* name; block code; };
static block bind_bytecoded_builtins(block b) {
block builtins = gen_noop();
{
struct bytecoded_builtin builtin_defs[] = {
{"empty", gen_op_simple(BACKTRACK)},
{"false", gen_const(jv_false())},
{"true", gen_const(jv_true())},
{"null", gen_const(jv_null())},
{"not", gen_condbranch(gen_const(jv_false()),
gen_const(jv_true()))}
};
for (unsigned i=0; i<sizeof(builtin_defs)/sizeof(builtin_defs[0]); i++) {
builtins = BLOCK(builtins, gen_function(builtin_defs[i].name, gen_noop(),
builtin_defs[i].code));
}
}
{
struct bytecoded_builtin builtin_def_1arg[] = {
{"path", BLOCK(gen_op_simple(DUP),
gen_call("arg", gen_noop()),
gen_op_simple(GETPATH))},
};
for (unsigned i=0; i<sizeof(builtin_def_1arg)/sizeof(builtin_def_1arg[0]); i++) {
builtins = BLOCK(builtins, gen_function(builtin_def_1arg[i].name,
gen_op_block_unbound(CLOSURE_PARAM, "arg"),
builtin_def_1arg[i].code));
}
}
return block_bind(builtins, b, OP_IS_CALL_PSEUDO);
}
static const char* const jq_builtins[] = {
"def map(f): [.[] | f];",
"def select(f): if f then . else empty end;",
"def sort_by(f): _sort_by_impl(map([f]));",
"def group_by(f): _group_by_impl(map([f]));",
"def unique: group_by(.) | map(.[0]);",
"def max_by(f): _max_by_impl(map([f]));",
"def min_by(f): _min_by_impl(map([f]));",
"def add: fold null as $sum (.[] | $sum + .);",
"def del(f): delpaths([path(f)]);",
"def _assign(paths; value): value as $v | fold . as $obj (path(paths) as $p | $obj | setpath($p; $v));",
"def _modify(paths; update): fold . as $obj (path(paths) as $p | $obj | setpath($p; getpath($p) | update));",
"def recurse(f): ., (f | select(. != null) | recurse(f));",
};
block builtins_bind(block b) {
for (int i=(int)(sizeof(jq_builtins)/sizeof(jq_builtins[0]))-1; i>=0; i--) {
struct locfile src;
locfile_init(&src, jq_builtins[i], strlen(jq_builtins[i]));
block funcs;
int nerrors = jq_parse_library(&src, &funcs);
assert(!nerrors);
b = block_bind(funcs, b, OP_IS_CALL_PSEUDO);
locfile_free(&src);
}
b = bind_bytecoded_builtins(b);
return gen_cbinding(function_list, sizeof(function_list)/sizeof(function_list[0]), b);
}
-21
View File
@@ -1,21 +0,0 @@
#ifndef BUILTIN_H
#define BUILTIN_H
#include "compile.h"
block builtins_bind(block);
typedef void (*cfunction_ptr)(void);
struct cfunction {
cfunction_ptr fptr;
const char* name;
int nargs;
};
jv cfunction_invoke(struct cfunction* function, jv input[]);
#endif
-89
View File
@@ -1,89 +0,0 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "bytecode.h"
#include "opcode.h"
#include "jv_alloc.h"
static int bytecode_operation_length(uint16_t* codeptr) {
int length = opcode_describe(*codeptr)->length;
if (*codeptr == CALL_JQ) {
length += codeptr[1] * 2;
}
return length;
}
void dump_disassembly(int indent, struct bytecode* bc) {
if (bc->nclosures > 0) {
printf("%*s[params: %d]\n", indent, "", bc->nclosures);
}
dump_code(indent, bc);
for (int i=0; i<bc->nsubfunctions; i++) {
printf("%*ssubfn[%d]:\n", indent, "", i);
dump_disassembly(indent+2, bc->subfunctions[i]);
}
}
void dump_code(int indent, struct bytecode* bc) {
int pc = 0;
while (pc < bc->codelen) {
printf("%*s", indent, "");
dump_operation(bc, bc->code + pc);
printf("\n");
pc += bytecode_operation_length(bc->code + pc);
}
}
void dump_operation(struct bytecode* bc, uint16_t* codeptr) {
int pc = codeptr - bc->code;
printf("%04d ", pc);
const struct opcode_description* op = opcode_describe(bc->code[pc++]);
printf("%s", op->name);
if (op->length > 1) {
uint16_t imm = bc->code[pc++];
if (op->op == CALL_JQ) {
for (int i=0; i<imm+1; i++) {
uint16_t level = bc->code[pc++];
uint16_t idx = bc->code[pc++];
if (idx & ARG_NEWCLOSURE) {
printf(" subfn[%d]", idx & ~ARG_NEWCLOSURE);
} else {
printf(" param[%d]", idx);
}
if (level) {
printf("^%d", level);
}
}
} else if (op->flags & OP_HAS_BRANCH) {
printf(" %04d", pc + imm);
} else if (op->flags & OP_HAS_CONSTANT) {
printf(" ");
jv_dump(jv_array_get(jv_copy(bc->constants), imm), 0);
} else if (op->flags & OP_HAS_VARIABLE) {
uint16_t v = bc->code[pc++];
printf(" v%d", v);
if (imm) {
printf("^%d", imm);
}
} else {
printf(" %d", imm);
}
}
}
void symbol_table_free(struct symbol_table* syms) {
jv_mem_free(syms->cfunctions);
jv_mem_free(syms);
}
void bytecode_free(struct bytecode* bc) {
jv_mem_free(bc->code);
jv_free(bc->constants);
for (int i=0; i<bc->nsubfunctions; i++)
bytecode_free(bc->subfunctions[i]);
if (!bc->parent)
symbol_table_free(bc->globals);
jv_mem_free(bc->subfunctions);
jv_mem_free(bc);
}
-45
View File
@@ -1,45 +0,0 @@
#ifndef BYTECODE_H
#define BYTECODE_H
#include <stdint.h>
#include "jv.h"
#include "opcode.h"
#include "builtin.h"
#define MAX_CFUNCTION_ARGS 10
struct symbol_table {
struct cfunction* cfunctions;
int ncfunctions;
};
// The bytecode format matters in:
// execute.c - interpreter
// compile.c - compiler
// bytecode.c - disassembler
#define ARG_NEWCLOSURE 0x1000
struct bytecode {
uint16_t* code;
int codelen;
int nlocals;
int nclosures;
jv constants; // JSON array of constants
struct symbol_table* globals;
struct bytecode** subfunctions;
int nsubfunctions;
struct bytecode* parent;
};
void dump_disassembly(int, struct bytecode* code);
void dump_code(int, struct bytecode* code);
void dump_operation(struct bytecode* bc, uint16_t* op);
void symbol_table_free(struct symbol_table* syms);
void bytecode_free(struct bytecode* bc);
#endif
Executable
+102
View File
@@ -0,0 +1,102 @@
#!/bin/bash
# old values
OLD_CFLAGS=$CFLAGS
OLD_LDFLAGS=$LDFLAGS
ORIG_PWD=`pwd`
# For parallelism in make
NJOBS="-j`sysctl -n hw.ncpu || echo 1`"
# Get oniguruma
rm -rf $PWD/build/ios oniguruma-5.9.6
echo "Downloading oniguruma 5.9.6"
curl -L https://github.com/kkos/oniguruma/archive/v5.9.6.tar.gz | tar xz
cd oniguruma-5.9.6
# So, we need to remake the configure scripts so that the arm64 architecture
# exists in config.sub. In order to keep autoreconf from failing, create
# NEWS and ChangeLog.
touch NEWS ChangeLog
autoreconf -fi >/dev/null 2>&1
CC=`xcrun -f clang`
cd $ORIG_PWD
autoreconf -fi
for arch in i386 x86_64 armv7 armv7s arm64; do
# Some of the architectures are a bit different...
if [[ "$arch" = "i386" || "$arch" = "x86_64" ]]
then
SYSROOT=`xcrun -f --sdk iphonesimulator --show-sdk-path`
else
SYSROOT=`xcrun -f --sdk iphoneos --show-sdk-path`
fi
if [[ "$arch" = "arm64" ]]
then
HOST="aarch64-apple-darwin"
else
HOST="$arch-apple-darwin"
fi
CFLAGS="-arch $arch -miphoneos-version-min=6.0 -isysroot $SYSROOT $OLD_CFLAGS"
LDFLAGS="-arch $arch -miphoneos-version-min=6.0 -isysroot $SYSROOT $OLD_LDFLAGS"
# Build oniguruma for this architecture
cd oniguruma-5.9.6
CC=$CC CFLAGS=$CFLAGS LDFLAGS=$LDFLAGS ./configure --disable-shared --enable-static --host=$HOST --prefix=$ORIG_PWD/build/ios/$arch
STATUS=$?
if [ $STATUS -ne 0 ]
then
echo "Failed to configure oniguruma for architecture $arch. Check `pwd`/config.log for details."
cd $PWD
exit $STATUS
fi
make clean
make $NJBOS install
STATUS=$?
if [ $STATUS -ne 0 ]
then
echo "Failed to make oniguruma for architecture $arch."
cd $PWD
exit $STATUS
fi
# Build jq for this architecture
cd $ORIG_PWD
CC=$CC CFLAGS=$CFLAGS LDFLAGS=$LDFLAGS ./configure --disable-shared --enable-static -host=$HOST --prefix=$ORIG_PWD/build/ios/$arch --with-oniguruma=$ORIG_PWD/build/ios/$arch
STATUS=$?
if [ $STATUS -ne 0 ]
then
echo "Failed to configure jq for architecture $arch"
exit $STATUS
fi
make clean
make $NJOBS install
STATUS=$?
if [ $STATUS -ne 0 ]
then
echo "Failed to make jq for architecture $arch"
exit $STATUS
fi
done
# lipo together the different architectures into a universal 'fat' file
lipo -create -output $ORIG_PWD/build/ios/libonig.a $ORIG_PWD/build/ios/{i386,x86_64,armv7,armv7s,arm64}/lib/libonig.a
lipo -create -output $ORIG_PWD/build/ios/libjq.a $ORIG_PWD/build/ios/{i386,x86_64,armv7,armv7s,arm64}/lib/libjq.a
# copy the products into the destination directory and clean up the single-architecture files.
cp $ORIG_PWD/build/ios/i386/include/*.h $ORIG_PWD/build/ios/
rm -rf $ORIG_PWD/build/ios/{i386,x86_64,armv7,armv7s,arm64}
echo "Products are in $ORIG_PWD/build/ios"
-646
View File
@@ -1,646 +0,0 @@
#define _GNU_SOURCE // for strdup
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include "opcode.h"
#include "compile.h"
#include "bytecode.h"
#include "locfile.h"
#include "jv_alloc.h"
/*
The intermediate representation for jq filters is as a sequence of
struct inst, which form a doubly-linked list via the next and prev
pointers.
A "block" represents a sequence of "struct inst", which may be
empty.
Blocks are generated by the parser bottom-up, so may have free
variables (refer to things not defined). See inst.bound_by and
inst.symbol.
*/
struct inst {
struct inst* next;
struct inst* prev;
opcode op;
struct {
uint16_t intval;
struct inst* target;
jv constant;
const struct cfunction* cfunc;
} imm;
location source;
// Binding
// An instruction requiring binding (for parameters/variables/functions)
// is in one of three states:
// inst->bound_by = NULL - Unbound free variable
// inst->bound_by = inst - This instruction binds a variable
// inst->bound_by = other - Uses variable bound by other instruction
// Unbound instructions (references to other things that may or may not
// exist) are created by "gen_foo_unbound", and bindings are created by
// block_bind(definition, body), which binds all instructions in
// body which are unboudn and refer to "definition" by name.
struct inst* bound_by;
char* symbol;
block subfn; // used by CLOSURE_CREATE (body of function)
block arglist; // used by CLOSURE_CREATE (formals) and CALL_JQ (arguments)
// This instruction is compiled as part of which function?
// (only used during block_compile)
struct bytecode* compiled;
int bytecode_pos; // position just after this insn
};
static inst* inst_new(opcode op) {
inst* i = jv_mem_alloc(sizeof(inst));
i->next = i->prev = 0;
i->op = op;
i->bytecode_pos = -1;
i->bound_by = 0;
i->symbol = 0;
i->subfn = gen_noop();
i->arglist = gen_noop();
i->source = UNKNOWN_LOCATION;
return i;
}
static void inst_free(struct inst* i) {
jv_mem_free(i->symbol);
block_free(i->subfn);
block_free(i->arglist);
if (opcode_describe(i->op)->flags & OP_HAS_CONSTANT) {
jv_free(i->imm.constant);
}
jv_mem_free(i);
}
static block inst_block(inst* i) {
block b = {i,i};
return b;
}
static int block_is_single(block b) {
return b.first && b.first == b.last;
}
static inst* block_take(block* b) {
if (b->first == 0) return 0;
inst* i = b->first;
if (i->next) {
i->next->prev = 0;
b->first = i->next;
i->next = 0;
} else {
b->first = 0;
b->last = 0;
}
return i;
}
block gen_location(location loc, block b) {
for (inst* i = b.first; i; i = i->next) {
if (i->source.start == UNKNOWN_LOCATION.start &&
i->source.end == UNKNOWN_LOCATION.end) {
i->source = loc;
}
}
return b;
}
block gen_noop() {
block b = {0,0};
return b;
}
block gen_op_simple(opcode op) {
assert(opcode_describe(op)->length == 1);
return inst_block(inst_new(op));
}
block gen_const(jv constant) {
assert(opcode_describe(LOADK)->flags & OP_HAS_CONSTANT);
inst* i = inst_new(LOADK);
i->imm.constant = constant;
return inst_block(i);
}
block gen_op_target(opcode op, block target) {
assert(opcode_describe(op)->flags & OP_HAS_BRANCH);
assert(target.last);
inst* i = inst_new(op);
i->imm.target = target.last;
return inst_block(i);
}
block gen_op_targetlater(opcode op) {
assert(opcode_describe(op)->flags & OP_HAS_BRANCH);
inst* i = inst_new(op);
i->imm.target = 0;
return inst_block(i);
}
void inst_set_target(block b, block target) {
assert(block_is_single(b));
assert(opcode_describe(b.first->op)->flags & OP_HAS_BRANCH);
assert(target.last);
b.first->imm.target = target.last;
}
block gen_op_var_unbound(opcode op, const char* name) {
assert(opcode_describe(op)->flags & OP_HAS_VARIABLE);
inst* i = inst_new(op);
i->symbol = strdup(name);
return inst_block(i);
}
block gen_op_var_bound(opcode op, block binder) {
assert(block_is_single(binder));
block b = gen_op_var_unbound(op, binder.first->symbol);
b.first->bound_by = binder.first;
return b;
}
block gen_op_block_unbound(opcode op, const char* name) {
assert(opcode_describe(op)->flags & OP_IS_CALL_PSEUDO);
inst* i = inst_new(op);
i->symbol = strdup(name);
return inst_block(i);
}
block gen_op_block_bound(opcode op, block binder) {
assert(block_is_single(binder));
block b = gen_op_block_unbound(op, binder.first->symbol);
b.first->bound_by = binder.first;
return b;
}
static void inst_join(inst* a, inst* b) {
assert(a && b);
assert(!a->next);
assert(!b->prev);
a->next = b;
b->prev = a;
}
void block_append(block* b, block b2) {
if (b2.first) {
if (b->last) {
inst_join(b->last, b2.first);
} else {
b->first = b2.first;
}
b->last = b2.last;
}
}
block block_join(block a, block b) {
block c = a;
block_append(&c, b);
return c;
}
int block_has_only_binders(block binders, int bindflags) {
bindflags |= OP_HAS_BINDING;
for (inst* curr = binders.first; curr; curr = curr->next) {
if ((opcode_describe(curr->op)->flags & bindflags) != bindflags) {
return 0;
}
}
return 1;
}
static void block_bind_subblock(block binder, block body, int bindflags) {
assert(block_is_single(binder));
assert((opcode_describe(binder.first->op)->flags & bindflags) == bindflags);
assert(binder.first->symbol);
assert(binder.first->bound_by == 0 || binder.first->bound_by == binder.first);
binder.first->bound_by = binder.first;
for (inst* i = body.first; i; i = i->next) {
int flags = opcode_describe(i->op)->flags;
if ((flags & bindflags) == bindflags &&
i->bound_by == 0 &&
!strcmp(i->symbol, binder.first->symbol)) {
// bind this instruction
i->bound_by = binder.first;
}
// binding recurses into closures
block_bind_subblock(binder, i->subfn, bindflags);
// binding recurses into argument list
block_bind_subblock(binder, i->arglist, bindflags);
}
}
static void block_bind_each(block binder, block body, int bindflags) {
assert(block_has_only_binders(binder, bindflags));
bindflags |= OP_HAS_BINDING;
for (inst* curr = binder.first; curr; curr = curr->next) {
block_bind_subblock(inst_block(curr), body, bindflags);
}
}
block block_bind(block binder, block body, int bindflags) {
block_bind_each(binder, body, bindflags);
return block_join(binder, body);
}
block gen_function(const char* name, block formals, block body) {
block_bind_each(formals, body, OP_IS_CALL_PSEUDO);
inst* i = inst_new(CLOSURE_CREATE);
i->subfn = body;
i->symbol = strdup(name);
i->arglist = formals;
block b = inst_block(i);
block_bind_subblock(b, b, OP_IS_CALL_PSEUDO | OP_HAS_BINDING);
return b;
}
block gen_lambda(block body) {
return gen_function("@lambda", gen_noop(), body);
}
block gen_call(const char* name, block args) {
block b = gen_op_block_unbound(CALL_JQ, name);
b.first->arglist = args;
return b;
}
block gen_subexp(block a) {
return BLOCK(gen_op_simple(DUP), a, gen_op_simple(SWAP));
}
block gen_both(block a, block b) {
block jump = gen_op_targetlater(JUMP);
block fork = gen_op_target(FORK, jump);
block c = BLOCK(fork, a, jump, b);
inst_set_target(jump, c);
return c;
}
block gen_collect(block expr) {
block array_var = block_bind(gen_op_var_unbound(STOREV, "collect"),
gen_noop(), OP_HAS_VARIABLE);
block c = BLOCK(gen_op_simple(DUP), gen_const(jv_array()), array_var);
block tail = BLOCK(gen_op_var_bound(APPEND, array_var),
gen_op_simple(BACKTRACK));
return BLOCK(c,
gen_op_target(FORK, tail),
expr,
tail,
gen_op_var_bound(LOADV, array_var));
}
block gen_fold(const char* varname, block init, block fold) {
block loop = BLOCK(fold, gen_op_var_unbound(STOREV, varname), gen_op_simple(BACKTRACK));
return BLOCK(gen_op_simple(DUP),
init,
block_bind(gen_op_var_unbound(STOREV, varname),
BLOCK(gen_op_target(FORK, loop),
loop,
gen_op_var_unbound(LOADV, varname)),
OP_HAS_VARIABLE));
}
block gen_definedor(block a, block b) {
// var found := false
block found_var = block_bind(gen_op_var_unbound(STOREV, "found"),
gen_noop(), OP_HAS_VARIABLE);
block init = BLOCK(gen_op_simple(DUP), gen_const(jv_false()), found_var);
// if found, backtrack. Otherwise execute b
block backtrack = gen_op_simple(BACKTRACK);
block tail = BLOCK(gen_op_simple(DUP),
gen_op_var_bound(LOADV, found_var),
gen_op_target(JUMP_F, backtrack),
backtrack,
gen_op_simple(POP),
b);
// try again
block if_notfound = gen_op_simple(BACKTRACK);
// found := true, produce result
block if_found = BLOCK(gen_op_simple(DUP),
gen_const(jv_true()),
gen_op_var_bound(STOREV, found_var),
gen_op_target(JUMP, tail));
return BLOCK(init,
gen_op_target(FORK, if_notfound),
a,
gen_op_target(JUMP_F, if_found),
if_found,
if_notfound,
tail);
}
block gen_condbranch(block iftrue, block iffalse) {
iftrue = BLOCK(iftrue, gen_op_target(JUMP, iffalse));
return BLOCK(gen_op_target(JUMP_F, iftrue), iftrue, iffalse);
}
block gen_and(block a, block b) {
// a and b = if a then (if b then true else false) else false
return BLOCK(gen_op_simple(DUP), a,
gen_condbranch(BLOCK(gen_op_simple(POP),
b,
gen_condbranch(gen_const(jv_true()),
gen_const(jv_false()))),
BLOCK(gen_op_simple(POP), gen_const(jv_false()))));
}
block gen_or(block a, block b) {
// a or b = if a then true else (if b then true else false)
return BLOCK(gen_op_simple(DUP), a,
gen_condbranch(BLOCK(gen_op_simple(POP), gen_const(jv_true())),
BLOCK(gen_op_simple(POP),
b,
gen_condbranch(gen_const(jv_true()),
gen_const(jv_false())))));
}
block gen_var_binding(block var, const char* name, block body) {
return BLOCK(gen_op_simple(DUP), var,
block_bind(gen_op_var_unbound(STOREV, name),
body, OP_HAS_VARIABLE));
}
block gen_cond(block cond, block iftrue, block iffalse) {
return BLOCK(gen_op_simple(DUP), cond,
gen_condbranch(BLOCK(gen_op_simple(POP), iftrue),
BLOCK(gen_op_simple(POP), iffalse)));
}
block gen_cbinding(const struct cfunction* cfunctions, int ncfunctions, block code) {
for (int cfunc=0; cfunc<ncfunctions; cfunc++) {
inst* i = inst_new(CLOSURE_CREATE_C);
i->imm.cfunc = &cfunctions[cfunc];
i->symbol = strdup(i->imm.cfunc->name);
code = block_bind(inst_block(i), code, OP_IS_CALL_PSEUDO);
}
return code;
}
static uint16_t nesting_level(struct bytecode* bc, inst* target) {
uint16_t level = 0;
assert(bc && target->compiled);
while (bc && target->compiled != bc) {
level++;
bc = bc->parent;
}
assert(bc && bc == target->compiled);
return level;
}
static int count_cfunctions(block b) {
int n = 0;
for (inst* i = b.first; i; i = i->next) {
if (i->op == CLOSURE_CREATE_C) n++;
n += count_cfunctions(i->subfn);
}
return n;
}
// Expands call instructions into a calling sequence
static int expand_call_arglist(struct locfile* locations, block* b) {
int errors = 0;
block ret = gen_noop();
for (inst* curr; (curr = block_take(b));) {
if (opcode_describe(curr->op)->flags & OP_HAS_BINDING) {
if (!curr->bound_by) {
locfile_locate(locations, curr->source, "error: %s is not defined", curr->symbol);
errors++;
// don't process this instruction if it's not well-defined
ret = BLOCK(ret, inst_block(curr));
continue;
}
}
block prelude = gen_noop();
if (curr->op == CALL_JQ) {
int actual_args = 0, desired_args = 0;
// We expand the argument list as a series of instructions
switch (curr->bound_by->op) {
default: assert(0 && "Unknown function type"); break;
case CLOSURE_CREATE:
case CLOSURE_PARAM: {
block callargs = gen_noop();
for (inst* i; (i = block_take(&curr->arglist));) {
assert(opcode_describe(i->op)->flags & OP_IS_CALL_PSEUDO);
block b = inst_block(i);
switch (i->op) {
default: assert(0 && "Unknown type of parameter"); break;
case CLOSURE_REF:
block_append(&callargs, b);
break;
case CLOSURE_CREATE:
block_append(&prelude, b);
block_append(&callargs, gen_op_block_bound(CLOSURE_REF, b));
break;
}
actual_args++;
}
curr->imm.intval = actual_args;
curr->arglist = callargs;
if (curr->bound_by->op == CLOSURE_CREATE) {
for (inst* i = curr->bound_by->arglist.first; i; i = i->next) {
assert(i->op == CLOSURE_PARAM);
desired_args++;
}
}
break;
}
case CLOSURE_CREATE_C: {
for (inst* i; (i = block_take(&curr->arglist)); ) {
assert(i->op == CLOSURE_CREATE); // FIXME
block body = i->subfn;
i->subfn = gen_noop();
inst_free(i);
// arguments should be pushed in reverse order, prepend them to prelude
errors += expand_call_arglist(locations, &body);
prelude = BLOCK(gen_subexp(body), prelude);
actual_args++;
}
assert(curr->op == CALL_JQ);
curr->op = CALL_BUILTIN;
curr->imm.intval = actual_args + 1 /* include the implicit input in arg count */;
assert(curr->bound_by->op == CLOSURE_CREATE_C);
desired_args = curr->bound_by->imm.cfunc->nargs - 1;
assert(!curr->arglist.first);
break;
}
}
if (actual_args != desired_args) {
locfile_locate(locations, curr->source,
"error: %s arguments to %s (expected %d but got %d)",
actual_args > desired_args ? "too many" : "too few",
curr->symbol, desired_args, actual_args);
errors++;
}
}
ret = BLOCK(ret, prelude, inst_block(curr));
}
*b = ret;
return errors;
}
static int compile(struct locfile* locations, struct bytecode* bc, block b) {
int errors = 0;
int pos = 0;
int var_frame_idx = 0;
bc->nsubfunctions = 0;
errors += expand_call_arglist(locations, &b);
if (bc->parent) {
// functions should end in a return
b = BLOCK(b, gen_op_simple(RET));
} else {
// the toplevel should YIELD;BACKTRACK; when it finds an answer
b = BLOCK(b, gen_op_simple(YIELD), gen_op_simple(BACKTRACK));
}
for (inst* curr = b.first; curr; curr = curr->next) {
if (!curr->next) assert(curr == b.last);
int length = opcode_describe(curr->op)->length;
if (curr->op == CALL_JQ) {
for (inst* arg = curr->arglist.first; arg; arg = arg->next) {
length += 2;
}
}
pos += length;
curr->bytecode_pos = pos;
curr->compiled = bc;
assert(curr->op != CLOSURE_REF && curr->op != CLOSURE_PARAM);
if ((opcode_describe(curr->op)->flags & OP_HAS_VARIABLE) &&
curr->bound_by == curr) {
curr->imm.intval = var_frame_idx++;
}
if (curr->op == CLOSURE_CREATE) {
assert(curr->bound_by == curr);
curr->imm.intval = bc->nsubfunctions++;
}
if (curr->op == CLOSURE_CREATE_C) {
assert(curr->bound_by == curr);
int idx = bc->globals->ncfunctions++;
bc->globals->cfunctions[idx] = *curr->imm.cfunc;
curr->imm.intval = idx;
}
}
if (bc->nsubfunctions) {
bc->subfunctions = jv_mem_alloc(sizeof(struct bytecode*) * bc->nsubfunctions);
for (inst* curr = b.first; curr; curr = curr->next) {
if (curr->op == CLOSURE_CREATE) {
struct bytecode* subfn = jv_mem_alloc(sizeof(struct bytecode));
bc->subfunctions[curr->imm.intval] = subfn;
subfn->globals = bc->globals;
subfn->parent = bc;
subfn->nclosures = 0;
for (inst* param = curr->arglist.first; param; param = param->next) {
assert(param->op == CLOSURE_PARAM);
assert(param->bound_by == param);
param->imm.intval = subfn->nclosures++;
param->compiled = subfn;
}
errors += compile(locations, subfn, curr->subfn);
curr->subfn = gen_noop();
}
}
} else {
bc->subfunctions = 0;
}
bc->codelen = pos;
uint16_t* code = jv_mem_alloc(sizeof(uint16_t) * bc->codelen);
bc->code = code;
pos = 0;
jv constant_pool = jv_array();
int maxvar = -1;
if (!errors) for (inst* curr = b.first; curr; curr = curr->next) {
const struct opcode_description* op = opcode_describe(curr->op);
if (op->length == 0)
continue;
code[pos++] = curr->op;
assert(curr->op != CLOSURE_REF && curr->op != CLOSURE_PARAM);
if (curr->op == CALL_BUILTIN) {
assert(curr->bound_by->op == CLOSURE_CREATE_C);
assert(!curr->arglist.first);
code[pos++] = (uint16_t)curr->imm.intval;
code[pos++] = curr->bound_by->imm.intval;
} else if (curr->op == CALL_JQ) {
assert(curr->bound_by->op == CLOSURE_CREATE ||
curr->bound_by->op == CLOSURE_PARAM);
code[pos++] = (uint16_t)curr->imm.intval;
code[pos++] = nesting_level(bc, curr->bound_by);
code[pos++] = curr->bound_by->imm.intval |
(curr->bound_by->op == CLOSURE_CREATE ? ARG_NEWCLOSURE : 0);
for (inst* arg = curr->arglist.first; arg; arg = arg->next) {
assert(arg->op == CLOSURE_REF && arg->bound_by->op == CLOSURE_CREATE);
code[pos++] = nesting_level(bc, arg->bound_by);
code[pos++] = arg->bound_by->imm.intval | ARG_NEWCLOSURE;
}
} else if (op->flags & OP_HAS_CONSTANT) {
code[pos++] = jv_array_length(jv_copy(constant_pool));
constant_pool = jv_array_append(constant_pool, jv_copy(curr->imm.constant));
} else if (op->flags & OP_HAS_VARIABLE) {
code[pos++] = nesting_level(bc, curr->bound_by);
uint16_t var = (uint16_t)curr->bound_by->imm.intval;
code[pos++] = var;
if (var > maxvar) maxvar = var;
} else if (op->flags & OP_HAS_BRANCH) {
assert(curr->imm.target->bytecode_pos != -1);
assert(curr->imm.target->bytecode_pos > pos); // only forward branches
code[pos] = curr->imm.target->bytecode_pos - (pos + 1);
pos++;
} else if (op->length > 1) {
assert(0 && "codegen not implemented for this operation");
}
}
bc->constants = constant_pool;
bc->nlocals = maxvar + 2; // FIXME: frames of size zero?
block_free(b);
return errors;
}
int block_compile(block b, struct locfile* locations, struct bytecode** out) {
struct bytecode* bc = jv_mem_alloc(sizeof(struct bytecode));
bc->parent = 0;
bc->nclosures = 0;
bc->globals = jv_mem_alloc(sizeof(struct symbol_table));
int ncfunc = count_cfunctions(b);
bc->globals->ncfunctions = 0;
bc->globals->cfunctions = jv_mem_alloc(sizeof(struct cfunction) * ncfunc);
int nerrors = compile(locations, bc, b);
assert(bc->globals->ncfunctions == ncfunc);
if (nerrors > 0) {
bytecode_free(bc);
*out = 0;
} else {
*out = bc;
}
return nerrors;
}
void block_free(block b) {
struct inst* next;
for (struct inst* curr = b.first; curr; curr = next) {
next = curr->next;
inst_free(curr);
}
}
-76
View File
@@ -1,76 +0,0 @@
#ifndef COMPILE_H
#define COMPILE_H
#include <stdint.h>
#include "jv.h"
#include "opcode.h"
#include "locfile.h"
struct bytecode;
struct symbol_table;
struct cfunction;
struct inst;
typedef struct inst inst;
typedef struct block {
inst* first;
inst* last;
} block;
block gen_location(location, block);
block gen_noop();
block gen_op_simple(opcode op);
block gen_const(jv constant);
block gen_op_target(opcode op, block target);
block gen_op_var_unbound(opcode op, const char* name);
block gen_op_var_bound(opcode op, block binder);
block gen_op_block_unbound(opcode op, const char* name);
block gen_function(const char* name, block formals, block body);
block gen_lambda(block body);
block gen_call(const char* name, block body);
block gen_subexp(block a);
block gen_both(block a, block b);
block gen_collect(block expr);
block gen_fold(const char* varname, block init, block body);
block gen_definedor(block a, block b);
block gen_condbranch(block iftrue, block iffalse);
block gen_and(block a, block b);
block gen_or(block a, block b);
block gen_var_binding(block var, const char* name, block body);
block gen_cond(block cond, block iftrue, block iffalse);
block gen_cbinding(const struct cfunction* functions, int nfunctions, block b);
void block_append(block* b, block b2);
block block_join(block a, block b);
int block_has_only_binders(block, int bindflags);
block block_bind(block binder, block body, int bindflags);
int block_compile(block, struct locfile*, struct bytecode**);
void block_free(block);
// Here's some horrible preprocessor gunk so that code
// sequences can be contructed as BLOCK(block1, block2, block3)
#define BLOCK_1(b1) (b1)
#define BLOCK_2(b1,b2) (block_join((b1),(b2)))
#define BLOCK_3(b1,b2,b3) (block_join(BLOCK_2(b1,b2),(b3)))
#define BLOCK_4(b1,b2,b3,b4) (block_join(BLOCK_3(b1,b2,b3),(b4)))
#define BLOCK_5(b1,b2,b3,b4,b5) (block_join(BLOCK_4(b1,b2,b3,b4),(b5)))
#define BLOCK_6(b1,b2,b3,b4,b5,b6) (block_join(BLOCK_5(b1,b2,b3,b4,b5),(b6)))
#define BLOCK_7(b1,b2,b3,b4,b5,b6,b7) (block_join(BLOCK_6(b1,b2,b3,b4,b5,b6),(b7)))
#define BLOCK_IDX(_1,_2,_3,_4,_5,_6,_7,NAME,...) NAME
#define BLOCK(...) \
BLOCK_IDX(__VA_ARGS__, BLOCK_7, BLOCK_6, BLOCK_5, BLOCK_4, BLOCK_3, BLOCK_2, BLOCK_1)(__VA_ARGS__)
#endif
-32
View File
@@ -1,32 +0,0 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
#undef NO_MINUS_C_MINUS_O
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Version number of package */
#undef VERSION
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
`char[]'. */
#undef YYTEXT_POINTER
+10
View File
@@ -0,0 +1,10 @@
config.guess
config.sub
compile
depcomp
install-sh
ltmain.sh
missing
ylwrap
test-driver
ar-lib
-343
View File
@@ -1,343 +0,0 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
scriptversion=2012-03-05.13; # UTC
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009, 2010, 2012 Free
# Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
nl='
'
# We need space, tab and new line, in precisely that order. Quoting is
# there to prevent tools from complaining about whitespace usage.
IFS=" "" $nl"
file_conv=
# func_file_conv build_file lazy
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts. If the determined conversion
# type is listed in (the comma separated) LAZY, no conversion will
# take place.
func_file_conv ()
{
file=$1
case $file in
/ | /[!/]*) # absolute file, and not a UNC file
if test -z "$file_conv"; then
# lazily determine how to convert abs files
case `uname -s` in
MINGW*)
file_conv=mingw
;;
CYGWIN*)
file_conv=cygwin
;;
*)
file_conv=wine
;;
esac
fi
case $file_conv/,$2, in
*,$file_conv,*)
;;
mingw/*)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin/*)
file=`cygpath -m "$file" || echo "$file"`
;;
wine/*)
file=`winepath -w "$file" || echo "$file"`
;;
esac
;;
esac
}
# func_cl_dashL linkdir
# Make cl look for libraries in LINKDIR
func_cl_dashL ()
{
func_file_conv "$1"
if test -z "$lib_path"; then
lib_path=$file
else
lib_path="$lib_path;$file"
fi
linker_opts="$linker_opts -LIBPATH:$file"
}
# func_cl_dashl library
# Do a library search-path lookup for cl
func_cl_dashl ()
{
lib=$1
found=no
save_IFS=$IFS
IFS=';'
for dir in $lib_path $LIB
do
IFS=$save_IFS
if $shared && test -f "$dir/$lib.dll.lib"; then
found=yes
lib=$dir/$lib.dll.lib
break
fi
if test -f "$dir/$lib.lib"; then
found=yes
lib=$dir/$lib.lib
break
fi
done
IFS=$save_IFS
if test "$found" != yes; then
lib=$lib.lib
fi
}
# func_cl_wrapper cl arg...
# Adjust compile command to suit cl
func_cl_wrapper ()
{
# Assume a capable shell
lib_path=
shared=:
linker_opts=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
eat=1
case $2 in
*.o | *.[oO][bB][jJ])
func_file_conv "$2"
set x "$@" -Fo"$file"
shift
;;
*)
func_file_conv "$2"
set x "$@" -Fe"$file"
shift
;;
esac
;;
-I)
eat=1
func_file_conv "$2" mingw
set x "$@" -I"$file"
shift
;;
-I*)
func_file_conv "${1#-I}" mingw
set x "$@" -I"$file"
shift
;;
-l)
eat=1
func_cl_dashl "$2"
set x "$@" "$lib"
shift
;;
-l*)
func_cl_dashl "${1#-l}"
set x "$@" "$lib"
shift
;;
-L)
eat=1
func_cl_dashL "$2"
;;
-L*)
func_cl_dashL "${1#-L}"
;;
-static)
shared=false
;;
-Wl,*)
arg=${1#-Wl,}
save_ifs="$IFS"; IFS=','
for flag in $arg; do
IFS="$save_ifs"
linker_opts="$linker_opts $flag"
done
IFS="$save_ifs"
;;
-Xlinker)
eat=1
linker_opts="$linker_opts $2"
;;
-*)
set x "$@" "$1"
shift
;;
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
func_file_conv "$1"
set x "$@" -Tp"$file"
shift
;;
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
func_file_conv "$1" mingw
set x "$@" "$file"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -n "$linker_opts"; then
linker_opts="-link$linker_opts"
fi
exec "$@" $linker_opts
exit 1
}
eat=
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand '-c -o'.
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file 'INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "compile $scriptversion"
exit $?
;;
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
ofile=
cfile=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
# So we strip '-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no '-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# '.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi
# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
# Create the lock directory.
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
while true; do
if mkdir "$lockdir" >/dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15
# Run the compile.
"$@"
ret=$?
if test -f "$cofile"; then
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
fi
rmdir "$lockdir"
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
-708
View File
@@ -1,708 +0,0 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2012-03-27.16; # UTC
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010,
# 2011, 2012 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by 'PROGRAMS ARGS'.
object Object file output by 'PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
# A tabulation character.
tab=' '
# A newline character.
nl='
'
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvisualcpp
fi
if test "$depmode" = msvc7msys; then
# This is just like msvc7 but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvc7
fi
if test "$depmode" = xlc; then
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations.
gccflag=-qmakedep=gcc,-MF
depmode=gcc
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the "deleted header file" problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' "$nl" < "$tmpdepfile" |
## Some versions of gcc put a space before the ':'. On the theory
## that the space means something, we add a space to the output as
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like '#:fec' to the end of the
# dependency line.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr "$nl" ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
xlc)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts '$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
tmpdepfile1=$dir$base.u
tmpdepfile2=$dir$base.u
tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
# Each line is of the form 'foo.o: dependent.h'.
# Do two passes, one to just change these to
# '$object: dependent.h' and one to simply 'dependent.h:'.
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
icc)
# Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'.
# However on
# $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using '\':
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
# tcc 0.9.26 (FIXME still under development at the moment of writing)
# will emit a similar output, but also prepend the continuation lines
# with horizontal tabulation characters.
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form 'foo.o: dependent.h',
# or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'.
# Do two passes, one to just change these to
# '$object: dependent.h' and one to simply 'dependent.h:'.
sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \
< "$tmpdepfile" > "$depfile"
sed '
s/[ '"$tab"'][ '"$tab"']*/ /g
s/^ *//
s/ *\\*$//
s/^[^:]*: *//
/^$/d
/:$/d
s/$/ :/
' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
# Add 'dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
s/$/:/
p
}' "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in 'foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
# With Tru64 cc, shared objects can also be used to make a
# static library. This mechanism is used in libtool 1.4 series to
# handle both shared and static libraries in a single compilation.
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
#
# With libtool 1.5 this exception was removed, and libtool now
# generates 2 separate objects for the 2 libraries. These two
# compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
tmpdepfile2=$dir$base.o.d # libtool 1.5
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.o.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
tmpdepfile4=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
msvc7)
if test "$libtool" = yes; then
showIncludes=-Wc,-showIncludes
else
showIncludes=-showIncludes
fi
"$@" $showIncludes > "$tmpdepfile"
stat=$?
grep -v '^Note: including file: ' "$tmpdepfile"
if test "$stat" = 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The first sed program below extracts the file names and escapes
# backslashes for cygpath. The second sed program outputs the file
# name when reading, but also accumulates all include files in the
# hold buffer in order to output them again at the end. This only
# works with sed implementations that can handle large buffers.
sed < "$tmpdepfile" -n '
/^Note: including file: *\(.*\)/ {
s//\1/
s/\\/\\\\/g
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
s/\(.*\)/'"$tab"'\1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
s/.*/'"$tab"'/
G
p
}' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvc7msys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for ':'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' "$nl" < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no eat=no
for arg
do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
if test $eat = yes; then
eat=no
continue
fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-arch)
eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E |
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
IFS=" "
for arg
do
case "$arg" in
-o)
shift
;;
$object)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E 2>/dev/null |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
echo "$tab" >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvcmsys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
-527
View File
@@ -1,527 +0,0 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2011-01-19.21; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_glob='?'
initialize_posix_glob='
test "$posix_glob" != "?" || {
if (set -f) 2>/dev/null; then
posix_glob=
else
posix_glob=:
fi
}
'
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
no_target_directory=
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t) dst_arg=$2
# Protect names problematic for `test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) no_target_directory=true;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for `test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for `test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writeable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
$posix_glob set -f
set fnord $dstdir
shift
$posix_glob set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
eval "$initialize_posix_glob" &&
$posix_glob set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
$posix_glob set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
+2
View File
@@ -0,0 +1,2 @@
libtool.m4
lt*.m4
+4
View File
@@ -0,0 +1,4 @@
dnl AC_FIND_FUNC(func, arguments)
AC_DEFUN([AC_CHECK_MATH_FUNC], [
AC_FIND_FUNC_NO_LIBS([$1], [m], [#include <math.h>], [$2])
])
+8
View File
@@ -0,0 +1,8 @@
dnl Shamelessly stolen from Heimdal
dnl
dnl Look for function in any of the specified libraries
dnl
dnl AC_FIND_FUNC_NO_LIBS(func, libraries, includes, arguments, extra libs, extra args)
AC_DEFUN([AC_FIND_FUNC_NO_LIBS], [
AC_FIND_FUNC_NO_LIBS2([$1], ["" $2], [$3], [$4], [$5], [$6])])
+62
View File
@@ -0,0 +1,62 @@
dnl Shamelessly stolen from Heimdal
dnl
dnl Look for function in any of the specified libraries
dnl
dnl AC_FIND_FUNC_NO_LIBS2(func, libraries, includes, arguments, extra libs, extra args)
AC_DEFUN([AC_FIND_FUNC_NO_LIBS2], [
AC_MSG_CHECKING([for $1])
AC_CACHE_VAL(ac_cv_funclib_$1,
[
if eval "test \"\$ac_cv_func_$1\" != yes" ; then
ac_save_LIBS="$LIBS"
for ac_lib in $2; do
case "$ac_lib" in
"") ;;
yes) ac_lib="" ;;
no) continue ;;
-l*) ;;
*) ac_lib="-l$ac_lib" ;;
esac
LIBS="$6 $ac_lib $5 $ac_save_LIBS"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[$3]],[[$1($4)]])],[eval "if test -n \"$ac_lib\";then ac_cv_funclib_$1=$ac_lib; else ac_cv_funclib_$1=yes; fi";break])
done
eval "ac_cv_funclib_$1=\${ac_cv_funclib_$1-no}"
LIBS="$ac_save_LIBS"
fi
])
eval "ac_res=\$ac_cv_funclib_$1"
if false; then
AC_CHECK_FUNCS($1)
dnl AC_CHECK_LIBS($2, foo)
fi
# $1
eval "ac_tr_func=HAVE_[]upcase($1)"
eval "ac_tr_lib=HAVE_LIB[]upcase($ac_res | sed -e 's/-l//')"
eval "LIB_$1=$ac_res"
case "$ac_res" in
yes)
eval "ac_cv_func_$1=yes"
eval "LIB_$1="
AC_DEFINE_UNQUOTED($ac_tr_func)
AC_MSG_RESULT([yes])
;;
no)
eval "ac_cv_func_$1=no"
eval "LIB_$1="
AC_MSG_RESULT([no])
;;
*)
eval "ac_cv_func_$1=yes"
eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
AC_DEFINE_UNQUOTED($ac_tr_func)
AC_DEFINE_UNQUOTED($ac_tr_lib)
AC_MSG_RESULT([yes, in $ac_res])
;;
esac
AC_SUBST(LIB_$1)
])
+9
View File
@@ -0,0 +1,9 @@
dnl Shamelessly stolen from Heimdal
dnl
dnl AC_FIND_FUNC(func, libraries, includes, arguments)
AC_DEFUN([AC_FIND_FUNC], [
AC_FIND_FUNC_NO_LIBS([$1], [$2], [$3], [$4])
if test -n "$LIB_$1"; then
LIBS="$LIB_$1 $LIBS"
fi
])
+3
View File
@@ -0,0 +1,3 @@
dnl Shamelessly stolen from Heimdal
AC_DEFUN([upcase],[`echo $1 | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`])dnl
-331
View File
@@ -1,331 +0,0 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2012-01-06.13; # UTC
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
msg="missing on your system"
case $1 in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
autom4te touch the output file, or create a stub one
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
\`g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
esac
# normalize program name to check for.
program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`
# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program). This is about non-GNU programs, so use $1 not
# $program.
case $1 in
lex*|yacc*)
# Not GNU programs, they don't have --version.
;;
*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
# Could not run --version or --help. This is probably someone
# running `$TOOL --version' or `$TOOL --help' to check whether
# $TOOL exists and not knowing $TOOL uses missing.
exit 1
fi
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case $program in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case $f in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te*)
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison*|yacc*)
echo 1>&2 "\
WARNING: \`$1' $msg. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if test $# -ne 1; then
eval LASTARG=\${$#}
case $LASTARG in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if test ! -f y.tab.h; then
echo >y.tab.h
fi
if test ! -f y.tab.c; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex*|flex*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if test $# -ne 1; then
eval LASTARG=\${$#}
case $LASTARG in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if test ! -f lex.yy.c; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit $?
fi
;;
makeinfo*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '
/^@setfilename/{
s/.* \([^ ]*\) *$/\1/
p
q
}' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
# If the file does not exist, the user really needs makeinfo;
# let's fail without touching anything.
test -f $file || exit 1
touch $file
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
-226
View File
@@ -1,226 +0,0 @@
#! /bin/sh
# ylwrap - wrapper for lex/yacc invocations.
scriptversion=2011-08-25.18; # UTC
# Copyright (C) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005,
# 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
#
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
case "$1" in
'')
echo "$0: No files given. Try \`$0 --help' for more information." 1>&2
exit 1
;;
--basedir)
basedir=$2
shift 2
;;
-h|--h*)
cat <<\EOF
Usage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]...
Wrapper for lex/yacc invocations, renaming files as desired.
INPUT is the input file
OUTPUT is one file PROG generates
DESIRED is the file we actually want instead of OUTPUT
PROGRAM is program to run
ARGS are passed to PROG
Any number of OUTPUT,DESIRED pairs may be used.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v|--v*)
echo "ylwrap $scriptversion"
exit $?
;;
esac
# The input.
input="$1"
shift
case "$input" in
[\\/]* | ?:[\\/]*)
# Absolute path; do nothing.
;;
*)
# Relative path. Make it absolute.
input="`pwd`/$input"
;;
esac
pairlist=
while test "$#" -ne 0; do
if test "$1" = "--"; then
shift
break
fi
pairlist="$pairlist $1"
shift
done
# The program to run.
prog="$1"
shift
# Make any relative path in $prog absolute.
case "$prog" in
[\\/]* | ?:[\\/]*) ;;
*[\\/]*) prog="`pwd`/$prog" ;;
esac
# FIXME: add hostname here for parallel makes that run commands on
# other machines. But that might take us over the 14-char limit.
dirname=ylwrap$$
do_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
mkdir $dirname || exit 1
cd $dirname
case $# in
0) "$prog" "$input" ;;
*) "$prog" "$@" "$input" ;;
esac
ret=$?
if test $ret -eq 0; then
set X $pairlist
shift
first=yes
# Since DOS filename conventions don't allow two dots,
# the DOS version of Bison writes out y_tab.c instead of y.tab.c
# and y_tab.h instead of y.tab.h. Test to see if this is the case.
y_tab_nodot="no"
if test -f y_tab.c || test -f y_tab.h; then
y_tab_nodot="yes"
fi
# The directory holding the input.
input_dir=`echo "$input" | sed -e 's,\([\\/]\)[^\\/]*$,\1,'`
# Quote $INPUT_DIR so we can use it in a regexp.
# FIXME: really we should care about more than `.' and `\'.
input_rx=`echo "$input_dir" | sed 's,\\\\,\\\\\\\\,g;s,\\.,\\\\.,g'`
while test "$#" -ne 0; do
from="$1"
# Handle y_tab.c and y_tab.h output by DOS
if test $y_tab_nodot = "yes"; then
if test $from = "y.tab.c"; then
from="y_tab.c"
else
if test $from = "y.tab.h"; then
from="y_tab.h"
fi
fi
fi
if test -f "$from"; then
# If $2 is an absolute path name, then just use that,
# otherwise prepend `../'.
case "$2" in
[\\/]* | ?:[\\/]*) target="$2";;
*) target="../$2";;
esac
# We do not want to overwrite a header file if it hasn't
# changed. This avoid useless recompilations. However the
# parser itself (the first file) should always be updated,
# because it is the destination of the .y.c rule in the
# Makefile. Divert the output of all other files to a temporary
# file so we can compare them to existing versions.
if test $first = no; then
realtarget="$target"
target="tmp-`echo $target | sed s/.*[\\/]//g`"
fi
# Edit out `#line' or `#' directives.
#
# We don't want the resulting debug information to point at
# an absolute srcdir; it is better for it to just mention the
# .y file with no path.
#
# We want to use the real output file name, not yy.lex.c for
# instance.
#
# We want the include guards to be adjusted too.
FROM=`echo "$from" | sed \
-e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'\
-e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`
TARGET=`echo "$2" | sed \
-e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'\
-e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`
sed -e "/^#/!b" -e "s,$input_rx,," -e "s,$from,$2," \
-e "s,$FROM,$TARGET," "$from" >"$target" || ret=$?
# Check whether header files must be updated.
if test $first = no; then
if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then
echo "$2" is unchanged
rm -f "$target"
else
echo updating "$2"
mv -f "$target" "$realtarget"
fi
fi
else
# A missing file is only an error for the first file. This
# is a blatant hack to let us support using "yacc -d". If -d
# is not specified, we don't want an error when the header
# file is "missing".
if test $first = yes; then
ret=1
fi
fi
shift
shift
first=no
done
else
ret=$?
fi
# Remove the directory.
cd ..
rm -rf $dirname
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
+240 -23
View File
@@ -1,66 +1,283 @@
AC_INIT([jq], [1.2], [mu@netsoc.tcd.ie],
[jq], [http://stedolan.github.com/jq/])
m4_define([jq_version],
m4_esyscmd_s([(git rev-parse --verify -q jq-1.0 > /dev/null &&
(git describe --tags --dirty --match 'jq-*'|sed 's/^jq-//')) ||
echo `git rev-parse --abbrev-ref HEAD`-`git describe --always --dirty`])))
AC_INIT([jq], [jq_version], [https://github.com/stedolan/jq/issues],
[jq], [https://stedolan.github.io/jq])
m4_include([m4/ax_compare_version.m4])
m4_include([m4/ax_prog_bison_version.m4])
dnl Created autoconf implementation thompson@dtosolutions, 26NOV12
AC_PREREQ([2.61])
AC_PREREQ([2.64])
AC_CONFIG_AUX_DIR([config])
AM_INIT_AUTOMAKE([parallel-tests foreign])
AM_INIT_AUTOMAKE([1.11.2 subdir-objects parallel-tests foreign -Wall])
AM_SILENT_RULES([yes])
AM_PROG_AR
AM_MAINTAINER_MODE([enable])
AC_PROG_CC
AC_PROG_CC_STDC
AC_PROG_CPP_WERROR
AC_PROG_YACC
AC_OBJEXT
AC_EXEEXT
LT_INIT([shared static win32-dll])
AM_PROG_CC_C_O
dnl couldn't use AM_PROG_LEX as it doesn't support header files like the
dnl AC_PROG_YACC macros...
dnl
dnl these program checks should probably be deleted
dnl
dnl check bison version
AC_PROG_LEX
if test "x$LEX" != xflex; then
LEX="$SHELL $missing_dir/missing flex"
if test "$USE_MAINTAINER_MODE" = yes; then
if test "$YACC" != "bison -y"; then
AC_MSG_CHECKING([bison version])
AC_MSG_RESULT([not bison])
else
AX_PROG_BISON_VERSION([3],
[],
[AC_MSG_ERROR([You need bison version 3.0 or greater, or use --disable-maintainer-mode.])])
fi
AC_CHECK_PROGS(LEX, flex lex)
fi
dnl Check for valgrind
AC_CHECK_PROGS(valgrind_cmd, valgrind)
if test "x$valgrind_cmd" = "x" ; then
AC_MSG_WARN([valgrind is required to test jq.])
fi
AC_CHECK_FUNCS(memmem)
AC_CHECK_FUNCS(mkstemp)
AC_CHECK_HEADER("shlwapi.h",[have_win32=1;])
AM_CONDITIONAL([WIN32], [test "x$have_win32" = x1])
dnl Running tests with Valgrind is slow. It is faster to iterate on
dnl code without Valgrind until tests pass, then enable Valgrind and
dnl fix leaks.
AC_ARG_ENABLE([valgrind],
AC_HELP_STRING([--disable-valgrind], [do not run tests under Valgrind]))
dnl Running tests with Valgrind is slow; address sanitizer (ASAN) is
dnl faster.
AC_ARG_ENABLE([asan],
AC_HELP_STRING([--enable-asan], [enable address sanitizer]))
dnl Undefined Behavior Sanitizer
AC_ARG_ENABLE([ubsan],
AC_HELP_STRING([--enable-ubsan], [enable undefined behavior sanitizer]))
dnl Code coverage
AC_ARG_ENABLE([gcov],
AC_HELP_STRING([--enable-gcov], [enable gcov code coverage tool]))
dnl Don't attempt to build docs if there's no Ruby lying around
AC_ARG_ENABLE([docs],
AC_HELP_STRING([--disable-docs], [don't build docs]))
dnl Don't attempt to build the error injection object (if there is no LD_PRELOAD support)
AC_ARG_ENABLE([error-injection],
AC_HELP_STRING([--enable-error-injection], [build and test with error injection]))
dnl Enable building all static
AC_ARG_ENABLE([all-static],
AC_HELP_STRING([--enable-all-static], [link jq with static libraries only]))
AS_IF([test "x$enable_docs" != "xno"],[
AC_CHECK_PROGS(bundle_cmd, bundle)
AS_IF([test "x$bundle_cmd" = "x" || \
! ( cd ${srcdir}/docs; "$bundle_cmd" check 2>/dev/null )],[
AC_MSG_WARN([no bundler])
cat <<EOF
AC_CACHE_CHECK([for Ruby dependencies], [jq_cv_ruby_deps],
[jq_cv_ruby_deps=yes;
AS_IF([test "x$bundle_cmd" = "x" || \
! bmsg="`cd ${srcdir}/docs; "$bundle_cmd" check 2>/dev/null`"],[
AC_MSG_WARN([$bmsg])
cat <<EOF
*****************************************************************
* Ruby dependencies for building jq documentation not found. *
* You can still build, install and hack on jq, but the manpage *
* will not be rebuilt and some of the tests won't run. *
* will not be rebuilt and some of the tests will not run. *
* See docs/README.md for how to install the docs dependencies. *
*****************************************************************
EOF
enable_docs=no
])
jq_cv_ruby_deps=no
])])
if test "x$jq_cv_ruby_deps" != "xyes"; then
enable_docs=no
fi
])
AM_CONDITIONAL([ENABLE_VALGRIND], [test "x$enable_valgrind" != xno])
AM_CONDITIONAL([ENABLE_ASAN], [test "x$enable_asan" = xyes])
AM_CONDITIONAL([ENABLE_UBSAN], [test "x$enable_ubsan" = xyes])
AM_CONDITIONAL([ENABLE_GCOV], [test "x$enable_gcov" = xyes])
AM_CONDITIONAL([ENABLE_DOCS], [test "x$enable_docs" != xno])
AM_CONDITIONAL([ENABLE_ERROR_INJECTION], [test "x$enable_error_injection" = xyes])
AM_CONDITIONAL([ENABLE_ALL_STATIC], [test "x$enable_all_static" = xyes])
AC_FUNC_ALLOCA
AC_FIND_FUNC([isatty], [c], [#include <unistd.h>], [0])
AC_FIND_FUNC([_isatty], [c], [#include <io.h>], [0])
AC_FIND_FUNC([strptime], [c], [#include <time.h>], [0, 0, 0])
AC_FIND_FUNC([strftime], [c], [#include <time.h>], [0, 0, 0, 0])
AC_FIND_FUNC([timegm], [c], [#include <time.h>], [0])
AC_FIND_FUNC([gmtime_r], [c], [#include <time.h>], [0, 0])
AC_FIND_FUNC([gmtime], [c], [#include <time.h>], [0])
AC_FIND_FUNC([localtime_r], [c], [#include <time.h>], [0, 0])
AC_FIND_FUNC([localtime], [c], [#include <time.h>], [0])
AC_FIND_FUNC([gettimeofday], [c], [#include <time.h>], [0, 0])
AC_CHECK_MEMBER([struct tm.tm_gmtoff], [AC_DEFINE([HAVE_TM_TM_GMT_OFF],1,[Define to 1 if the system has the tm_gmt_off field in struct tm])],
[], [[#include <time.h>]])
AC_CHECK_MEMBER([struct tm.__tm_gmtoff], [AC_DEFINE([HAVE_TM___TM_GMT_OFF],1,[Define to 1 if the system has the __tm_gmt_off field in struct tm])],
[], [[#include <time.h>]])
AC_ARG_ENABLE([pthread-tls],
[AC_HELP_STRING([--enable-pthread-tls],
[Enable use of pthread thread local storage])],
[],
[enable_pthread_tls=no])
if test $enable_pthread_tls = yes; then
AC_FIND_FUNC([pthread_key_create], [pthread], [#include <pthread.h>], [NULL, NULL])
AC_FIND_FUNC([pthread_once], [pthread], [#include <pthread.h>], [NULL, NULL])
AC_FIND_FUNC([atexit], [pthread], [#include <stdlib.h>], [NULL])
fi
dnl libm math.h functions
AC_CHECK_MATH_FUNC(acos, [.5])
AC_CHECK_MATH_FUNC(acosh, [.5])
AC_CHECK_MATH_FUNC(asin, [.5])
AC_CHECK_MATH_FUNC(asinh, [.5])
AC_CHECK_MATH_FUNC(atan2, [.5,.5])
AC_CHECK_MATH_FUNC(atan, [.5])
AC_CHECK_MATH_FUNC(atanh, [.5])
AC_CHECK_MATH_FUNC(cbrt, [.5])
AC_CHECK_MATH_FUNC(ceil,[.5])
AC_CHECK_MATH_FUNC(copysign,[.5,1.0])
AC_CHECK_MATH_FUNC(cos, [.5])
AC_CHECK_MATH_FUNC(cosh, [.5])
AC_CHECK_MATH_FUNC(drem,[.5,1.0])
AC_CHECK_MATH_FUNC(erf,[.5])
AC_CHECK_MATH_FUNC(erfc,[.5])
AC_CHECK_MATH_FUNC(exp10,[.5])
AC_CHECK_MATH_FUNC(exp2, [.5])
AC_CHECK_MATH_FUNC(exp, [.5])
AC_CHECK_MATH_FUNC(expm1,[.5])
AC_CHECK_MATH_FUNC(fabs,[.5])
AC_CHECK_MATH_FUNC(fdim,[.5,1.0])
AC_CHECK_MATH_FUNC(floor, [.5])
AC_CHECK_MATH_FUNC(fma,[.5,1.0,1.5])
AC_CHECK_MATH_FUNC(fmax,[.5,1.0])
AC_CHECK_MATH_FUNC(fmin,[.5,1.0])
AC_CHECK_MATH_FUNC(fmod,[.5,1.0])
AC_FIND_FUNC([frexp], [m c], [#include <math.h>], [0, 0])
AC_CHECK_MATH_FUNC(gamma,[.5])
AC_CHECK_MATH_FUNC(hypot, [.5,.5])
AC_CHECK_MATH_FUNC(j0, [.5])
AC_CHECK_MATH_FUNC(j1, [.5])
AC_CHECK_MATH_FUNC(jn, [1,.5])
AC_CHECK_MATH_FUNC(ldexp,[.5,2])
AC_CHECK_MATH_FUNC(lgamma,[.5])
AC_CHECK_MATH_FUNC(log10, [.5])
AC_CHECK_MATH_FUNC(log1p,[.5])
AC_CHECK_MATH_FUNC(log2, [.5])
AC_CHECK_MATH_FUNC(log, [.5])
AC_CHECK_MATH_FUNC(logb,[.5])
AC_CHECK_MATH_FUNC([modf], [m c], [#include <math.h>], [0, 0])
AC_CHECK_MATH_FUNC([lgamma_r], [m c], [#include <math.h>], [0, 0])
AC_CHECK_MATH_FUNC(nearbyint,[.5])
AC_CHECK_MATH_FUNC(nextafter,[.5,1.0])
AC_CHECK_MATH_FUNC(nexttoward,[.5,1.0])
AC_CHECK_MATH_FUNC(pow10,[.5])
AC_CHECK_MATH_FUNC(pow, [2,2])
AC_CHECK_MATH_FUNC(remainder, [3,2])
AC_CHECK_MATH_FUNC(rint,[.5])
AC_CHECK_MATH_FUNC(round,[.5])
AC_CHECK_MATH_FUNC(scalb,[.5,1.0])
AC_CHECK_MATH_FUNC(scalbln,[.5,2])
AC_CHECK_MATH_FUNC(significand,[.5])
AC_CHECK_MATH_FUNC(sin, [.5])
AC_CHECK_MATH_FUNC(sinh, [.5])
AC_CHECK_MATH_FUNC(sqrt, [.5])
AC_CHECK_MATH_FUNC(tan, [.5])
AC_CHECK_MATH_FUNC(tanh, [.5])
AC_CHECK_MATH_FUNC(tgamma, [.5])
AC_CHECK_MATH_FUNC(trunc,[.5])
AC_CHECK_MATH_FUNC(y0, [.5])
AC_CHECK_MATH_FUNC(y1, [.5])
AC_CHECK_MATH_FUNC(yn, [1,.5])
dnl Thread local storage
have___thread=no
AC_MSG_CHECKING(for thread-local storage)
AC_LINK_IFELSE([AC_LANG_SOURCE([
static __thread int x ;
int main () { x = 123; return x; }
])], have___thread=yes)
if test $have___thread = yes; then
AC_DEFINE([HAVE___THREAD],1,[Define to 1 if the system supports __thread])
fi
AC_MSG_RESULT($have___thread)
AC_C_BIGENDIAN(
AC_DEFINE([IEEE_MC68k], 1, [machine is bigendian]),
AC_DEFINE([IEEE_8087], 1, [machine is littleendian]),
AC_MSG_ERROR(unknown endianess),
AC_MSG_ERROR(universial endianess not supported)
)
dnl Oniguruma
AC_ARG_WITH([oniguruma],
[AS_HELP_STRING([--with-oniguruma=prefix],
[try this for a non-standard install prefix of the oniguruma library])], ,
[with_oniguruma=yes])
onig_CFLAGS=
onig_LDFLAGS=
build_oniguruma=no
AS_IF([test "x$with_oniguruma" != xno], [
save_CFLAGS="$CFLAGS"
save_LDFLAGS="$LDFLAGS"
AS_IF([test "x$with_oniguruma" != xyes], [
AS_IF([test "x$with_oniguruma" = xbuiltin], [
build_oniguruma=yes
], [
onig_CFLAGS="-I${with_oniguruma}/include"
onig_LDFLAGS="-L${with_oniguruma}/lib"
])
])
AS_IF([test "x$build_oniguruma" = xno], [
# check for ONIGURUMA library, either in /usr or where requested
CFLAGS="$CFLAGS $onig_CFLAGS"
LDFLAGS="$LDFLAGS $onig_LDFLAGS"
AC_CHECK_HEADER("oniguruma.h",
AC_CHECK_LIB([onig],[onig_version]))
# handle check results
AS_IF([test "x$ac_cv_lib_onig_onig_version" != "xyes"], [
build_oniguruma=yes
AC_MSG_NOTICE([Oniguruma was not found. Will use the packaged oniguruma.])
])
])
AS_IF([test "x$build_oniguruma" = xyes -a -f "${srcdir}/modules/oniguruma/configure.ac" ], [
onig_CFLAGS="-I${srcdir}/modules/oniguruma/src"
onig_LDFLAGS="-L${srcdir}/modules/oniguruma/src -Wl,-rpath,${libdir}"
AC_CONFIG_SUBDIRS([modules/oniguruma])
AC_DEFINE([HAVE_LIBONIG],1,[Define to 1 if the system includes libonig])
])
CFLAGS="$save_CFLAGS"
LDFLAGS="$save_LDFLAGS"
])
AC_SUBST(onig_CFLAGS)
AC_SUBST(onig_LDFLAGS)
AM_CONDITIONAL([BUILD_ONIGURUMA], [test "x$build_oniguruma" = xyes])
AC_SUBST([BUNDLER], ["$bundle_cmd"])
dnl AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS(config.h)
AM_INIT_AUTOMAKE([-Wall])
AC_CONFIG_MACRO_DIR([config/m4])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
+1
View File
@@ -4,3 +4,4 @@ gem "rake"
gem "bonsai"
gem "maruku"
gem "ronn"
gem "mustache", "<1.0" # to support ruby <2.0
+30 -30
View File
@@ -1,15 +1,14 @@
GEM
remote: https://rubygems.org/
specs:
POpen4 (0.1.4)
Platform (>= 0.4.0)
open4
Platform (0.4.0)
activesupport (3.2.12)
i18n (~> 0.6)
multi_json (~> 1.0)
addressable (2.3.4)
bonsai (1.4.8)
activesupport (4.2.3)
i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.3.8)
bonsai (1.4.9)
activesupport (>= 3.0.3)
builder (>= 3.0.0)
i18n (>= 0.5.0)
@@ -22,36 +21,36 @@ GEM
tilt (>= 1.3)
watch (>= 0.1.0)
yui-compressor
builder (3.2.0)
builder (3.2.2)
hpricot (0.8.6)
i18n (0.6.4)
launchy (2.3.0)
i18n (0.7.0)
json (1.8.3)
launchy (2.4.3)
addressable (~> 2.3)
liquid (2.5.0)
maruku (0.6.1)
syntax (>= 1.0.0)
multi_json (1.7.3)
mustache (0.99.4)
open4 (1.3.0)
rack (1.5.2)
rack-protection (1.5.0)
liquid (3.0.6)
maruku (0.7.2)
minitest (5.8.0)
mustache (0.99.8)
rack (1.6.4)
rack-protection (1.5.3)
rack
rake (10.0.3)
rdiscount (2.0.7.2)
rake (10.4.2)
rdiscount (2.1.8)
ronn (0.7.3)
hpricot (>= 0.8.2)
mustache (>= 0.7.0)
rdiscount (>= 1.5.8)
sass (3.2.8)
sinatra (1.4.2)
rack (~> 1.5, >= 1.5.2)
sass (3.4.16)
sinatra (1.4.6)
rack (~> 1.4)
rack-protection (~> 1.4)
tilt (~> 1.3, >= 1.3.4)
syntax (1.0.0)
tilt (1.4.0)
tilt (>= 1.3, < 3)
thread_safe (0.3.5)
tilt (2.0.1)
tzinfo (1.2.2)
thread_safe (~> 0.1)
watch (0.1.0)
yui-compressor (0.9.6)
POpen4 (>= 0.1.4)
yui-compressor (0.12.0)
PLATFORMS
ruby
@@ -59,5 +58,6 @@ PLATFORMS
DEPENDENCIES
bonsai
maruku
mustache (< 1.0)
rake
ronn
+1 -1
View File
@@ -13,7 +13,7 @@ RVM and Ruby 1.9.3 like so:
After that finishes installing, you'll need to make sure RVM is on
your path by doing `source $HOME/.rvm/scripts/rvm`, or just opening a
new shell. See <http://rvm.io> for more info on RVM.
new shell. See <https://rvm.io> for more info on RVM.
Once RVM is installed, you can install all the dependencies for jq's
documentation build by running this from the `docs` directory:
+15 -137
View File
@@ -1,146 +1,24 @@
require 'yaml'
require 'bonsai'
require 'liquid'
require 'maruku'
require 'json'
require 'ronn'
require 'tempfile'
require 'yaml'
module ExtraFilters
def markdownify(input)
Maruku.new(input).to_html
end
def sanitize(input)
input.gsub(/[^a-zA-Z0-9_]/,"")
end
def json(input)
input.to_json
end
def unique(input)
@n = (@n || 0) + 1
input + @n.to_s
end
end
Liquid::Template.register_filter(ExtraFilters)
task :serve do
begin
Bonsai.log "Press Control+C to quit"
require 'rack'
require 'sinatra'
require 'watch'
require 'launchy'
Bonsai.root_dir = Dir.pwd
server = fork {
app = Rack::Builder.app {
map "/jq" do
use Bonsai::StaticPassThrough, :root => Bonsai.root_dir + "/output", :urls => ["/"]
end
run Bonsai::DevelopmentServer
}
Rack::Handler.default.run(app, :Port => 5000) do
Launchy.open("http://localhost:5000/jq/")
end
}
Watch.new("{content,templates,public}/**/*") { Bonsai::Exporter.process! }
rescue Interrupt
Process.kill("QUIT", server)
Process.wait(server)
exit
end
end
task :build do
Bonsai.root_dir = Dir.pwd
Bonsai::Exporter.publish!
end
$BINARIES = {
:osx32 => "--host=i686-apple-darwin10 CFLAGS='-m32 -g -O'",
:osx64 => "--host=i686-apple-darwin10 CFLAGS='-m64 -g -O'",
:win32 => "--host=i686-w64-mingw32 CFLAGS='-g -O'",
:win64 => "--host=x86_64-w64-mingw32 CFLAGS='-g -O'",
:linux32 => "--host=x86_64-linux-gnu CFLAGS='-m32 -g -O'",
:linux64 => "--host=x86_64-linux-gnu CFLAGS='-m64 -g -O'"
}
$BINARIES.each do |name, args|
file "../build/#{name}" do |t|
sh "MAKEFLAGS=-j4 ../scripts/crosscompile #{name} #{args}"
end
task :binaries => ["../build/#{name}"]
end
task :binaries => ["output/download"] do
$BINARIES.each do |name, args|
FileUtils.cp_r "../build/#{name}", "output/download/"
end
end
def load_manual
YAML::ENGINE.yamler = 'syck'
YAML::load(File.open("content/3.manual/manual.yml"))
end
current_dir = File.dirname(__FILE__)
rakefile_manual = File.expand_path(File.join(current_dir, "Rakefile.manual"))
rakefile_website = File.expand_path(File.join(current_dir, "Rakefile.website"))
desc "Build the manpage from the bonsai source of the manual"
task :manpage do
Tempfile.open "manpage" do |f|
manual = load_manual
f.puts manual['manpage_intro']
f.puts manual['body']
manual['sections'].each do |section|
f.puts "## #{section['title'].upcase}\n"
f.puts section['body']
f.puts ""
(section['entries'] || []).each do |entry|
f.puts "### #{entry['title']}\n"
f.puts entry['body']
f.puts ""
(entry['examples'] || []).each do |example|
f.puts " jq '#{example['program']}'"
f.puts " #{example['input']}"
f.puts " => #{example['output'].join(", ")}"
f.puts
end
end
f.puts ""
end
f.puts manual['manpage_epilogue']
f.close
puts Ronn::Document.new(f.path).convert('roff').gsub(/<\/?code>/,"")
end
end
task :manpage_default => ["default_manpage.md"] do
puts Ronn::Document.new("default_manpage.md").convert('roff').gsub(/<\/?code>/,"")
system %(#{$0} -f #{rakefile_manual} manpage)
end
desc "Collect jq unit test cases from the bonsai source of the manual"
task :mantests do
load_manual['sections'].each do |section|
(section['entries'] || []).each do |entry|
(entry['examples'] || []).each do |example|
puts example['program'].gsub("\n", " ")
puts example['input']
example['output'].each do |s| puts s end
puts
end
end
end
system %(#{$0} -f #{rakefile_manual} mantests)
end
directory "output/download/source"
task :tarball => ["output/download/source"] do
sh "cd ..; ./configure && make dist && make distclean"
sh "cp ../jq-*.tar.gz output/download/source"
desc "Build the website from the bonsai sources"
task :build do
system %(#{$0} -f #{rakefile_website} build)
end
desc "Serve a live view of the website on http://localhost:5000/jq/"
task :serve do
system %(#{$0} -f #{rakefile_website} serve)
end
task :dist => [:build, :binaries, :tarball]
+49
View File
@@ -0,0 +1,49 @@
require 'ronn'
require 'tempfile'
require 'yaml'
def load_manual
YAML::load(File.open("content/3.manual/manual.yml"))
end
task :manpage do
Tempfile.open "manpage" do |f|
manual = load_manual
f.puts manual['manpage_intro']
f.puts manual['body']
manual['sections'].each do |section|
f.puts "## #{section['title'].upcase}\n"
f.puts section['body']
f.puts ""
(section['entries'] || []).each do |entry|
f.puts "### #{entry['title']}\n"
f.puts entry['body']
f.puts ""
(entry['examples'] || []).each do |example|
f.puts " jq '#{example['program']}'"
f.puts " #{example['input']}"
f.puts " => #{example['output'].join(", ")}"
f.puts
end
end
f.puts ""
end
f.puts manual['manpage_epilogue']
f.close
puts Ronn::Document.new(f.path).convert('roff').gsub(/<\/?code>/,"")
end
end
task :mantests do
load_manual['sections'].each do |section|
(section['entries'] || []).each do |entry|
(entry['examples'] || []).each do |example|
puts example['program'].gsub("\n", " ")
puts example['input']
example['output'].each do |s| puts s end
puts
end
end
end
end
+76
View File
@@ -0,0 +1,76 @@
require 'bonsai'
require 'json'
require 'liquid'
require 'maruku'
module ExtraFilters
def markdownify(input)
Maruku.new(input).to_html
end
def search_id(input)
input.gsub(/`/, '')
end
def section_id(input)
input.gsub(/[^a-zA-Z0-9_]/, '')
end
def entry_id(input)
input.gsub(/[ `]/, '')
end
def no_paragraph(input)
input.gsub('<p>', '').gsub('</p>', '')
end
def json(input)
input.to_json
end
def unique(input)
@n = (@n || 0) + 1
input + @n.to_s
end
end
Liquid::Template.register_filter(ExtraFilters)
begin
`java 2>&1`
rescue
class Bonsai::Exporter
def self.compress_assets
Bonsai.log "java not found! Not compressing javascript or stylesheets"
end
end
end
task :build do
Bonsai.root_dir = Dir.pwd
Bonsai::Exporter.publish!
end
task :serve do
begin
Bonsai.log "Press Control+C to quit"
require 'rack'
require 'sinatra'
require 'watch'
require 'launchy'
Bonsai.root_dir = Dir.pwd
server = fork {
app = Rack::Builder.app {
map "/jq" do
use Bonsai::StaticPassThrough, :root => Bonsai.root_dir + "/output", :urls => ["/"]
end
run Bonsai::DevelopmentServer
}
Rack::Handler.default.run(app, :Port => 5000) do
Launchy.open("http://localhost:5000/jq/")
end
}
Watch.new("{content,templates,public}/**/*") { Bonsai::Exporter.process! }
rescue Interrupt
Process.kill("QUIT", server)
Process.wait(server)
exit
end
end
+261 -175
View File
@@ -2,124 +2,212 @@ headline: Tutorial
body:
- text: |
Twitter has a JSON API, so let's play with that. This URL gets
us the last 5 tweets about JSON:
- command: "curl 'http://search.twitter.com/search.json?q=json&rpp=5&include_entities=true'"
GitHub has a JSON API, so let's play with that. This URL gets us the last
5 commits from the jq repo.
- command: "curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5'"
result: |
{"completed_in":0.108,"max_id":247677287108067328,"max_id_str":"247677287108067328","next_page":"?page=2&max_id=247677287108067328&q=json&rpp=5&include_entities=1","page":1,"query":"json","refresh_url":"?since_id=247677287108067328&q=json&include_entities=1","results":[{"created_at":"Mon, 17 Sep 2012 12:44:01 +0000","entities":{"hashtags":[],"urls":[{"url":"http:\/\/t.co\/XRvh1ZVw","expanded_url":"http:\/\/jase.im\/Ri7I0M","display_url":"jase.im\/Ri7I0M","indices":[112,132]}],"user_mentions":[{"screen_name":"imagemechanics","name":"Jason Cotterell","id":57271393,"id_str":"57271393","indices":[3,18]}]},"from_user":"_AaronNg","from_user_id":79771704,"from_user_id_str":"79771704","from_user_name":"NgChenChong","geo":null,"id":247677287108067328,"id_str":"247677287108067328","iso_language_code":"en","metadata":{"result_type":"recent"},"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/2523558403\/ek8mo4j4beq84iw28gjl_normal.jpeg","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/2523558403\/ek8mo4j4beq84iw28gjl_normal.jpeg","source":"&lt;a href=&quot;http:\/\/twitter.com\/&quot;&gt;web&lt;\/a&gt;","text":"RT @imagemechanics: iPhone 5 website teardown: How Apple compresses video using JPEG, JSON, and &lt;canvas&gt;.\nhttp:\/\/t.co\/XRvh1ZVw","to_user":null,"to_user_id":0,"to_user_id_str":"0","to_user_name":null}, ...
[
{
"sha": "d25341478381063d1c76e81b3a52e0592a7c997f",
"commit": {
"author": {
"name": "Stephen Dolan",
"email": "mu@netsoc.tcd.ie",
"date": "2013-06-22T16:30:59Z"
},
"committer": {
"name": "Stephen Dolan",
"email": "mu@netsoc.tcd.ie",
"date": "2013-06-22T16:30:59Z"
},
"message": "Merge pull request #162 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161",
"tree": {
"sha": "6ab697a8dfb5a96e124666bf6d6213822599fb40",
"url": "https://api.github.com/repos/stedolan/jq/git/trees/6ab697a8dfb5a96e124666bf6d6213822599fb40"
},
"url": "https://api.github.com/repos/stedolan/jq/git/commits/d25341478381063d1c76e81b3a52e0592a7c997f",
"comment_count": 0
},
"url": "https://api.github.com/repos/stedolan/jq/commits/d25341478381063d1c76e81b3a52e0592a7c997f",
"html_url": "https://github.com/stedolan/jq/commit/d25341478381063d1c76e81b3a52e0592a7c997f",
"comments_url": "https://api.github.com/repos/stedolan/jq/commits/d25341478381063d1c76e81b3a52e0592a7c997f/comments",
"author": {
"login": "stedolan",
...
- text: |
There's lots of info and no whitespace, so to make it a bit more
legible we pipe it through jq, telling jq to just spit the input
back at us using the expression `.`:
GitHub returns nicely formatted JSON. For servers that don't, it can be
helpful to pipe the response through jq to pretty-print it. The simplest
jq program is the expression `.`, which takes the input and produces it
unchanged as output.
- command: "curl 'http://search.twitter.com/search.json?q=json&rpp=5&include_entities=true' | jq '.'"
- command: "curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' | jq '.'"
result: |
{
"since_id_str": "0",
"since_id": 0,
"results_per_page": 5,
"completed_in": 0.108,
"max_id": 247677287108067330,
"max_id_str": "247677287108067328",
"next_page": "?page=2&max_id=247677287108067328&q=json&rpp=5&include_entities=1",
"page": 1,
"query": "json",
"refresh_url": "?since_id=247677287108067328&q=json&include_entities=1",
"results": [
{
"from_user_name": "NgChenChong",
"from_user_id_str": "79771704",
"from_user_id": 79771704,
"from_user": "_AaronNg",
"iso_language_code": "en",
"text": "RT @imagemechanics: iPhone 5 website teardown: How Apple compresses video using JPEG, JSON, and &lt;canvas&gt;.\nhttp://t.co/XRvh1ZVw",
"to_user": null
/* lots more fields... */
[
{
"sha": "d25341478381063d1c76e81b3a52e0592a7c997f",
"commit": {
"author": {
"name": "Stephen Dolan",
"email": "mu@netsoc.tcd.ie",
"date": "2013-06-22T16:30:59Z"
},
"committer": {
"name": "Stephen Dolan",
"email": "mu@netsoc.tcd.ie",
"date": "2013-06-22T16:30:59Z"
},
"message": "Merge pull request #162 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161",
"tree": {
"sha": "6ab697a8dfb5a96e124666bf6d6213822599fb40",
"url": "https://api.github.com/repos/stedolan/jq/git/trees/6ab697a8dfb5a96e124666bf6d6213822599fb40"
},
"url": "https://api.github.com/repos/stedolan/jq/git/commits/d25341478381063d1c76e81b3a52e0592a7c997f",
"comment_count": 0
},
/* lots more results... */
"url": "https://api.github.com/repos/stedolan/jq/commits/d25341478381063d1c76e81b3a52e0592a7c997f",
"html_url": "https://github.com/stedolan/jq/commit/d25341478381063d1c76e81b3a52e0592a7c997f",
"comments_url": "https://api.github.com/repos/stedolan/jq/commits/d25341478381063d1c76e81b3a52e0592a7c997f/comments",
"author": {
"login": "stedolan",
...
- text: |
We can use jq to extract just the first commit.
- command: "curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' | jq '.[0]'"
result: |
{
"sha": "d25341478381063d1c76e81b3a52e0592a7c997f",
"commit": {
"author": {
"name": "Stephen Dolan",
"email": "mu@netsoc.tcd.ie",
"date": "2013-06-22T16:30:59Z"
},
"committer": {
"name": "Stephen Dolan",
"email": "mu@netsoc.tcd.ie",
"date": "2013-06-22T16:30:59Z"
},
"message": "Merge pull request #162 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161",
"tree": {
"sha": "6ab697a8dfb5a96e124666bf6d6213822599fb40",
"url": "https://api.github.com/repos/stedolan/jq/git/trees/6ab697a8dfb5a96e124666bf6d6213822599fb40"
},
"url": "https://api.github.com/repos/stedolan/jq/git/commits/d25341478381063d1c76e81b3a52e0592a7c997f",
"comment_count": 0
},
"url": "https://api.github.com/repos/stedolan/jq/commits/d25341478381063d1c76e81b3a52e0592a7c997f",
"html_url": "https://github.com/stedolan/jq/commit/d25341478381063d1c76e81b3a52e0592a7c997f",
"comments_url": "https://api.github.com/repos/stedolan/jq/commits/d25341478381063d1c76e81b3a52e0592a7c997f/comments",
"author": {
"login": "stedolan",
"id": 79765,
"avatar_url": "https://avatars.githubusercontent.com/u/79765?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/stedolan",
"html_url": "https://github.com/stedolan",
"followers_url": "https://api.github.com/users/stedolan/followers",
"following_url": "https://api.github.com/users/stedolan/following{/other_user}",
"gists_url": "https://api.github.com/users/stedolan/gists{/gist_id}",
"starred_url": "https://api.github.com/users/stedolan/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/stedolan/subscriptions",
"organizations_url": "https://api.github.com/users/stedolan/orgs",
"repos_url": "https://api.github.com/users/stedolan/repos",
"events_url": "https://api.github.com/users/stedolan/events{/privacy}",
"received_events_url": "https://api.github.com/users/stedolan/received_events",
"type": "User",
"site_admin": false
},
"committer": {
"login": "stedolan",
"id": 79765,
"avatar_url": "https://avatars.githubusercontent.com/u/79765?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/stedolan",
"html_url": "https://github.com/stedolan",
"followers_url": "https://api.github.com/users/stedolan/followers",
"following_url": "https://api.github.com/users/stedolan/following{/other_user}",
"gists_url": "https://api.github.com/users/stedolan/gists{/gist_id}",
"starred_url": "https://api.github.com/users/stedolan/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/stedolan/subscriptions",
"organizations_url": "https://api.github.com/users/stedolan/orgs",
"repos_url": "https://api.github.com/users/stedolan/repos",
"events_url": "https://api.github.com/users/stedolan/events{/privacy}",
"received_events_url": "https://api.github.com/users/stedolan/received_events",
"type": "User",
"site_admin": false
},
"parents": [
{
"sha": "54b9c9bdb225af5d886466d72f47eafc51acb4f7",
"url": "https://api.github.com/repos/stedolan/jq/commits/54b9c9bdb225af5d886466d72f47eafc51acb4f7",
"html_url": "https://github.com/stedolan/jq/commit/54b9c9bdb225af5d886466d72f47eafc51acb4f7"
},
{
"sha": "8b1b503609c161fea4b003a7179b3fbb2dd4345a",
"url": "https://api.github.com/repos/stedolan/jq/commits/8b1b503609c161fea4b003a7179b3fbb2dd4345a",
"html_url": "https://github.com/stedolan/jq/commit/8b1b503609c161fea4b003a7179b3fbb2dd4345a"
}
]
}
- text: |
Let's pull out the first tweet:
- command: "curl 'http://search.twitter.com/search.json?q=json&rpp=5&include_entities=true' | jq '.results[0]'"
For the rest of the examples, I'll leave out the `curl` command - it's not
going to change.
There's a lot of info we don't care about there, so we'll restrict it down
to the most interesting fields.
- command: "jq '.[0] | {message: .commit.message, name: .commit.committer.name}'"
result: |
{
"from_user_name": "NgChenChong",
"from_user_id_str": "79771704",
"from_user_id": 79771704,
"from_user": "_AaronNg",
"iso_language_code": "en",
"text": "RT @imagemechanics: iPhone 5 website teardown: How Apple compresses video using JPEG, JSON, and &lt;canvas&gt;.\nhttp://t.co/XRvh1ZVw",
"to_user": null
/* lots more fields... */
},
"message": "Merge pull request #162 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161",
"name": "Stephen Dolan"
}
- text: |
For the rest of the examples, I'll leave out the `curl` command - it's not going to change.
The `|` operator in jq feeds the output of one filter (`.[0]` which gets
the first element of the array in the response) into the input of another
(`{...}` which builds an object out of those fields). You can access
nested attributes, such as `.commit.message`.
There's still a lot of info we don't care about there, so we'll
restrict it down to the most interesting fields.
Now let's get the rest of the commits.
- command: "jq '.results[0] | {from_user, text}'"
- command: "jq '.[] | {message: .commit.message, name: .commit.committer.name}'"
result: |
{
"text": "RT @imagemechanics: iPhone 5 website teardown: How Apple compresses video using JPEG, JSON, and &lt;canvas&gt;.\nhttp://t.co/XRvh1ZVw",
"from_user": "_AaronNg"
"message": "Merge pull request #162 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161",
"name": "Stephen Dolan"
}
{
"message": "Reject all overlong UTF8 sequences.",
"name": "Stephen Dolan"
}
{
"message": "Fix various UTF8 parsing bugs.\n\nIn particular, parse bad UTF8 by replacing the broken bits with U+FFFD\nand resychronise correctly after broken sequences.",
"name": "Stephen Dolan"
}
{
"message": "Fix example in manual for `floor`. See #155.",
"name": "Stephen Dolan"
}
{
"message": "Document floor",
"name": "Nicolas Williams"
}
- text: |
The `|` operator in jq feeds the output of one filter
(`.results[0]` which gets the first element of the results
array) into the input of another (`{from_user, text}` which
builds an object of those two fields).
Now let's get the rest of the tweets:
- command: "jq '.results[] | {from_user, text}'"
result: |
{
"text": "RT @imagemechanics: iPhone 5 website teardown: How Apple compresses video using JPEG, JSON, and &lt;canvas&gt;.\nhttp://t.co/XRvh1ZVw",
"from_user": "_AaronNg"
}
{
"text": "RT @_kud: iPhone 5 website teardown: How Apple compresses video using JPEG, JSON, and &lt;canvas&gt; -- http://t.co/Lhp92IqD",
"from_user": "blouerat"
}
{
"text": "Dynamic Forms Mobile App by pmadiset: Few Forms details are hosted on our server in the form of JSON. This JSON ... http://t.co/7KALdWaX",
"from_user": "cebu_iphone"
}
{
"text": "iPhone 5 website insanity - Video compressing using JPEG, JSON, and &lt;canvas&gt; http://t.co/28Jesbio (Oh #Apple, U So #Awesome...)",
"from_user": "dieswaytoofast"
}
{
"text": "RT @umutm: A very nice web-based JSON editor - http://t.co/M70snaIf",
"from_user": "Leolik"
}
- text: |
`.results[]` returns each element of the results array, one at a
time, which are all fed into `{from_user, text}`.
`.[]` returns each element of the array returned in the response, one at a
time, which are all fed into
`{message: .commit.message, name: .commit.committer.name}`.
Data in jq is represented as streams of JSON values - every jq
expression runs for each value in its input stream, and can
@@ -128,114 +216,112 @@ body:
Streams are serialised by just separating JSON values with
whitespace. This is a `cat`-friendly format - you can just join
two JSON streams together and get a valid JSON stream.
If you want to get the output as a single array, you can tell jq to
"collect" all of the answers by wrapping the filter in square
brackets:
- command: "jq '[.results[] | {from_user, text}]'"
- command: "jq '[.[] | {message: .commit.message, name: .commit.committer.name}]'"
result: |
[
{
"text": "RT @imagemechanics: iPhone 5 website teardown: How Apple compresses video using JPEG, JSON, and &lt;canvas&gt;.\nhttp://t.co/XRvh1ZVw",
"from_user": "_AaronNg"
"message": "Merge pull request #163 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161",
"name": "Stephen Dolan"
},
{
"text": "RT @_kud: iPhone 5 website teardown: How Apple compresses video using JPEG, JSON, and &lt;canvas&gt; -- http://t.co/Lhp92IqD",
"from_user": "blouerat"
"message": "Reject all overlong UTF8 sequences.",
"name": "Stephen Dolan"
},
{
"text": "Dynamic Forms Mobile App by pmadiset: Few Forms details are hosted on our server in the form of JSON. This JSON ... http://t.co/7KALdWaX",
"from_user": "cebu_iphone"
"message": "Fix various UTF8 parsing bugs.\n\nIn particular, parse bad UTF8 by replacing the broken bits with U+FFFD\nand resychronise correctly after broken sequences.",
"name": "Stephen Dolan"
},
{
"text": "iPhone 5 website insanity - Video compressing using JPEG, JSON, and &lt;canvas&gt; http://t.co/28Jesbio (Oh #Apple, U So #Awesome...)",
"from_user": "dieswaytoofast"
"message": "Fix example in manual for `floor`. See #155.",
"name": "Stephen Dolan"
},
{
"text": "RT @umutm: A very nice web-based JSON editor - http://t.co/M70snaIf",
"from_user": "Leolik"
"message": "Document floor",
"name": "Nicolas Williams"
}
]
- text: |
- - -
Next, let's try getting the URLs out of those API results as
well. In each tweet, the Twitter API includes a field called
"entities" which looks like this:
{
"user_mentions": [],
"urls": [{
"indices": [83, 103],
"display_url": "bit.ly/StniqT",
"expanded_url": "http://bit.ly/StniqT",
"url": "http://t.co/28Jesbio"
}],
"hashtags": [
{"indices": [108, 114], "text": "Apple" },
{"indices": [121, 129], "text": "Awesome"}
]
}
Next, let's try getting the URLs of the parent commits out of the
API results as well. In each commit, the GitHub API includes information
about "parent" commits. There can be one or many.
We want to pull out all of the "url" fields inside that array of url
objects, and make a simple list of strings to go along with the
"from_user" and "text" fields we already have.
"parents": [
{
"sha": "54b9c9bdb225af5d886466d72f47eafc51acb4f7",
"url": "https://api.github.com/repos/stedolan/jq/commits/54b9c9bdb225af5d886466d72f47eafc51acb4f7",
"html_url": "https://github.com/stedolan/jq/commit/54b9c9bdb225af5d886466d72f47eafc51acb4f7"
},
{
"sha": "8b1b503609c161fea4b003a7179b3fbb2dd4345a",
"url": "https://api.github.com/repos/stedolan/jq/commits/8b1b503609c161fea4b003a7179b3fbb2dd4345a",
"html_url": "https://github.com/stedolan/jq/commit/8b1b503609c161fea4b003a7179b3fbb2dd4345a"
}
]
- command: "jq '.results[] | {from_user, text, urls: [.entities.urls[].url]}'"
We want to pull out all of the "html_url" fields inside that array of parent
commits and make a simple list of strings to go along with the
"message" and "author" fields we already have.
- command: "jq '[.[] | {message: .commit.message, name: .commit.committer.name, parents: [.parents[].html_url]}]'"
result: |
{
"urls": [
"http://t.co/XRvh1ZVw"
],
"text": "RT @imagemechanics: iPhone 5 website teardown: How Apple compresses video using JPEG, JSON, and &lt;canvas&gt;.\nhttp://t.co/XRvh1ZVw",
"from_user": "_AaronNg"
}
{
"urls": [
"http://t.co/Lhp92IqD"
],
"text": "RT @_kud: iPhone 5 website teardown: How Apple compresses video using JPEG, JSON, and &lt;canvas&gt; -- http://t.co/Lhp92IqD",
"from_user": "blouerat"
}
{
"urls": [
"http://t.co/7KALdWaX"
],
"text": "Dynamic Forms Mobile App by pmadiset: Few Forms details are hosted on our server in the form of JSON. This JSON ... http://t.co/7KALdWaX",
"from_user": "cebu_iphone"
}
{
"urls": [
"http://t.co/28Jesbio"
],
"text": "iPhone 5 website insanity - Video compressing using JPEG, JSON, and &lt;canvas&gt; http://t.co/28Jesbio (Oh #Apple, U So #Awesome...)",
"from_user": "dieswaytoofast"
}
{
"urls": [
"http://t.co/M70snaIf"
],
"text": "RT @umutm: A very nice web-based JSON editor - http://t.co/M70snaIf",
"from_user": "Leolik"
}
[
{
"message": "Merge pull request #162 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161",
"name": "Stephen Dolan",
"parents": [
"https://github.com/stedolan/jq/commit/54b9c9bdb225af5d886466d72f47eafc51acb4f7",
"https://github.com/stedolan/jq/commit/8b1b503609c161fea4b003a7179b3fbb2dd4345a"
]
},
{
"message": "Reject all overlong UTF8 sequences.",
"name": "Stephen Dolan",
"parents": [
"https://github.com/stedolan/jq/commit/ff48bd6ec538b01d1057be8e93b94eef6914e9ef"
]
},
{
"message": "Fix various UTF8 parsing bugs.\n\nIn particular, parse bad UTF8 by replacing the broken bits with U+FFFD\nand resychronise correctly after broken sequences.",
"name": "Stephen Dolan",
"parents": [
"https://github.com/stedolan/jq/commit/54b9c9bdb225af5d886466d72f47eafc51acb4f7"
]
},
{
"message": "Fix example in manual for `floor`. See #155.",
"name": "Stephen Dolan",
"parents": [
"https://github.com/stedolan/jq/commit/3dcdc582ea993afea3f5503a78a77675967ecdfa"
]
},
{
"message": "Document floor",
"name": "Nicolas Williams",
"parents": [
"https://github.com/stedolan/jq/commit/7c4171d414f647ab08bcd20c76a4d8ed68d9c602"
]
}
]
- text: |
Here we're making an object as before, but this time the urls
field is being set to `[.entities.urls[].url]`, which collects
all of the URLs defined in the entities object.
Here we're making an object as before, but this time the `parents`
field is being set to `[.parents[].html_url]`, which collects
all of the parent commit URLs defined in the parents object.
- text: |
- - -
Here endeth the tutorial! There's lots more to play with, go
Here endeth the tutorial! There's lots more to play with. Go
read [the manual](../manual/) if you're interested, and [download
jq](../download/) if you haven't already.
jq](../download/) if you haven't already.
+129 -33
View File
@@ -15,64 +15,160 @@ body:
### Linux
* Binaries for [64-bit](linux64/jq) or [32-bit](linux32/jq) systems.
* For Arch users, a PKGBUILD for jq-1.1 is in the
[AUR](https://aur.archlinux.org/packages.php?ID=63849), as
well as a PKGBUILD for the HEAD of master
([jq-git](https://aur.archlinux.org/packages.php?ID=63850)).
You can install them using
[Yaourt](https://wiki.archlinux.org/index.php/Yaourt) or
manually by following instructions on [Arch Linux's
Wiki](https://wiki.archlinux.org/index.php/Arch_UseRepository).
* jq 1.5 is in the official [Debian](https://packages.debian.org/jq) and
[Ubuntu](http://packages.ubuntu.com/jq) repositories. Install using
`sudo apt-get install jq`.
* Debian/Ubuntu packages are coming Real Soon Now.
* jq 1.5 is in the official
[Fedora](http://pkgs.fedoraproject.org/cgit/jq.git/) repository.
Install using `sudo dnf install jq`.
* jq 1.4 is in the official [openSUSE](https://software.opensuse.org/package/jq)
repository. Install using `sudo zypper install jq`.
* jq 1.5 is in the official
[Arch](https://www.archlinux.org/packages/?sort=&q=jq&maintainer=&flagged=)
repository. Install using `sudo pacman -Sy jq`.
* jq 1.5 binaries for
[64-bit](https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64)
or
[32-bit](https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux32).
* jq 1.4 binaries for
[64-bit](https://github.com/stedolan/jq/releases/download/jq-1.4/jq-linux-x86_64)
or
[32-bit](https://github.com/stedolan/jq/releases/download/jq-1.4/jq-linux-x86).
* jq 1.3 binaries for
[64-bit](https://github.com/stedolan/jq/releases/download/jq-1.3/jq-linux-x86_64)
or
[32-bit](https://github.com/stedolan/jq/releases/download/jq-1.3/jq-linux-x86).
### OS X
* `brew install jq` using [homebrew](http://mxcl.github.com/homebrew/)
* Use [Homebrew](http://brew.sh/) to install jq 1.5 with
`brew install jq`.
* Or, grab prebuilt [64-bit binaries](osx64/jq) or [32-bit
binaries](osx32/jq)
* jq 1.5 binary for
[64-bit](https://github.com/stedolan/jq/releases/download/jq-1.5/jq-osx-amd64).
* jq 1.4 binaries for
[64-bit](https://github.com/stedolan/jq/releases/download/jq-1.4/jq-osx-x86_64)
or
[32-bit](https://github.com/stedolan/jq/releases/download/jq-1.4/jq-osx-x86).
* jq 1.3 binaries for
[64-bit](https://github.com/stedolan/jq/releases/download/jq-1.3/jq-osx-x86_64)
or
[32-bit](https://github.com/stedolan/jq/releases/download/jq-1.3/jq-osx-x86).
### FreeBSD
* `pkg install jq` as root installs a pre-built
[binary package](https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/pkgng-intro.html).
* `make -C /usr/ports/textproc/jq install clean` as root installs the
[jq](https://www.freshports.org/textproc/jq/)
[port](https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/ports-using.html)
from source.
### Solaris
* `pkgutil -i jq` in [OpenCSW](https://www.opencsw.org/p/jq) for Solaris
10+, Sparc and x86.
* jq 1.4 binaries for Solaris 11
[64-bit](https://github.com/stedolan/jq/releases/download/jq-1.4/jq-solaris11-64)
or
[32-bit](https://github.com/stedolan/jq/releases/download/jq-1.4/jq-solaris11-32).
### Windows
* Executables for [64-bit](win64/jq.exe) or [32-bit](win32/jq.exe)
* Use [Chocolatey NuGet](https://chocolatey.org/) to install jq 1.5 with
`chocolatey install jq`.
### From source on Linux or OS X
* jq 1.5 executables for
[64-bit](https://github.com/stedolan/jq/releases/download/jq-1.5/jq-win64.exe)
or
[32-bit](https://github.com/stedolan/jq/releases/download/jq-1.5/jq-win32.exe).
* jq 1.4 executables for
[64-bit](https://github.com/stedolan/jq/releases/download/jq-1.4/jq-win64.exe)
or
[32-bit](https://github.com/stedolan/jq/releases/download/jq-1.4/jq-win32.exe).
* jq 1.3 executables for
[64-bit](https://github.com/stedolan/jq/releases/download/jq-1.3/jq-win64.exe)
or
[32-bit](https://github.com/stedolan/jq/releases/download/jq-1.3/jq-win32.exe).
### Checksums and signatures
SHA-256 checksums are provided for all release and pre-release binaries.
They can be found under
[sig/v1.x/sha256sum.txt](https://github.com/stedolan/jq/tree/master/sig).
The checksums for jq 1.5 are in
[sig/v1.5/sha256sum.txt](https://raw.githubusercontent.com/stedolan/jq/master/sig/v1.5/sha256sum.txt).
Additionally, all binaries are signed by the
[jq Package Signing Key](https://raw.githubusercontent.com/stedolan/jq/master/sig/jq-release.key).
The signatures can be found under
[sig/v1.x/\*.asc](https://github.com/stedolan/jq/tree/master/sig).
The signatures for jq 1.5 are in
[sig/v1.5/\*.asc](https://github.com/stedolan/jq/tree/master/sig/v1.5).
You can use [GnuPG](https://gnupg.org/) to verify a signature by downloading
the signature and running `gpg --verify signature.asc`.
### From source on Linux, OS X, Cygwin, and other POSIX-like operating systems
* [Source tarball for jq 1.5](https://github.com/stedolan/jq/releases/download/jq-1.5/jq-1.5.tar.gz)
You can build it using the usual `./configure && make && sudo
make install` rigmarole.
If you're interested in using the lastest development version, try:
git clone https://github.com/stedolan/jq.git
cd jq
make && sudo make install
autoreconf -i
./configure --disable-maintainer-mode
make
sudo make install
To build it from a git clone, you'll need to install a few
packages first:
* [Flex](http://www.gnu.org/software/flex/)
* [Bison](http://www.gnu.org/software/bison/)
* [Python](http://www.python.org)
* [GCC](http://gcc.gnu.org)
* [Make](http://www.gnu.org/software/make)
* [GCC](https://gcc.gnu.org)
* [Make](https://www.gnu.org/software/make/)
* [Autotools](https://www.gnu.org/software/automake/)
For Linux systems, these will all be in your system's package
manager, and if you do development on the machine they're most
likely already installed.
On OS X, these are all included in Apple's command line tools, which
can be installed from [Xcode](http://developer.apple.com/technologies/tools/).
However, you may find that you need a newer version of Bison than the one provided
by Apple. This can be found in [Homebrew](http://mxcl.github.com/homebrew/)
or [MacPorts](http://macports.org/).
On OS X, these are all included in Apple's command line tools, which can
be installed from [Xcode](https://developer.apple.com/xcode/). However,
you may find that you need a newer version of Bison than the one provided
by Apple. This can be found in [Homebrew](http://brew.sh) or
[MacPorts](https://macports.org/).
The `--disable-maintainer-mode` flag says to use the pre-generated lexer
and parser that come with the code. To compile the lexer and parser also
from source, leave out this flag. You will need to install
[Flex](http://flex.sourceforge.net/) and
[Bison](https://www.gnu.org/software/bison/).
`flex` and `bison` are used to generate the lexer and parser for
jq, and some python scripts generate the UTF8 encoding tables
needed for JSON parsing.
#### Building the documentation
jq's documentation is compiled into static HTML using
[Bonsai](http://www.tinytree.info). To view the documentation
locally, run `rake serve` from the docs/ subdirectory.
[Bonsai](http://www.tinytree.info). To view the documentation
locally, run `rake serve` (or `bundle exec rake serve`) from the
docs/ subdirectory. To build the docs just `rake build` from the
docs subdirectory. You'll need a few Ruby dependencies, which can
be installed by following the instructions in `docs/README.md`.
The man page is built by `make jq.1`, or just `make`, also from
the YAML docs, and you'll still need the Ruby dependencies to
build the manpage.
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+46 -6
View File
@@ -1,9 +1,9 @@
headline: jq
blurb: |
jq is a lightweight and flexible command-line JSON processor.
body1: |
jq is like `sed` for JSON data - you can use it to slice and filter
@@ -14,14 +14,54 @@ body2: |
jq is written in portable C, and it has zero runtime
dependencies. You can download a single binary, `scp` it to a far away
machine, and expect it to work.
machine of the same type, and expect it to work.
body3: |
jq can mangle the data format that you have into the one that you
want with very little effort, and the program to do so is often
shorter and simpler than you'd expect.
tail: |
Go read the [tutorial](tutorial/) for more, or the [manual](manual/)
for *way* more.
Go read the [tutorial](/jq/tutorial/) for more, or the [manual](/jq/manual/)
for *way* more.
Ask questions on [stackoverflow](https://stackoverflow.com/) using the [jq
tag](https://stackoverflow.com/questions/tagged/jq), or on the
[#jq](http://irc.lc/freenode/%23jq/) channel on
[Freenode](https://webchat.freenode.net/).
news:
- date: 15 August 2015
body: |
jq 1.5 released, including new datetime, math, and regexp functions,
try/catch syntax, array and object destructuring, a streaming parser,
and a module system. See installation options on the
[download](/jq/download/) page, and the
[release notes](https://github.com/stedolan/jq/releases/tag/jq-1.5)
for details.
- date: 26 July 2015
body: |
jq 1.5rc2 is available. Get it on the
[releases](https://github.com/stedolan/jq/releases) page.
- date: 01 January 2015
body: |
jq 1.5rc1 is available. Get it on the
[releases](https://github.com/stedolan/jq/releases) page.
- date: 09 June 2014
body: |
jq 1.4 (finally) released! Get it on the [download](/jq/download/) page.
- date: 19 May 2013
body: |
jq 1.3 released.
-22
View File
@@ -1,22 +0,0 @@
jq(1) -- Command-line JSON processor
====================================
## DESCRIPTION
`jq` can transform JSON in various ways, by selecting, iterating,
reducing and otherwise mangling JSON documents.
This version of `jq` was built without a manual, so this manpage is a
stub. For full documentation of the `jq` language, see:
http://stedolan.github.com/jq
## BUGS
Presumably. Report them or discuss them at:
https://github.com/stedolan/jq/issues
## AUTHOR
Stephen Dolan `<mu@netsoc.tcd.ie>`
+2 -2
View File
@@ -12,7 +12,7 @@ FileETag All
</IfModule>
</IfModule>
# Cache, aggressively
# Cache, aggressively
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 10 days"
@@ -25,4 +25,4 @@ FileETag All
# Mime-types
AddType application/vnd.ms-fontobject .eot
AddType font/ttf .ttf
AddType font/otf .otf
AddType font/otf .otf
File diff suppressed because it is too large. Load diff
@@ -1,9 +0,0 @@
/*!
* Bootstrap Responsive v2.1.1
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Designed and built with all the love in the world @twitter by @mdo and @fat.
*/.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*maLine truncated
File diff suppressed because it is too large. Load diff
-9
View File
@@ -1,9 +0,0 @@
/*!
* Bootstrap v2.1.1
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Designed and built with all the love in the world @twitter by @mdo and @fat.
*/article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{width:auto\9;height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluiLine truncated
Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because it is too large. Load diff
-6
View File
@@ -1,6 +0,0 @@
/*!
* Bootstrap.js by @fat & @mdo
* Copyright 2012 Twitter, Inc.
* http://www.apache.org/licenses/LICENSE-2.0.txt
*/
!function(e){e(function(){"use strict";e.support.transition=function(){var e=function(){var e=document.createElement("bootstrap"),t={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},n;for(n in t)if(e.style[n]!==undefined)return t[n]}();return e&&{end:e}}()})}(window.jQuery),!function(e){"use strict";var t='[data-dismiss="alert"]',n=function(n){e(n).on("click",t,this.close)};n.prototype.close=function(t){function s(){i.trigger("closed").remove()}var n=e(this),r=n.attr("data-target"),i;r||(r=n.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,"")),i=e(r),t&&t.preventDefault(),i.length||(i=n.hasClass("alert")?n:n.parent()),i.trigger(t=e.Event("close"));if(t.isDefaultPrevented())return;i.removeClass("in"),e.support.transition&&i.hasClass("fade")?i.on(e.support.transition.end,s):s()},e.fn.alert=function(t){return this.each(function(){var r=e(this),i=r.data("alert");i||r.data("alert",i=new n(this)),typeof t=="string"&&i[t].call(r)})},e.fn.alert.Constructor=n,e(function(){e("body").on("click.alert.data-api",t,n.prototype.close)})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.button.defaults,n)};t.prototype.setState=function(e){var t="disabled",n=this.$element,r=n.data(),i=n.is("input")?"val":"html";e+="Text",r.resetText||n.data("resetText",n[i]()),n[i](r[e]||this.options[e]),setTimeout(function(){e=="loadingText"?n.addClass(t).attr(t,t):n.removeClass(t).removeAttr(t)},0)},t.prototype.toggle=function(){var e=this.$element.closest('[data-toggle="buttons-radio"]');e&&e.find(".active").removeClass("active"),this.$element.toggleClass("active")},e.fn.button=function(n){return this.each(function(){var r=e(this),i=r.data("button"),s=typeof n=="object"&&n;i||r.data("button",i=new t(this,s)),n=="toggle"?i.toggle():n&&i.setState(n)})},e.fn.button.defaults={loadingText:"loading..."},e.fn.button.Constructor=t,e(function(){e("body").on("click.button.data-api","[data-toggle^=button]",function(t){var n=e(t.target);n.hasClass("btn")||(n=n.closest(".btn")),n.button("toggle")})})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=n,this.options.slide&&this.slide(this.options.slide),this.options.pause=="hover"&&this.$element.on("mouseenter",e.proxy(this.pause,this)).on("mouseleave",e.proxy(this.cycle,this))};t.prototype={cycle:function(t){return t||(this.paused=!1),this.options.interval&&!this.paused&&(this.interval=setInterval(e.proxy(this.next,this),this.options.interval)),this},to:function(t){var n=this.$element.find(".item.active"),r=n.parent().children(),i=r.index(n),s=this;if(t>r.length-1||t<0)return;return this.sliding?this.$element.one("slid",function(){s.to(t)}):i==t?this.pause().cycle():this.slide(t>i?"next":"prev",e(r[t]))},pause:function(t){return t||(this.paused=!0),this.$element.find(".next, .prev").length&&e.support.transition.end&&(this.$element.trigger(e.support.transition.end),this.cycle()),clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(t,n){var r=this.$element.find(".item.active"),i=n||r[t](),s=this.interval,o=t=="next"?"left":"right",u=t=="next"?"first":"last",a=this,f=e.Event("slide",{relatedTarget:i[0]});this.sliding=!0,s&&this.pause(),i=i.length?i:this.$element.find(".item")[u]();if(i.hasClass("active"))return;if(e.support.transition&&this.$element.hasClass("slide")){this.$element.trigger(f);if(f.isDefaultPrevented())return;i.addClass(t),i[0].offsetWidth,r.addClass(o),i.addClass(o),this.$element.one(e.support.transition.end,function(){i.removeClass([t,o].join(" ")).addClass("active"),r.removeClass(["active",o].join(" ")),a.sliding=!1,setTimeout(function(){a.$element.trigger("slid")},0)})}else{this.$element.trigger(f);if(f.isDefaultPrevented())return;r.removeClass("active"),i.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return s&&this.cycle(),this}},e.fn.carousel=function(n){return this.each(function(){var r=e(this),i=r.data("carousel"),s=e.extend({},e.fn.carousel.defaults,typeof n=="object"&&n),o=typeof n=="string"?n:s.slide;i||r.data("carousel",i=new t(this,s)),typeof n=="number"?i.to(n):o?i[o]():s.interval&&i.cycle()})},e.fn.carousel.defaults={interval:5e3,pause:"hover"},e.fn.carousel.Constructor=t,e(function(){e("body").on("click.carousel.data-api","[data-slide]",function(t){var n=e(this),r,i=e(n.attr("data-target")||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,"")),s=!i.data("modal")&&e.extend({},i.data(),n.data());i.carousel(s),t.preventDefault()})})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.collapse.defaults,n),this.options.parent&&(this.$parent=e(this.options.parent)),this.options.toggle&&this.toggle()};t.prototype={constructor:t,dimension:function(){var e=this.$element.hLine truncated
+154 -65
View File
@@ -1,85 +1,79 @@
@charset "utf-8";
body {
padding-top: 60px;
padding-top: 80px;
}
footer {
background-color: #F5F5F5;
padding: 40px 0;
height: 100px;
margin-top: 40px;
color: #999999;
.container {
max-width: 970px;
}
section {
padding-top: 30px;
}
.manual-example {
border-top: 1px solid #E5E5E5;
}
.manual-example td {
white-space: pre-wrap;
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
}
.manual-example td.jqprogram {
font-weight: bold;
}
.manual-example th {
text-align: right;
padding-right: 10px;
}
.tutorial-example {
position: relative;
margin-bottom: 10px;
}
.tutorial-example pre {
margin-bottom: 0px;
}
.tutorial-example a {
position: absolute;
top: 0px;
right: 0px;
padding: 15px 8px;
color: #777777;
font-weight: bold;
line-height: 10px;
font-size: 12px;
border-left: 1px solid #DDDDDD;
bottom: 0;
display: block;
}
/* index.liquid *******************************************/
#blurb {
padding-top: 40px;
padding-right: 50px;
}
#blurb p {
font-size: 20pt;
}
#blurb .btn-group {
margin-top: 20px;
p {
font-size: 1.9em;
}
.btn-group {
margin: 4px;
}
}
#multiblurb {
line-height: 1.7;
text-align: center;
font-size: 12pt;
code {
border: 0;
font-size: 12pt;
}
}
#multiblurb code {
border: 0;
#news {
font-size: 12pt;
.date {
font-style: italic;
}
}
/* default.liquid *****************************************/
.tutorial-example {
position: relative;
margin-bottom: 10px;
pre {
margin-bottom: 0px;
}
a {
position: absolute;
top: 0px;
right: 0px;
padding: 15px 8px;
color: #777777;
font-weight: bold;
line-height: 10px;
font-size: 12px;
border-left: 1px solid #DDDDDD;
display: block;
}
.accordion-body pre {
margin: 0 4px;
border-top: 0;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
}
@media print {
.tutorial-example a {
display: none;
}
}
/* manual.liquid ******************************************/
section {
padding-top: 24px;
}
h3 code {
@@ -87,6 +81,101 @@ h3 code {
font-size: 20px;
}
@media(max-width: 991px){
#navcolumn {
/* Put nav column above manual content */
position: relative !important;
margin-bottom: 60px;
}
}
@media(min-width: 992px) {
#manualcontent {
/* Put nav column left of manual content */
padding-left: 280px;
}
}
.nav-pills {
li a {
padding: 8px 12px;
}
margin-bottom: 20px;
}
.manual-example table {
border-top: 1px solid #E5E5E5;
td {
white-space: pre-wrap;
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
}
td.jqprogram {
font-weight: bold;
}
th {
text-align: right;
padding-right: 10px;
}
}
@media print {
#navcolumn {
display: none !important;
}
.manual-example {
display: block !important;
height: auto !important;
}
.jqplay-btn {
display: none !important;
}
}
/* shared/_footer.liquid **********************************/
footer {
background-color: #F5F5F5;
padding: 20px 0;
margin-top: 40px;
color: #999999;
text-align: center;
}
p {
margin: 8px 0;
}
}
/* typeahead **********************************************/
.twitter-typeahead {
width: 100%;
}
.tt-menu {
width: 100%;
background-color: #fff;
padding: 8px 0;
border: 1px solid #ccc;
border: 1px solid rgba(0, 0, 0, 0.2);
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
-webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
-moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
box-shadow: 0 5px 10px rgba(0,0,0,.2);
}
.tt-suggestion {
padding: 3px 20px;
&:hover {
cursor: pointer;
color: #fff;
background-color: #446e9b;
}
&.tt-cursor {
color: #fff;
background-color: #446e9b;
}
p {
margin: 0;
}
}
+52
View File
@@ -0,0 +1,52 @@
var section_names = function(q) {
if (!q) {
return [];
}
var matches = [];
q = q.toLowerCase();
$.each(section_map, function(k, v) {
if (k.toLowerCase().indexOf(q) != -1) {
matches.push(k);
}
});
matches.sort(function(a, b) {
// shortest to longest
return a.length - b.length;
});
return matches;
}
var section_names_cb = function(q, cb) {
cb(section_names(q));
}
var go_to_section = function() {
query = $('#searchbox').val();
results = section_names(query);
if (results.length == 0) {
return;
}
result = results[0];
location.hash = '#' + section_map[result];
if (result != query) {
$('#searchbox').val(result);
}
}
$(function(){
$('#searchbox').typeahead(
{hint: false, highlight: true, minLength: 1},
{name: "contents", source: section_names_cb, limit: 6}
).on('typeahead:selected', function(e, data) {
go_to_section();
});
$('#searchbox').change(go_to_section);
});
// add "Run" button to execute examples on jqplay.org
$(function() {
$.each($('.manual-example table'), function(index, value) {
$value = $(value)
var j = $value.find('tr:nth-child(2) td:first').text();
var q = $value.find('.jqprogram').text().replace(/^jq /, '').replace(/^'(.+)'$/, '$1');
var url = 'https://jqplay.org/jq?q=' + encodeURIComponent(q) +'&j=' + encodeURIComponent(j)
var $last_tr = $value.find('tr:last');
$last_tr.after('<tr class="jqplay-btn"><th><a href="' + url + '" class="btn btn-primary btn-sm">Run</a></th><th></th></tr><tr><th></th><th></th></tr>');
});
});
+2 -11
View File
@@ -1,18 +1,9 @@
# The key value pairs found below are available within the templates.
:url: http://stedolan.github.io/jq
:url: https://stedolan.github.io/jq
# This line is modified by the Makefile. To change the version number,
# edit the Autoconf version number at the top of configure.ac
jq_version: 1.2
jq_version: "1.4-2-g15c4a7f-dirty"
root: '/jq'
footer: |
This website is made with [Bonsai](http://www.tinytree.info) and
[Twitter Bootstrap](http://twitter.github.com/bootstrap/), themed
with [Bootswatch](http://bootswatch.com).
jq is licensed under the MIT license (code) and the
[CC-BY-3.0](http://creativecommons.org/licenses/by/3.0/) license
(docs).
+11 -11
View File
@@ -1,34 +1,34 @@
<!DOCTYPE html>
<html lang="en">
{% include "shared/head" %}
{% include "shared/head" %}
<body id="{{slug}}">
{% include "shared/header" %}
{% include "shared/navbar" %}
<div class="container">
<div class="row">
<h1>{{headline}}</h1>
{% for item in body %}
{% if item.text %}
{{ item.text | markdownify }}
{{ item.text | replace: '$JQ_VERSION', jq_version | markdownify }}
{% endif %}
{% if item.command %}
{% if item.command %}
{% capture resultID %}{{ "result" | unique}}{% endcapture %}
<div class="tutorial-example">
<div class="accordion-heading">
<pre>{{item.command}}</pre>
<a data-toggle="collapse" href="#{{resultID}}">Show result</a>
</div>
<div id="{{resultID}}" class="accordion-body collapse"><pre>{{item.result}}</pre></div>
<div id="{{resultID}}" class="accordion-body collapse">
<pre>{{item.result}}</pre>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
{% include "shared/footer" %}
{% include "shared/footer" %}
</body>
</html>
+55 -23
View File
@@ -1,41 +1,73 @@
<!DOCTYPE html>
<html lang="en">
{% include "shared/head" %}
{% include "shared/head" %}
<body id="{{slug}}">
{% include "shared/header" %}
{% include "shared/navbar" %}
<div class="container">
<div class="row">
<div class="hero-unit">
<img src="{{root}}/jq.png" style="width: 400px; height: 220px; float: left; margin-right: 60px">
<div id="blurb">
{{blurb | markdownify}}
<div class="btn-group" style="float:right">
<a class="btn btn-primary dropdown-toggle" data-toggle="dropdown" href="#">
Download jq-{{jq_version}}
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="{{root}}/download/linux64/jq">Linux (64-bit)</a></li>
<li><a href="{{root}}/download/osx64/jq">OS X (64-bit)</a></li>
<li><a href="{{root}}/download/">Other platforms and source</a></li>
</ul>
<div class="jumbotron">
<div class="row">
<div class="col-sm-6">
<img src="{{root}}/jq.png" class="img-responsive" alt="jq logo"
width="400" height="220">
</div>
<div class="col-sm-6">
<div id="blurb">
{{blurb | markdownify}}
<div class="btn-toolbar" role="toolbar">
<div class="btn-group" role="group">
<a class="btn btn-primary dropdown-toggle" data-toggle="dropdown" href="#">
Download jq 1.5
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64">Linux (64-bit)</a></li>
<li><a href="https://github.com/stedolan/jq/releases/download/jq-1.5/jq-osx-amd64">OS X (64-bit)</a></li>
<li><a href="https://github.com/stedolan/jq/releases/download/jq-1.5/jq-win64.exe">Windows (64-bit)</a></li>
<li><a href="/jq/download/">Other platforms, older versions, and source</a></li>
</ul>
</div>
<div class="btn-group">
<a class="btn btn-primary" href="https://jqplay.org">
Try online at jqplay.org!
</a>
</div>
</div>
</div>
</div>
</div>
<div style="clear:both;"></div>
</div>
</div>
<div class="row" id="multiblurb">
<div class="span4">{{body1 | markdownify}}</div>
<div class="span4">{{body2 | markdownify}}</div>
<div class="span4">{{body3 | markdownify}}</div>
<div class="col-sm-4">{{body1 | markdownify}}</div>
<div class="col-sm-4">{{body2 | markdownify}}</div>
<div class="col-sm-4">{{body3 | markdownify}}</div>
</div>
<div class="row" style="text-align:center; margin-top: 30px">
{{tail | markdownify}}
</div>
<div class="row">
<h2>News</h2>
<div id="news">
<ul>
{% for item in news %}
<li>
<span class="date">{{item.date}}</span>
{{item.body | markdownify}}
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
{% include "shared/footer" %}
{% include "shared/footer" %}
</body>
</html>
+68 -79
View File
@@ -1,110 +1,99 @@
<!DOCTYPE html>
<html lang="en">
{% include "shared/head" %}
{% include "shared/head" %}
<body id="{{slug}}" data-spy="scroll" data-target="#navcolumn" data-offset="100">
{% include "shared/header" %}
{% include "shared/navbar" %}
<div class="container">
<div class="row">
<div class="span3" id="navcolumn">
<div class="affix">
<div class="affix" id="navcolumn">
<h4>Contents</h4>
<ul class="nav nav-pills nav-stacked">
{% for section in sections %}
<li {% if forloop.first %} class="active" {% endif %}>
<a href="#{{section.title | sanitize}}">{{section.title}}</a>
<li>
<a href="#{{section.title | section_id}}">{{section.title}}</a>
</li>
{% endfor %}
</ul>
<form class="form-search">
<script type="text/javascript">
var section_map = {
{% for section in sections %}
{% for entry in section.entries %}
{{entry.title | json}} : {{entry.title | sanitize | json}},
{% endfor %}
{{section.title | json}} : {{section.title | sanitize | json}}
{% unless forloop.last %},{% endunless %}
{% endfor %}
};
var section_names = $.map(section_map, function(v,k){return k});
$(function(){
$('#searchbox').typeahead({source: section_names})
$('#searchbox').change(function() {
if ($(this).val() in section_map) {
location.hash = '#' + section_map[$(this).val()];
}
});
});
</script>
<form class="form-group" onsubmit="go_to_section(); return false;">
<input type="text"
class="input-medium search-query"
placeholder="Search"
autocomplete="off"
id="searchbox">
class="form-control"
placeholder="Search"
autocomplete="off"
id="searchbox">
</form>
</div>
</div>
<div class="span9">
<div id="manualcontent">
<h1>{{headline}}</h1>
{{ history | markdownify }}
{{ body | markdownify }}
{% for section in sections %}
<section id="{{section.title | sanitize}}">
<section id="{{section.title | section_id}}">
<h2>{{section.title}}</h2>
{{section.body | markdownify}}
{% for entry in section.entries %}
<section id="{{entry.title | sanitize}}">
<h3>
{{entry.title | markdownify}}
{% if entry.subtitle %}<small>{{entry.subtitle}}</small>{% endif %}
</h3>
{{entry.body | markdownify}}
<section id="{{entry.title | entry_id}}">
<h3>
{{entry.title | markdownify | no_paragraph}}
{% if entry.subtitle %}<small>{{entry.subtitle}}</small>{% endif %}
</h3>
{{entry.body | markdownify}}
{% if entry.examples %}
<div>
{% capture exampleID %}{{ "" | unique }}{% endcapture %}
<a data-toggle="collapse" href="#example{{exampleID}}">
<i class="icon-chevron-right"></i>
{% if entry.examples[1] %}Examples{%else%}Example{%endif%}
</a>
<div id="example{{exampleID}}" class="collapse">
{% for example in entry.examples %}
<table class="manual-example">
<tr><th></th><td class="jqprogram">jq '{{example.program}}'</td></tr>
<tr><th>Input</th><td>{{example.input}}</td></tr>
{% unless example.output[0] %}
<tr>
<th>Output</th>
<td><i>none</i></td>
</tr>
{% endunless %}
{% for output in example.output %}
<tr>
{% if forloop.index == 1 %}
<th>Output</th>
{% else %}
<th></th>
{% endif %}
<td>{{output}}</td>
</tr>
{% if entry.examples %}
<div>
{% capture exampleID %}{{ "" | unique }}{% endcapture %}
<a data-toggle="collapse" href="#example{{exampleID}}">
<i class="glyphicon glyphicon-chevron-right"></i>
{% if entry.examples[1] %}Examples{%else%}Example{%endif%}
</a>
<div id="example{{exampleID}}" class="manual-example collapse">
{% for example in entry.examples %}
<table>
<tr><th></th><td class="jqprogram">jq '{{example.program | escape}}'</td></tr>
<tr><th>Input</th><td>{{example.input | escape}}</td></tr>
{% unless example.output[0] %}
<tr>
<th>Output</th>
<td><i>none</i></td>
</tr>
{% endunless %}
{% for output in example.output %}
<tr>
{% if forloop.index == 1 %}
<th>Output</th>
{% else %}
<th></th>
{% endif %}
<td>{{output | escape}}</td>
</tr>
{% endfor %}
</table>
{% endfor %}
</table>
{% endfor %}
</div>
</div>
</div>
{% endif %}
</section>
{% endif %}
</section>
{% endfor %}
</section>
{% endfor %}
</div>
</div>
</div>
{% include "shared/footer" %}
{% include "shared/footer" %}
<script>
var section_map = {
{% for section in sections %}
{% for entry in section.entries %}
{{entry.title | search_id | json}} : {{entry.title | entry_id | json}},
{% endfor %}
{{section.title | search_id | json}} : {{section.title | section_id | json}}
{% unless forloop.last %},{% endunless %}
{% endfor %}
};
</script>
<script src="{{root}}/js/manual-search.js"></script>
</body>
</html>
+10 -5
View File
@@ -1,5 +1,10 @@
<footer>
<div class="container">
{{ footer | markdownify }}
</div>
</footer>
<footer>
<div class="container">
<p>This website is made with <a href="http://www.tinytree.info">Bonsai</a> and <a href="http://getbootstrap.com">Bootstrap</a>, themed with <a href="https://bootswatch.com">Bootswatch</a>.</p>
<p>jq is licensed under the MIT license (code) and the <a href="https://creativecommons.org/licenses/by/3.0/">CC-BY-3.0</a> license (docs).</p>
</div>
</footer>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js" integrity="sha256-Sk3nkD6mLTMOF0EOpNtsIry+s1CsaqQC1rVLTAy+0yc= sha512-K1qjQ+NcF2TYO/eI3M6v8EiNYZfA95pQumfvcVrTHtwQVDG+aHRqLi/ETn2uB+1JqwYqVG3LIvdm9lj6imS/pQ==" crossorigin="anonymous"></script>
<script src="https://twitter.github.io/typeahead.js/releases/0.11.1/typeahead.bundle.js"></script>
+17 -12
View File
@@ -1,12 +1,17 @@
<head>
<meta charset=UTF-8>
<title>{{headline}}</title>
<link rel="stylesheet" href="{{root}}/bootstrap/css/bootstrap.css" type="text/css">
<link rel="stylesheet" href="{{root}}/css/base.css" type="text/css">
<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script src="{{root}}/bootstrap/js/bootstrap.js"></script>
</head>
<head>
<script>
if ((window.location.host == "stedolan.github.io") && (window.location.protocol != "https:"))
window.location.protocol = "https";
</script>
<meta charset="utf-8">
<title>{{headline}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<link rel="canonical" href="{{url}}{{permalink | remove:'/index'}}" />
<link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.5/spacelab/bootstrap.min.css" rel="stylesheet" integrity="sha256-j7Dtnd7ZjexEiPNbscbopFn9+Cs0b3TLipKsWAPHZIM= sha512-RFhfi6P8zWMAJrEGU+CPjuxPh3r/UUBGqQ+/o6WKPIVZmQqeOipGotH2ihRULuQ8wsMBoK15TSZqc/7VYWyuIw==" crossorigin="anonymous">
<link rel="stylesheet" href="{{root}}/css/base.css" type="text/css">
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
-24
View File
@@ -1,24 +0,0 @@
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="brand" href="{{root}}/">jq</a>
<div class="nav-collapse collapse">
<ul class="nav">
{% for item in navigation %}
<li {% if item.permalink == permalink %} class="active" {% endif %}>
<a href="{{root}}{{item.permalink}}">{{item.name}}</a>
</li>
{% endfor %}
<li><a href="https://github.com/stedolan/jq/issues">Issues</a></li>
<li><a href="https://github.com/stedolan/jq">Source</a></li>
</ul>
</div>
</div>
</div>
</div>
+27
View File
@@ -0,0 +1,27 @@
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#nav-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="{{root}}/">jq</a>
</div>
<div class="navbar-collapse collapse" id="nav-collapse">
<ul class="nav navbar-nav">
{% for item in navigation %}
<li {% if item.permalink == permalink %} class="active" {% endif %}>
<a href="{{root}}{{item.permalink}}">{{item.name}}</a>
</li>
{% endfor %}
<li><a href="https://github.com/stedolan/jq/issues">Issues</a></li>
<li><a href="https://github.com/stedolan/jq">Source</a></li>
<li><a href="https://jqplay.org">Try online!</a></li>
<li><a href="https://raw.githubusercontent.com/stedolan/jq/master/NEWS">News</a></li>
</ul>
</div>
</div>
</div>
-538
View File
@@ -1,538 +0,0 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "execute.h"
#include "opcode.h"
#include "bytecode.h"
#include "forkable_stack.h"
#include "frame_layout.h"
#include "jv_alloc.h"
#include "jq_parser.h"
#include "locfile.h"
#include "jv.h"
#include "jv_aux.h"
#include "parser.h"
#include "builtin.h"
typedef struct {
jv value;
int pathidx;
} stackval;
struct jq_state {
struct forkable_stack data_stk;
struct forkable_stack frame_stk;
struct forkable_stack fork_stk;
jv* pathbuf;
int pathsize; // number of allocated elements
int debug_trace_enabled;
};
int path_push(jq_state *jq, stackval sv, jv val) {
int pos = sv.pathidx;
assert(pos <= jq->pathsize);
assert(pos >= 0);
if (pos == jq->pathsize) {
int oldpathsize = jq->pathsize;
jq->pathsize = oldpathsize ? oldpathsize * 2 : 100;
jq->pathbuf = jv_mem_realloc(jq->pathbuf, sizeof(jq->pathbuf[0]) * jq->pathsize);
for (int i=oldpathsize; i<jq->pathsize; i++) {
jq->pathbuf[i] = jv_invalid();
}
}
jv_free(jq->pathbuf[pos]);
jq->pathbuf[pos] = val;
return pos + 1;
}
stackval stackval_replace(stackval value, jv newjs) {
jv_free(value.value);
stackval s = {newjs, value.pathidx};
return s;
}
// Probably all uses of this function are bugs
stackval stackval_root(jv v) {
stackval s = {v, 0};
return s;
}
typedef struct {
FORKABLE_STACK_HEADER;
stackval sv;
} data_stk_elem;
void stack_push(jq_state *jq, stackval val) {
assert(jv_is_valid(val.value));
data_stk_elem* s = forkable_stack_push(&jq->data_stk, sizeof(data_stk_elem));
s->sv = val;
}
stackval stack_pop(jq_state *jq) {
data_stk_elem* s = forkable_stack_peek(&jq->data_stk);
stackval sv = s->sv;
if (!forkable_stack_pop_will_free(&jq->data_stk)) {
sv.value = jv_copy(sv.value);
}
forkable_stack_pop(&jq->data_stk);
assert(jv_is_valid(sv.value));
return sv;
}
struct forkpoint {
FORKABLE_STACK_HEADER;
struct forkable_stack_state saved_data_stack;
struct forkable_stack_state saved_call_stack;
};
void stack_save(jq_state *jq){
struct forkpoint* fork = forkable_stack_push(&jq->fork_stk, sizeof(struct forkpoint));
forkable_stack_save(&jq->data_stk, &fork->saved_data_stack);
forkable_stack_save(&jq->frame_stk, &fork->saved_call_stack);
}
void stack_switch(jq_state *jq) {
struct forkpoint* fork = forkable_stack_peek(&jq->fork_stk);
forkable_stack_switch(&jq->data_stk, &fork->saved_data_stack);
forkable_stack_switch(&jq->frame_stk, &fork->saved_call_stack);
}
int stack_restore(jq_state *jq){
while (!forkable_stack_empty(&jq->data_stk) &&
forkable_stack_pop_will_free(&jq->data_stk)) {
jv_free(stack_pop(jq).value);
}
while (!forkable_stack_empty(&jq->frame_stk) &&
forkable_stack_pop_will_free(&jq->frame_stk)) {
frame_pop(&jq->frame_stk);
}
if (forkable_stack_empty(&jq->fork_stk)) {
return 0;
} else {
struct forkpoint* fork = forkable_stack_peek(&jq->fork_stk);
forkable_stack_restore(&jq->data_stk, &fork->saved_data_stack);
forkable_stack_restore(&jq->frame_stk, &fork->saved_call_stack);
forkable_stack_pop(&jq->fork_stk);
return 1;
}
}
static struct closure make_closure(struct forkable_stack* stk, frame_ptr fr, uint16_t* pc) {
uint16_t level = *pc++;
uint16_t idx = *pc++;
fr = frame_get_level(stk, fr, level);
if (idx & ARG_NEWCLOSURE) {
int subfn_idx = idx & ~ARG_NEWCLOSURE;
assert(subfn_idx < frame_self(fr)->bc->nsubfunctions);
struct closure cl = {frame_self(fr)->bc->subfunctions[subfn_idx],
forkable_stack_to_idx(stk, fr)};
return cl;
} else {
return *frame_closure_arg(fr, idx);
}
}
void print_error(jv value) {
assert(!jv_is_valid(value));
jv msg = jv_invalid_get_msg(value);
if (jv_get_kind(msg) == JV_KIND_STRING) {
fprintf(stderr, "jq: error: %s\n", jv_string_value(msg));
}
jv_free(msg);
}
#define ON_BACKTRACK(op) ((op)+NUM_OPCODES)
jv jq_next(jq_state *jq) {
jv cfunc_input[MAX_CFUNCTION_ARGS];
assert(!forkable_stack_empty(&jq->frame_stk));
uint16_t* pc = *frame_current_retaddr(&jq->frame_stk);
frame_pop(&jq->frame_stk);
assert(!forkable_stack_empty(&jq->frame_stk));
int backtracking = 0;
while (1) {
uint16_t opcode = *pc;
if (jq->debug_trace_enabled) {
dump_operation(frame_current_bytecode(&jq->frame_stk), pc);
printf("\t");
const struct opcode_description* opdesc = opcode_describe(opcode);
data_stk_elem* param = 0;
int stack_in = opdesc->stack_in;
if (stack_in == -1) stack_in = pc[1];
for (int i=0; i<stack_in; i++) {
if (i == 0) {
param = forkable_stack_peek(&jq->data_stk);
} else {
printf(" | ");
param = forkable_stack_peek_next(&jq->data_stk, param);
}
if (!param) break;
jv_dump(jv_copy(param->sv.value), 0);
printf("<%d>", jv_get_refcnt(param->sv.value));
}
if (backtracking) printf("\t<backtracking>");
printf("\n");
}
if (backtracking) {
opcode = ON_BACKTRACK(opcode);
backtracking = 0;
}
pc++;
switch (opcode) {
default: assert(0 && "invalid instruction");
case LOADK: {
jv v = jv_array_get(jv_copy(frame_current_bytecode(&jq->frame_stk)->constants), *pc++);
assert(jv_is_valid(v));
stack_push(jq, stackval_replace(stack_pop(jq), v));
break;
}
case DUP: {
stackval v = stack_pop(jq);
stackval v2 = v;
v2.value = jv_copy(v.value);
stack_push(jq, v);
stack_push(jq, v2);
break;
}
case DUP2: {
stackval keep = stack_pop(jq);
stackval v = stack_pop(jq);
stackval v2 = v;
v2.value = jv_copy(v.value);
stack_push(jq, v);
stack_push(jq, keep);
stack_push(jq, v2);
break;
}
case SWAP: {
stackval a = stack_pop(jq);
stackval b = stack_pop(jq);
stack_push(jq, a);
stack_push(jq, b);
break;
}
case POP: {
jv_free(stack_pop(jq).value);
break;
}
case APPEND: {
// FIXME paths
jv v = stack_pop(jq).value;
uint16_t level = *pc++;
uint16_t vidx = *pc++;
frame_ptr fp = frame_get_level(&jq->frame_stk, frame_current(&jq->frame_stk), level);
jv* var = frame_local_var(fp, vidx);
assert(jv_get_kind(*var) == JV_KIND_ARRAY);
*var = jv_array_append(*var, v);
break;
}
case INSERT: {
stackval stktop = stack_pop(jq);
jv v = stack_pop(jq).value;
jv k = stack_pop(jq).value;
stackval objv = stack_pop(jq);
assert(jv_get_kind(k) == JV_KIND_STRING);
assert(jv_get_kind(objv.value) == JV_KIND_OBJECT);
objv.value = jv_object_set(objv.value, k, v);
stack_push(jq, objv);
stack_push(jq, stktop);
break;
}
// FIXME: loadv/storev may do too much copying/freeing
case LOADV: {
uint16_t level = *pc++;
uint16_t v = *pc++;
frame_ptr fp = frame_get_level(&jq->frame_stk, frame_current(&jq->frame_stk), level);
jv* var = frame_local_var(fp, v);
if (jq->debug_trace_enabled) {
printf("V%d = ", v);
jv_dump(jv_copy(*var), 0);
printf("\n");
}
stack_push(jq, stackval_replace(stack_pop(jq), jv_copy(*var)));
break;
}
case STOREV: {
uint16_t level = *pc++;
uint16_t v = *pc++;
frame_ptr fp = frame_get_level(&jq->frame_stk, frame_current(&jq->frame_stk), level);
jv* var = frame_local_var(fp, v);
stackval val = stack_pop(jq);
if (jq->debug_trace_enabled) {
printf("V%d = ", v);
jv_dump(jv_copy(val.value), 0);
printf("\n");
}
jv_free(*var);
*var = val.value;
break;
}
case GETPATH: {
stackval path_end = stack_pop(jq);
stackval path_start = stack_pop(jq);
jv_free(path_end.value);
jv path = jv_array();
for (int i=path_start.pathidx; i<path_end.pathidx; i++) {
path = jv_array_set(path, i, jv_copy(jq->pathbuf[i]));
}
stack_push(jq, stackval_replace(path_start, path));
break;
}
case INDEX: {
stackval t = stack_pop(jq);
jv k = stack_pop(jq).value;
int pathidx = path_push(jq, t, jv_copy(k));
jv v = jv_get(t.value, k);
if (jv_is_valid(v)) {
stackval sv;
sv.value = v;
sv.pathidx = pathidx;
stack_push(jq, sv);
} else {
print_error(v);
goto do_backtrack;
}
break;
}
case JUMP: {
uint16_t offset = *pc++;
pc += offset;
break;
}
case JUMP_F: {
uint16_t offset = *pc++;
stackval t = stack_pop(jq);
jv_kind kind = jv_get_kind(t.value);
if (kind == JV_KIND_FALSE || kind == JV_KIND_NULL) {
pc += offset;
}
stack_push(jq, t); // FIXME do this better
break;
}
case EACH:
stack_push(jq, stackval_root(jv_number(-1)));
// fallthrough
case ON_BACKTRACK(EACH): {
int idx = jv_number_value(stack_pop(jq).value);
stackval container = stack_pop(jq);
int keep_going;
jv key, value;
if (jv_get_kind(container.value) == JV_KIND_ARRAY) {
if (opcode == EACH) idx = 0;
else idx = idx + 1;
keep_going = idx < jv_array_length(jv_copy(container.value));
if (keep_going) {
key = jv_number(idx);
value = jv_array_get(jv_copy(container.value), idx);
}
} else if (jv_get_kind(container.value) == JV_KIND_OBJECT) {
if (opcode == EACH) idx = jv_object_iter(container.value);
else idx = jv_object_iter_next(container.value, idx);
keep_going = jv_object_iter_valid(container.value, idx);
if (keep_going) {
key = jv_object_iter_key(container.value, idx);
value = jv_object_iter_value(container.value, idx);
}
} else {
assert(opcode == EACH);
print_error(jv_invalid_with_msg(jv_string_fmt("Cannot iterate over %s",
jv_kind_name(jv_get_kind(container.value)))));
keep_going = 0;
}
if (!keep_going) {
jv_free(container.value);
goto do_backtrack;
} else {
stack_save(jq);
stack_push(jq, container);
stack_push(jq, stackval_root(jv_number(idx)));
frame_push_backtrack(&jq->frame_stk, pc - 1);
stack_switch(jq);
stackval sv = {value,
path_push(jq, container, key)};
stack_push(jq, sv);
}
break;
}
do_backtrack:
case BACKTRACK: {
if (!stack_restore(jq)) {
return jv_invalid();
}
pc = *frame_current_retaddr(&jq->frame_stk);
frame_pop(&jq->frame_stk);
backtracking = 1;
break;
}
case FORK: {
stack_save(jq);
frame_push_backtrack(&jq->frame_stk, pc - 1);
stack_switch(jq);
pc++; // skip offset this time
break;
}
case ON_BACKTRACK(FORK): {
uint16_t offset = *pc++;
pc += offset;
break;
}
case YIELD: {
jv value = stack_pop(jq).value;
frame_push_backtrack(&jq->frame_stk, pc);
return value;
}
case CALL_BUILTIN: {
int nargs = *pc++;
stackval top = stack_pop(jq);
cfunc_input[0] = top.value;
for (int i = 1; i < nargs; i++) {
cfunc_input[i] = stack_pop(jq).value;
}
struct cfunction* func = &frame_current_bytecode(&jq->frame_stk)->globals->cfunctions[*pc++];
top.value = cfunction_invoke(func, cfunc_input);
if (jv_is_valid(top.value)) {
stack_push(jq, top);
} else {
print_error(top.value);
goto do_backtrack;
}
break;
}
case CALL_JQ: {
uint16_t nclosures = *pc++;
uint16_t* retaddr = pc + 2 + nclosures*2;
frame_ptr new_frame = frame_push(&jq->frame_stk,
make_closure(&jq->frame_stk, frame_current(&jq->frame_stk), pc),
retaddr);
pc += 2;
frame_ptr old_frame = forkable_stack_peek_next(&jq->frame_stk, new_frame);
assert(nclosures == frame_self(new_frame)->bc->nclosures);
for (int i=0; i<nclosures; i++) {
*frame_closure_arg(new_frame, i) = make_closure(&jq->frame_stk, old_frame, pc);
pc += 2;
}
pc = frame_current_bytecode(&jq->frame_stk)->code;
break;
}
case RET: {
pc = *frame_current_retaddr(&jq->frame_stk);
frame_pop(&jq->frame_stk);
break;
}
}
}
}
void jq_init(struct bytecode* bc, jv input, jq_state **jq, int flags) {
jq_state *new_jq;
new_jq = jv_mem_alloc(sizeof(*new_jq));
memset(new_jq, 0, sizeof(*new_jq));
forkable_stack_init(&new_jq->data_stk, sizeof(stackval) * 100);
forkable_stack_init(&new_jq->frame_stk, 1024);
forkable_stack_init(&new_jq->fork_stk, 1024);
stack_push(new_jq, stackval_root(input));
struct closure top = {bc, -1};
frame_push(&new_jq->frame_stk, top, 0);
frame_push_backtrack(&new_jq->frame_stk, bc->code);
if (flags & JQ_DEBUG_TRACE) {
new_jq->debug_trace_enabled = 1;
} else {
new_jq->debug_trace_enabled = 0;
}
*jq = new_jq;
}
void jq_teardown(jq_state **jq) {
jq_state *old_jq = *jq;
if (old_jq == NULL)
return;
*jq = NULL;
while (stack_restore(old_jq)) {}
assert(forkable_stack_empty(&old_jq->fork_stk));
assert(forkable_stack_empty(&old_jq->data_stk));
assert(forkable_stack_empty(&old_jq->frame_stk));
forkable_stack_free(&old_jq->fork_stk);
forkable_stack_free(&old_jq->data_stk);
forkable_stack_free(&old_jq->frame_stk);
for (int i=0; i<old_jq->pathsize; i++) {
jv_free(old_jq->pathbuf[i]);
}
jv_mem_free(old_jq->pathbuf);
jv_mem_free(old_jq);
}
struct bytecode* jq_compile_args(const char* str, jv args) {
assert(jv_get_kind(args) == JV_KIND_ARRAY);
struct locfile locations;
locfile_init(&locations, str, strlen(str));
block program;
struct bytecode* bc = 0;
int nerrors = jq_parse(&locations, &program);
if (nerrors == 0) {
for (int i=0; i<jv_array_length(jv_copy(args)); i++) {
jv arg = jv_array_get(jv_copy(args), i);
jv name = jv_object_get(jv_copy(arg), jv_string("name"));
jv value = jv_object_get(arg, jv_string("value"));
program = gen_var_binding(gen_const(value), jv_string_value(name), program);
jv_free(name);
}
jv_free(args);
program = builtins_bind(program);
nerrors = block_compile(program, &locations, &bc);
}
if (nerrors) {
fprintf(stderr, "%d compile %s\n", nerrors, nerrors > 1 ? "errors" : "error");
}
locfile_free(&locations);
return bc;
}
struct bytecode* jq_compile(const char* str) {
return jq_compile_args(str, jv_array());
}
-20
View File
@@ -1,20 +0,0 @@
#ifndef EXECUTE_H
#define EXECUTE_H
#include "bytecode.h"
struct bytecode* jq_compile(const char* str);
/* args must be an array of the form [{name:"foo", value:"thing"}, {name:"bar",value:3}] */
struct bytecode* jq_compile_args(const char* str, jv args);
typedef struct jq_state jq_state;
enum {JQ_DEBUG_TRACE = 1};
void jq_init(struct bytecode* bc, jv value, jq_state **, int flags);
jv jq_next(jq_state *);
void jq_teardown(jq_state **);
#endif
-172
View File
@@ -1,172 +0,0 @@
#ifndef FORKABLE_STACK_H
#define FORKABLE_STACK_H
#include <stddef.h>
#include <assert.h>
#include <string.h>
#include "jv_alloc.h"
struct forkable_stack_header {
/* distance in bytes between this header and the header
of the next object on the stack */
int next_delta;
};
#define FORKABLE_STACK_HEADER struct forkable_stack_header fk_header_
struct forkable_stack {
// Stack grows down from stk+length
char* stk;
// stk+length is just past end of allocated area
// stk = jv_mem_alloc(length)
int length;
// stk+pos is header of top object, or stk+length if empty
int pos;
// everything after-or-including stk+savedlimit must be preserved
int savedlimit;
};
static void forkable_stack_check(struct forkable_stack* s) {
assert(s->stk);
assert(s->length > 0);
assert(s->pos >= 0 && s->pos <= s->length);
assert(s->savedlimit >= 0 && s->savedlimit <= s->length);
}
static int forkable_stack_empty(struct forkable_stack* s) {
return s->pos == s->length;
}
static void forkable_stack_init(struct forkable_stack* s, size_t sz) {
s->stk = jv_mem_alloc(sz);
s->length = sz;
s->pos = s->length;
s->savedlimit = s->length;
forkable_stack_check(s);
}
static void forkable_stack_free(struct forkable_stack* s) {
assert(forkable_stack_empty(s));
assert(s->savedlimit == s->length);
jv_mem_free(s->stk);
s->stk = 0;
}
static void* forkable_stack_push(struct forkable_stack* s, size_t sz_size) {
assert(sz_size > 0 && sz_size % sizeof(struct forkable_stack_header) == 0);
int size = (int)sz_size;
forkable_stack_check(s);
int curr = s->pos < s->savedlimit ? s->pos : s->savedlimit;
if (curr - size < 0) {
int oldlen = s->length;
s->length = (size + oldlen + 1024) * 2;
s->stk = jv_mem_realloc(s->stk, s->length);
int shift = s->length - oldlen;
memmove(s->stk + shift, s->stk, oldlen);
s->pos += shift;
s->savedlimit += shift;
curr += shift;
}
int newpos = curr - size;
assert(newpos < s->pos);
void* ret = (void*)(s->stk + newpos);
((struct forkable_stack_header*)ret)->next_delta = s->pos - newpos;
s->pos = newpos;
forkable_stack_check(s);
return ret;
}
static void* forkable_stack_peek(struct forkable_stack* s) {
assert(!forkable_stack_empty(s));
forkable_stack_check(s);
return (void*)(s->stk + s->pos);
}
static void* forkable_stack_peek_next(struct forkable_stack* s, void* top) {
forkable_stack_check(s);
struct forkable_stack_header* elem = top;
int elempos = (char*)top - s->stk;
assert(elempos >= 0 && elempos < s->length);
assert(elempos + elem->next_delta <= s->length);
if (elempos + elem->next_delta < s->length) {
return (void*)(s->stk + elempos + elem->next_delta);
} else {
return 0;
}
}
// Returns 1 if the next forkable_stack_pop will permanently remove an
// object from the stack (i.e. the top object was not saved with a fork)
static int forkable_stack_pop_will_free(struct forkable_stack* s) {
return s->pos < s->savedlimit;
}
static void forkable_stack_pop(struct forkable_stack* s) {
forkable_stack_check(s);
struct forkable_stack_header* elem = forkable_stack_peek(s);
int reclaim_upto = s->pos + elem->next_delta < s->savedlimit ?
s->pos + elem->next_delta : s->savedlimit;
assert(reclaim_upto <= s->length);
int reclaimed = reclaim_upto > s->pos ? reclaim_upto - s->pos : 0;
assert(0 <= reclaimed && s->pos + reclaimed <= s->length);
// s->pos <= i < reclaim_upto means that position i is to be freed
assert((reclaimed > 0) == forkable_stack_pop_will_free(s));
int new_pos = s->pos + elem->next_delta;
jv_mem_invalidate(elem, reclaimed);
s->pos = new_pos;
}
struct forkable_stack_state {
// We save the previous pos, savedlimit as
// length-pos, length-savedlimit since these
// values are stable across stack reallocations.
int prev_pos_delta, prev_limit_delta;
};
static void forkable_stack_save(struct forkable_stack* s, struct forkable_stack_state* state) {
forkable_stack_check(s);
state->prev_pos_delta = s->length - s->pos;
state->prev_limit_delta = s->length - s->savedlimit;
if (s->pos < s->savedlimit) s->savedlimit = s->pos;
}
static void forkable_stack_switch(struct forkable_stack* s, struct forkable_stack_state* state) {
forkable_stack_check(s);
int curr_pos = s->pos;
s->pos = s->length - state->prev_pos_delta;
state->prev_pos_delta = s->length - curr_pos;
int curr_limit = s->savedlimit;
if (curr_pos < curr_limit) s->savedlimit = curr_pos;
//state->prevlimit = curr_limit; FIXME clean up
forkable_stack_check(s);
}
static void forkable_stack_restore(struct forkable_stack* s, struct forkable_stack_state* state) {
forkable_stack_check(s);
assert(s->savedlimit <= s->length - state->prev_pos_delta);
assert(s->savedlimit <= s->length - state->prev_limit_delta);
s->pos = s->length - state->prev_pos_delta;
s->savedlimit = s->length - state->prev_limit_delta;
forkable_stack_check(s);
}
typedef int stack_idx;
static stack_idx forkable_stack_to_idx(struct forkable_stack* s, void* ptr) {
char* item = ptr;
int pos = item - s->stk;
assert(pos >= 0 && pos < s->length);
return s->length - pos;
}
static void* forkable_stack_from_idx(struct forkable_stack* s, stack_idx idx) {
assert(idx >= 1 && idx <= s->length);
return &s->stk[s->length - idx];
}
#endif
-118
View File
@@ -1,118 +0,0 @@
#ifndef FRAME_LAYOUT_H
#include "forkable_stack.h"
#include "bytecode.h"
struct closure {
struct bytecode* bc;
stack_idx env;
};
struct continuation {
struct bytecode* bc;
stack_idx env;
uint16_t* retaddr;
// FIXME: probably not necessary as a separate field
int is_backtrack_frame;
};
typedef union frame_elem {
FORKABLE_STACK_HEADER;
struct continuation cont;
struct closure closure;
jv jsonval;
} *frame_ptr;
/*
* Frame layout
* fr[0] - FORKABLE_STACK_HEADER (next pointer)
* fr[1] - self (used to store return addresses, etc)
* fr[2...nclosures+2] - closure params
* fr[nclosures+2..nclosures+nlocals+2] - local variables
*/
static int frame_size(struct bytecode* bc) {
return sizeof(union frame_elem) * (bc->nclosures + bc->nlocals + 2);
}
static struct continuation* frame_self(frame_ptr fr) {
return &fr[1].cont;
}
static struct closure* frame_closure_arg(frame_ptr fr, int closure) {
assert(closure >= 0);
assert(closure < frame_self(fr)->bc->nclosures);
return &fr[2+closure].closure;
}
static jv* frame_local_var(frame_ptr fr, int var) {
assert(var >= 0);
assert(var < frame_self(fr)->bc->nlocals);
return &fr[2 + frame_self(fr)->bc->nclosures + var].jsonval;
}
static frame_ptr frame_current(struct forkable_stack* stk) {
frame_ptr fp = forkable_stack_peek(stk);
if (forkable_stack_peek_next(stk, fp)) {
struct bytecode* bc = frame_self(forkable_stack_peek_next(stk, fp))->bc;
assert(frame_self(fp)->retaddr >= bc->code && frame_self(fp)->retaddr < bc->code + bc->codelen);
} else {
assert(frame_self(fp)->retaddr == 0);
}
return fp;
}
static struct bytecode* frame_current_bytecode(struct forkable_stack* stk) {
return frame_self(frame_current(stk))->bc;
}
static uint16_t** frame_current_retaddr(struct forkable_stack* stk) {
return &frame_self(frame_current(stk))->retaddr;
}
static frame_ptr frame_get_parent(struct forkable_stack* stk, frame_ptr fr) {
return forkable_stack_from_idx(stk, frame_self(fr)->env);
}
static frame_ptr frame_get_level(struct forkable_stack* stk, frame_ptr fr, int level) {
for (int i=0; i<level; i++) {
fr = frame_get_parent(stk, fr);
}
return fr;
}
static frame_ptr frame_push(struct forkable_stack* stk, struct closure cl, uint16_t* retaddr) {
frame_ptr fp = forkable_stack_push(stk, frame_size(cl.bc));
struct continuation* cc = frame_self(fp);
cc->bc = cl.bc;
cc->env = cl.env;
cc->retaddr = retaddr;
cc->is_backtrack_frame = 0;
for (int i=0; i<cl.bc->nlocals; i++) {
*frame_local_var(fp, i) = jv_invalid();
}
return fp;
}
static frame_ptr frame_push_backtrack(struct forkable_stack* stk, uint16_t* retaddr) {
struct continuation cc = *frame_self(frame_current(stk));
frame_ptr fp = forkable_stack_push(stk, sizeof(union frame_elem) * 2);
assert(!cc.is_backtrack_frame);
cc.is_backtrack_frame = 1;
cc.retaddr = retaddr;
*frame_self(fp) = cc;
return fp;
}
static void frame_pop(struct forkable_stack* stk) {
frame_ptr fp = frame_current(stk);
if (forkable_stack_pop_will_free(stk) &&
!frame_self(fp)->is_backtrack_frame) {
int nlocals = frame_self(fp)->bc->nlocals;
for (int i=0; i<nlocals; i++) {
jv_free(*frame_local_var(fp, i));
}
}
forkable_stack_pop(stk);
}
#endif
-39
View File
@@ -1,39 +0,0 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "JQ" "1" "May 2013" "" ""
.
.SH "NAME"
\fBjq\fR \- Command\-line JSON processor
.
.SH "DESCRIPTION"
\fBjq\fR can transform JSON in various ways, by selecting, iterating, reducing and otherwise mangling JSON documents\.
.
.P
This version of \fBjq\fR was built without a manual, so this manpage is a stub\. For full documentation of the \fBjq\fR language, see:
.
.IP "" 4
.
.nf
http://stedolan\.github\.com/jq
.
.fi
.
.IP "" 0
.
.SH "BUGS"
Presumably\. Report them or discuss them at:
.
.IP "" 4
.
.nf
https://github\.com/stedolan/jq/issues
.
.fi
.
.IP "" 0
.
.SH "AUTHOR"
Stephen Dolan \fB<mu@netsoc\.tcd\.ie>\fR
+3459
View File
File diff suppressed because it is too large. Load diff
+8 -3
View File
@@ -5,7 +5,7 @@ Name: jq
Version: %{myver}
Release: %{myrel}%{?dist}
Source0: jq-%{myver}.tar.gz
URL: https://github.com/stedolan/jq
URL: https://stedolan.github.io/jq
License: BSD
AutoReqProv: no
#BuildPrereq: autoconf, libtool, automake, flex, bison, python
@@ -52,11 +52,16 @@ rm -rf %{buildroot}
%endif
%{_datadir}/doc/%{name}/AUTHORS
%{_datadir}/doc/%{name}/COPYING
%{_datadir}/doc/%{name}/INSTALL
%{_datadir}/doc/%{name}/NEWS
%{_datadir}/doc/%{name}/README
%{_datadir}/doc/%{name}/README.md
%{_datadir}/man/man1/jq.1
%{_includedir}/jq.h
%{_includedir}/jv.h
%{_prefix}/lib/libjq.a
%{_prefix}/lib/libjq.la
%{_prefix}/lib/libjq.so
%{_prefix}/lib/libjq.so.1
%{_prefix}/lib/libjq.so.1.0.4
%changelog
-1035
View File
File diff suppressed because it is too large. Load diff
-157
View File
@@ -1,157 +0,0 @@
#ifndef JV_H
#define JV_H
#include <stdint.h>
#include <assert.h>
#include <stddef.h>
typedef enum {
JV_KIND_INVALID,
JV_KIND_NULL,
JV_KIND_FALSE,
JV_KIND_TRUE,
JV_KIND_NUMBER,
JV_KIND_STRING,
JV_KIND_ARRAY,
JV_KIND_OBJECT
} jv_kind;
typedef struct {
size_t count;
} jv_refcnt;
typedef struct{
jv_refcnt* ptr;
int i[2];
} jv_complex;
typedef struct {
jv_kind kind;
union {
double number;
jv_complex complex;
} val;
} jv;
/*
* All jv_* functions consume (decref) input and produce (incref) output
* Except jv_copy
*/
jv_kind jv_get_kind(jv);
const char* jv_kind_name(jv_kind);
static int jv_is_valid(jv x) { return jv_get_kind(x) != JV_KIND_INVALID; }
jv jv_copy(jv);
void jv_free(jv);
int jv_equal(jv, jv);
int jv_contains(jv, jv);
jv jv_invalid();
jv jv_invalid_with_msg(jv);
jv jv_invalid_get_msg(jv);
int jv_invalid_has_msg(jv);
jv jv_null();
jv jv_true();
jv jv_false();
jv jv_bool(int);
jv jv_number(double);
double jv_number_value(jv);
jv jv_array();
jv jv_array_sized(int);
int jv_array_length(jv);
jv jv_array_get(jv, int);
jv jv_array_set(jv, int, jv);
jv jv_array_append(jv, jv);
jv jv_array_concat(jv, jv);
jv jv_array_slice(jv, int, int);
#define jv_array_foreach(a, i, x) \
for (int jv_len__ = jv_array_length(jv_copy(a)), i=0, jv_j__ = 1; \
jv_j__; jv_j__ = 0) \
for (jv x; \
i < jv_len__ ? \
(x = jv_array_get(jv_copy(a), i), 1) : 0; \
i++)
jv jv_string(const char*);
jv jv_string_sized(const char*, int);
int jv_string_length(jv);
uint32_t jv_string_hash(jv);
const char* jv_string_value(jv);
jv jv_string_concat(jv, jv);
jv jv_string_fmt(const char*, ...);
jv jv_string_append_buf(jv a, const char* buf, int len);
jv jv_string_append_str(jv a, const char* str);
jv jv_object();
jv jv_object_get(jv object, jv key);
jv jv_object_set(jv object, jv key, jv value);
jv jv_object_delete(jv object, jv key);
int jv_object_length(jv object);
jv jv_object_merge(jv, jv);
int jv_object_iter(jv);
int jv_object_iter_next(jv, int);
int jv_object_iter_valid(jv, int);
jv jv_object_iter_key(jv, int);
jv jv_object_iter_value(jv, int);
#define jv_object_foreach(t, k, v) \
for (int jv_i__ = jv_object_iter(t), jv_j__ = 1; jv_j__; jv_j__ = 0) \
for (jv k, v; \
jv_object_iter_valid((t), jv_i__) ? \
(k = jv_object_iter_key(t, jv_i__), \
v = jv_object_iter_value(t, jv_i__), \
1) \
: 0; \
jv_i__ = jv_object_iter_next(t, jv_i__)) \
int jv_get_refcnt(jv);
enum { JV_PRINT_PRETTY = 1, JV_PRINT_ASCII = 2, JV_PRINT_COLOUR = 4 };
void jv_dump(jv, int flags);
jv jv_dump_string(jv, int flags);
jv jv_parse(const char* string);
jv jv_parse_sized(const char* string, int length);
#endif
/*
true/false/null:
check kind
number:
introduce/eliminate jv
to integer
array:
copy
free
slice
index
update
updateslice?
*/
-37
View File
@@ -1,37 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include "jv_alloc.h"
static void memory_exhausted() {
fprintf(stderr, "error: cannot allocate memory\n");
abort();
}
void* jv_mem_alloc(size_t sz) {
void* p = malloc(sz);
if (!p) {
memory_exhausted();
}
return p;
}
void jv_mem_free(void* p) {
free(p);
}
void* jv_mem_realloc(void* p, size_t sz) {
p = realloc(p, sz);
if (!p) {
memory_exhausted();
}
return p;
}
#ifndef NDEBUG
volatile char jv_mem_uninitialised;
__attribute__((constructor)) void jv_mem_uninit_setup(){
char* p = malloc(1);
jv_mem_uninitialised = *p;
free(p);
}
#endif
-20
View File
@@ -1,20 +0,0 @@
#ifndef JV_AUX_H
#define JV_AUX_H
#include "jv.h"
jv jv_get(jv t, jv k);
jv jv_set(jv t, jv k, jv v);
jv jv_has(jv t, jv k);
jv jv_setpath(jv root, jv path, jv value);
jv jv_getpath(jv root, jv path);
jv jv_delpaths(jv root, jv paths);
jv jv_keys(jv /*object or array*/);
int jv_cmp(jv, jv);
jv jv_group(jv objects, jv keys);
jv jv_sort(jv objects, jv keys);
#endif
-446
View File
@@ -1,446 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jv.h"
#include "jv_dtoa.h"
#include "jv_parse.h"
#include "jv_unicode.h"
#include "jv_alloc.h"
typedef const char* presult;
#define TRY(x) do {presult msg__ = (x); if (msg__) return msg__; } while(0)
#ifdef __GNUC__
#define pfunc __attribute__((warn_unused_result)) presult
#else
#define pfunc presult
#endif
void jv_parser_init(struct jv_parser* p) {
p->stack = 0;
p->stacklen = p->stackpos = 0;
p->next = jv_invalid();
p->tokenbuf = 0;
p->tokenlen = p->tokenpos = 0;
p->st = JV_PARSER_NORMAL;
p->curr_buf = 0;
p->curr_buf_length = p->curr_buf_pos = p->curr_buf_is_partial = 0;
p->bom_strip_position = 0;
p->line = 1;
p->column = 0;
jvp_dtoa_context_init(&p->dtoa);
}
void jv_parser_free(struct jv_parser* p) {
jv_free(p->next);
for (int i=0; i<p->stackpos; i++)
jv_free(p->stack[i]);
jv_mem_free(p->stack);
jv_mem_free(p->tokenbuf);
jvp_dtoa_context_free(&p->dtoa);
}
static pfunc value(struct jv_parser* p, jv val) {
if (jv_is_valid(p->next)) return "Expected separator between values";
jv_free(p->next);
p->next = val;
return 0;
}
static void push(struct jv_parser* p, jv v) {
assert(p->stackpos <= p->stacklen);
if (p->stackpos == p->stacklen) {
p->stacklen = p->stacklen * 2 + 10;
p->stack = jv_mem_realloc(p->stack, p->stacklen * sizeof(jv));
}
assert(p->stackpos < p->stacklen);
p->stack[p->stackpos++] = v;
}
static pfunc token(struct jv_parser* p, char ch) {
switch (ch) {
case '[':
if (jv_is_valid(p->next)) return "Expected separator between values";
push(p, jv_array());
break;
case '{':
if (jv_is_valid(p->next)) return "Expected separator between values";
push(p, jv_object());
break;
case ':':
if (!jv_is_valid(p->next))
return "Expected string key before ':'";
if (p->stackpos == 0 || jv_get_kind(p->stack[p->stackpos-1]) != JV_KIND_OBJECT)
return "':' not as part of an object";
if (jv_get_kind(p->next) != JV_KIND_STRING)
return "Object keys must be strings";
push(p, p->next);
p->next = jv_invalid();
break;
case ',':
if (!jv_is_valid(p->next))
return "Expected value before ','";
if (p->stackpos == 0)
return "',' not as part of an object or array";
if (jv_get_kind(p->stack[p->stackpos-1]) == JV_KIND_ARRAY) {
p->stack[p->stackpos-1] = jv_array_append(p->stack[p->stackpos-1], p->next);
p->next = jv_invalid();
} else if (jv_get_kind(p->stack[p->stackpos-1]) == JV_KIND_STRING) {
assert(p->stackpos > 1 && jv_get_kind(p->stack[p->stackpos-2]) == JV_KIND_OBJECT);
p->stack[p->stackpos-2] = jv_object_set(p->stack[p->stackpos-2],
p->stack[p->stackpos-1], p->next);
p->stackpos--;
p->next = jv_invalid();
} else {
// this case hits on input like {"a", "b"}
return "Objects must consist of key:value pairs";
}
break;
case ']':
if (p->stackpos == 0 || jv_get_kind(p->stack[p->stackpos-1]) != JV_KIND_ARRAY)
return "Unmatched ']'";
if (jv_is_valid(p->next)) {
p->stack[p->stackpos-1] = jv_array_append(p->stack[p->stackpos-1], p->next);
p->next = jv_invalid();
} else {
if (jv_array_length(jv_copy(p->stack[p->stackpos-1])) != 0) {
// this case hits on input like [1,2,3,]
return "Expected another array element";
}
}
jv_free(p->next);
p->next = p->stack[--p->stackpos];
break;
case '}':
if (p->stackpos == 0)
return "Unmatched '}'";
if (jv_is_valid(p->next)) {
if (jv_get_kind(p->stack[p->stackpos-1]) != JV_KIND_STRING)
return "Objects must consist of key:value pairs";
assert(p->stackpos > 1 && jv_get_kind(p->stack[p->stackpos-2]) == JV_KIND_OBJECT);
p->stack[p->stackpos-2] = jv_object_set(p->stack[p->stackpos-2],
p->stack[p->stackpos-1], p->next);
p->stackpos--;
p->next = jv_invalid();
} else {
if (jv_get_kind(p->stack[p->stackpos-1]) != JV_KIND_OBJECT)
return "Unmatched '}'";
if (jv_object_length(jv_copy(p->stack[p->stackpos-1])) != 0)
return "Expected another key-value pair";
}
jv_free(p->next);
p->next = p->stack[--p->stackpos];
break;
}
return 0;
}
static void tokenadd(struct jv_parser* p, char c) {
assert(p->tokenpos <= p->tokenlen);
if (p->tokenpos == p->tokenlen) {
p->tokenlen = p->tokenlen*2 + 256;
p->tokenbuf = jv_mem_realloc(p->tokenbuf, p->tokenlen);
}
assert(p->tokenpos < p->tokenlen);
p->tokenbuf[p->tokenpos++] = c;
}
static int unhex4(char* hex) {
int r = 0;
for (int i=0; i<4; i++) {
char c = *hex++;
int n;
if ('0' <= c && c <= '9') n = c - '0';
else if ('a' <= c && c <= 'f') n = c - 'a' + 10;
else if ('A' <= c && c <= 'F') n = c - 'A' + 10;
else return -1;
r <<= 4;
r |= n;
}
return r;
}
static pfunc found_string(struct jv_parser* p) {
char* in = p->tokenbuf;
char* out = p->tokenbuf;
char* end = p->tokenbuf + p->tokenpos;
while (in < end) {
char c = *in++;
if (c == '\\') {
if (in >= end)
return "Expected escape character at end of string";
c = *in++;
switch (c) {
case '\\':
case '"':
case '/': *out++ = c; break;
case 'b': *out++ = '\b'; break;
case 'f': *out++ = '\f'; break;
case 't': *out++ = '\t'; break;
case 'n': *out++ = '\n'; break;
case 'r': *out++ = '\r'; break;
case 'u':
/* ahh, the complicated case */
if (in + 4 > end)
return "Invalid \\uXXXX escape";
int hexvalue = unhex4(in);
if (hexvalue < 0)
return "Invalid characters in \\uXXXX escape";
unsigned long codepoint = (unsigned long)hexvalue;
in += 4;
if (0xD800 <= codepoint && codepoint <= 0xDBFF) {
/* who thought UTF-16 surrogate pairs were a good idea? */
if (in + 6 > end || in[0] != '\\' || in[1] != 'u')
return "Invalid \\uXXXX\\uXXXX surrogate pair escape";
unsigned long surrogate = unhex4(in+2);
if (!(0xDC00 <= surrogate && surrogate <= 0xDFFF))
return "Invalid \\uXXXX\\uXXXX surrogate pair escape";
in += 6;
codepoint = 0x10000 + (((codepoint - 0xD800) << 10)
|(surrogate - 0xDC00));
}
// FIXME assert valid codepoint
out += jvp_utf8_encode(codepoint, out);
break;
default:
return "Invalid escape";
}
} else {
*out++ = c;
}
}
TRY(value(p, jv_string_sized(p->tokenbuf, out - p->tokenbuf)));
p->tokenpos = 0;
return 0;
}
static pfunc check_literal(struct jv_parser* p) {
if (p->tokenpos == 0) return 0;
const char* pattern = 0;
int plen;
jv v;
switch (p->tokenbuf[0]) {
case 't': pattern = "true"; plen = 4; v = jv_true(); break;
case 'f': pattern = "false"; plen = 5; v = jv_false(); break;
case 'n': pattern = "null"; plen = 4; v = jv_null(); break;
}
if (pattern) {
if (p->tokenpos != plen) return "Invalid literal";
for (int i=0; i<plen; i++)
if (p->tokenbuf[i] != pattern[i])
return "Invalid literal";
TRY(value(p, v));
} else {
// FIXME: better parser
p->tokenbuf[p->tokenpos] = 0; // FIXME: invalid
char* end = 0;
double d = jvp_strtod(&p->dtoa, p->tokenbuf, &end);
if (end == 0 || *end != 0)
return "Invalid numeric literal";
TRY(value(p, jv_number(d)));
}
p->tokenpos = 0;
return 0;
}
typedef enum {
LITERAL,
WHITESPACE,
STRUCTURE,
QUOTE,
INVALID
} chclass;
static chclass classify(char c) {
switch (c) {
case ' ':
case '\t':
case '\r':
case '\n':
return WHITESPACE;
case '"':
return QUOTE;
case '[':
case ',':
case ']':
case '{':
case ':':
case '}':
return STRUCTURE;
default:
return LITERAL;
}
}
static const presult OK = "output produced";
static int check_done(struct jv_parser* p, jv* out) {
if (p->stackpos == 0 && jv_is_valid(p->next)) {
*out = p->next;
p->next = jv_invalid();
return 1;
} else {
return 0;
}
}
static pfunc scan(struct jv_parser* p, char ch, jv* out) {
p->column++;
if (ch == '\n') {
p->line++;
p->column = 0;
}
presult answer = 0;
if (p->st == JV_PARSER_NORMAL) {
chclass cls = classify(ch);
if (cls != LITERAL) {
TRY(check_literal(p));
if (check_done(p, out)) answer = OK;
}
switch (cls) {
case LITERAL:
tokenadd(p, ch);
break;
case WHITESPACE:
break;
case QUOTE:
p->st = JV_PARSER_STRING;
break;
case STRUCTURE:
TRY(token(p, ch));
break;
case INVALID:
return "Invalid character";
}
if (check_done(p, out)) answer = OK;
} else {
if (ch == '"' && p->st == JV_PARSER_STRING) {
TRY(found_string(p));
p->st = JV_PARSER_NORMAL;
if (check_done(p, out)) answer = OK;
} else {
tokenadd(p, ch);
if (ch == '\\' && p->st == JV_PARSER_STRING) {
p->st = JV_PARSER_STRING_ESCAPE;
} else {
p->st = JV_PARSER_STRING;
}
}
}
return answer;
}
static const unsigned char UTF8_BOM[] = {0xEF,0xBB,0xBF};
void jv_parser_set_buf(struct jv_parser* p, const char* buf, int length, int is_partial) {
assert((p->curr_buf == 0 || p->curr_buf_pos == p->curr_buf_length)
&& "previous buffer not exhausted");
while (p->bom_strip_position < sizeof(UTF8_BOM)) {
if ((unsigned char)*buf == UTF8_BOM[p->bom_strip_position]) {
// matched a BOM character
buf++;
length--;
p->bom_strip_position++;
} else {
if (p->bom_strip_position == 0) {
// no BOM in this document
p->bom_strip_position = sizeof(UTF8_BOM);
} else {
// malformed BOM (prefix present, rest missing)
p->bom_strip_position = 0xff;
}
}
}
p->curr_buf = buf;
p->curr_buf_length = length;
p->curr_buf_pos = 0;
p->curr_buf_is_partial = is_partial;
}
jv jv_parser_next(struct jv_parser* p) {
assert(p->curr_buf && "a buffer must be provided");
if (p->bom_strip_position == 0xff) return jv_invalid_with_msg(jv_string("Malformed BOM"));
jv value;
presult msg = 0;
while (!msg && p->curr_buf_pos < p->curr_buf_length) {
char ch = p->curr_buf[p->curr_buf_pos++];
msg = scan(p, ch, &value);
}
if (msg == OK) {
return value;
} else if (msg) {
return jv_invalid_with_msg(jv_string_fmt("%s at line %d, column %d", msg, p->line, p->column));
} else if (p->curr_buf_is_partial) {
assert(p->curr_buf_pos == p->curr_buf_length);
// need another buffer
return jv_invalid();
} else {
assert(p->curr_buf_pos == p->curr_buf_length);
// at EOF
if (p->st != JV_PARSER_NORMAL)
return jv_invalid_with_msg(jv_string("Unfinished string"));
if ((msg = check_literal(p)))
return jv_invalid_with_msg(jv_string(msg));
if (p->stackpos != 0)
return jv_invalid_with_msg(jv_string("Unfinished JSON term"));
// p->next is either invalid (nothing here but no syntax error)
// or valid (this is the value). either way it's the thing to return
value = p->next;
p->next = jv_invalid();
return value;
}
}
jv jv_parse_sized(const char* string, int length) {
struct jv_parser parser;
jv_parser_init(&parser);
jv_parser_set_buf(&parser, string, length, 0);
jv value = jv_parser_next(&parser);
if (jv_is_valid(value)) {
jv next = jv_parser_next(&parser);
if (jv_is_valid(next)) {
// multiple JSON values, we only wanted one
jv_free(value);
jv_free(next);
value = jv_invalid_with_msg(jv_string("Unexpected extra JSON values"));
} else if (jv_invalid_has_msg(jv_copy(next))) {
// parser error after the first JSON value
jv_free(value);
value = next;
} else {
// a single valid JSON value
jv_free(next);
}
} else if (jv_invalid_has_msg(jv_copy(value))) {
// parse error, we'll return it
} else {
// no value at all
jv_free(value);
value = jv_invalid_with_msg(jv_string("Expected JSON value"));
}
jv_parser_free(&parser);
if (!jv_is_valid(value) && jv_invalid_has_msg(jv_copy(value))) {
jv msg = jv_invalid_get_msg(value);
value = jv_invalid_with_msg(jv_string_fmt("%s (while parsing '%s')",
jv_string_value(msg),
string));
jv_free(msg);
}
return value;
}
jv jv_parse(const char* string) {
return jv_parse_sized(string, strlen(string));
}
-37
View File
@@ -1,37 +0,0 @@
#ifndef JV_PARSE_H
#define JV_PARSE_H
#include "jv_dtoa.h"
struct jv_parser {
const char* curr_buf;
int curr_buf_length;
int curr_buf_pos;
int curr_buf_is_partial;
unsigned bom_strip_position;
jv* stack;
int stackpos;
int stacklen;
jv next;
char* tokenbuf;
int tokenpos;
int tokenlen;
int line, column;
struct dtoa_context dtoa;
enum {
JV_PARSER_NORMAL,
JV_PARSER_STRING,
JV_PARSER_STRING_ESCAPE
} st;
};
void jv_parser_init(struct jv_parser* p);
void jv_parser_free(struct jv_parser* p);
void jv_parser_set_buf(struct jv_parser* p, const char* buf, int length, int is_partial);
jv jv_parser_next(struct jv_parser* p);
#endif
-248
View File
@@ -1,248 +0,0 @@
#include "jv.h"
#include <stdio.h>
#include <float.h>
#include <string.h>
#include "jv_dtoa.h"
#include "jv_unicode.h"
#define ESC "\033"
#define COL(c) (ESC "[" c "m")
#define COLRESET (ESC "[0m")
// Colour table. See http://en.wikipedia.org/wiki/ANSI_escape_code#Colors
// for how to choose these.
static const jv_kind colour_kinds[] =
{JV_KIND_NULL, JV_KIND_FALSE, JV_KIND_TRUE, JV_KIND_NUMBER,
JV_KIND_STRING, JV_KIND_ARRAY, JV_KIND_OBJECT};
static const char* const colours[] =
{COL("30;1"), COL("0"), COL("0"), COL("0"),
COL("32"), COL("37"), COL("37")};
#define FIELD_COLOUR COL("34;1")
static void put_buf(const char* s, int len, FILE* fout, jv* strout) {
if (strout) {
*strout = jv_string_append_buf(*strout, s, len);
} else {
fwrite(s, 1, len, fout);
}
}
static void put_char(char c, FILE* fout, jv* strout) {
put_buf(&c, 1, fout, strout);
}
static void put_str(const char* s, FILE* fout, jv* strout) {
put_buf(s, strlen(s), fout, strout);
}
static void put_space(int n, FILE* fout, jv* strout) {
while (n--) {
put_char(' ', fout, strout);
}
}
static void jvp_dump_string(jv str, int ascii_only, FILE* F, jv* S) {
assert(jv_get_kind(str) == JV_KIND_STRING);
const char* i = jv_string_value(str);
const char* end = i + jv_string_length(jv_copy(str));
const char* cstart;
int c = 0;
char buf[32];
put_char('"', F, S);
while ((i = jvp_utf8_next((cstart = i), end, &c))) {
assert(c != -1);
int unicode_escape = 0;
if (0x20 <= c && c <= 0x7E) {
// printable ASCII
if (c == '"' || c == '\\') {
put_char('\\', F, S);
}
put_char(c, F, S);
} else if (c < 0x20 || c == 0x7F) {
// ASCII control character
switch (c) {
case '\b':
put_char('\\', F, S);
put_char('b', F, S);
break;
case '\t':
put_char('\\', F, S);
put_char('t', F, S);
break;
case '\r':
put_char('\\', F, S);
put_char('r', F, S);
break;
case '\n':
put_char('\\', F, S);
put_char('n', F, S);
break;
case '\f':
put_char('\\', F, S);
put_char('f', F, S);
break;
default:
unicode_escape = 1;
break;
}
} else {
if (ascii_only) {
unicode_escape = 1;
} else {
put_buf(cstart, i - cstart, F, S);
}
}
if (unicode_escape) {
if (c <= 0xffff) {
sprintf(buf, "\\u%04x", c);
} else {
c -= 0x10000;
sprintf(buf, "\\u%04x\\u%04x",
0xD800 | ((c & 0xffc00) >> 10),
0xDC00 | (c & 0x003ff));
}
put_str(buf, F, S);
}
}
assert(c != -1);
put_char('"', F, S);
}
enum { INDENT = 2 };
static void jv_dump_term(struct dtoa_context* C, jv x, int flags, int indent, FILE* F, jv* S) {
char buf[JVP_DTOA_FMT_MAX_LEN];
const char* colour = 0;
if (flags & JV_PRINT_COLOUR) {
for (unsigned i=0; i<sizeof(colour_kinds)/sizeof(colour_kinds[0]); i++) {
if (jv_get_kind(x) == colour_kinds[i]) {
colour = colours[i];
put_str(colour, F, S);
break;
}
}
}
switch (jv_get_kind(x)) {
case JV_KIND_INVALID:
assert(0 && "Invalid value");
break;
case JV_KIND_NULL:
put_str("null", F, S);
break;
case JV_KIND_FALSE:
put_str("false", F, S);
break;
case JV_KIND_TRUE:
put_str("true", F, S);
break;
case JV_KIND_NUMBER: {
double d = jv_number_value(x);
if (d != d) {
// JSON doesn't have NaN, so we'll render it as "null"
put_str("null", F, S);
} else {
// Normalise infinities to something we can print in valid JSON
if (d > DBL_MAX) d = DBL_MAX;
if (d < -DBL_MAX) d = -DBL_MAX;
put_str(jvp_dtoa_fmt(C, buf, d), F, S);
}
break;
}
case JV_KIND_STRING:
jvp_dump_string(x, flags & JV_PRINT_ASCII, F, S);
break;
case JV_KIND_ARRAY: {
if (jv_array_length(jv_copy(x)) == 0) {
put_str("[]", F, S);
break;
}
put_str("[", F, S);
if (flags & JV_PRINT_PRETTY) {
put_char('\n', F, S);
put_space(indent+INDENT, F, S);
}
jv_array_foreach(x, i, elem) {
if (i!=0) {
if (flags & JV_PRINT_PRETTY) {
put_str(",\n", F, S);
put_space(indent+INDENT, F, S);
} else {
put_str(",", F, S);
}
}
jv_dump_term(C, elem, flags, indent + INDENT, F, S);
if (colour) put_str(colour, F, S);
}
if (flags & JV_PRINT_PRETTY) {
put_char('\n', F, S);
put_space(indent, F, S);
}
if (colour) put_str(colour, F, S);
put_char(']', F, S);
break;
}
case JV_KIND_OBJECT: {
if (jv_object_length(jv_copy(x)) == 0) {
put_str("{}", F, S);
break;
}
put_char('{', F, S);
if (flags & JV_PRINT_PRETTY) {
put_char('\n', F, S);
put_space(indent+INDENT, F, S);
}
int first = 1;
jv_object_foreach(x, key, value) {
if (!first) {
if (flags & JV_PRINT_PRETTY){
put_str(",\n", F, S);
put_space(indent+INDENT, F, S);
} else {
put_str(",", F, S);
}
}
if (colour) put_str(COLRESET, F, S);
first = 0;
if (colour) put_str(FIELD_COLOUR, F, S);
jvp_dump_string(key, flags & JV_PRINT_ASCII, F, S);
jv_free(key);
if (colour) put_str(COLRESET, F, S);
if (colour) put_str(colour, F, S);
put_str((flags & JV_PRINT_PRETTY) ? ": " : ":", F, S);
if (colour) put_str(COLRESET, F, S);
jv_dump_term(C, value, flags, indent + INDENT, F, S);
if (colour) put_str(colour, F, S);
}
if (flags & JV_PRINT_PRETTY) {
put_char('\n', F, S);
put_space(indent, F, S);
}
if (colour) put_str(colour, F, S);
put_char('}', F, S);
}
}
jv_free(x);
if (colour) {
put_str(COLRESET, F, S);
}
}
void jv_dump(jv x, int flags) {
struct dtoa_context C;
jvp_dtoa_context_init(&C);
jv_dump_term(&C, x, flags, 0, stdout, 0);
jvp_dtoa_context_free(&C);
}
jv jv_dump_string(jv x, int flags) {
struct dtoa_context C;
jvp_dtoa_context_init(&C);
jv s = jv_string("");
jv_dump_term(&C, x, flags, 0, 0, &s);
jvp_dtoa_context_free(&C);
return s;
}
-64
View File
@@ -1,64 +0,0 @@
#include <stdio.h>
#include <assert.h>
#include "jv_unicode.h"
#include "jv_utf8_tables.h"
const char* jvp_utf8_next(const char* in, const char* end, int* codepoint) {
if (in == end) {
codepoint = 0;
return 0;
}
unsigned char first = (unsigned char)in[0];
int length = utf8_coding_length[first];
if (length == 0 || length == UTF8_CONTINUATION_BYTE || in + length > end) {
*codepoint = -1;
return 0;
}
*codepoint = ((unsigned)in[0]) & utf8_coding_bits[first];
for (int i=1; i<length; i++) {
int ch = (unsigned char)in[i];
if (utf8_coding_length[(unsigned char)in[i]] != UTF8_CONTINUATION_BYTE){
*codepoint = -1;
return 0;
}
*codepoint = (*codepoint << 6) | (ch & 0x3f);
}
return in + length;
}
int jvp_utf8_verify(const char* in, const char* end) {
int codepoint = 0;
while ((in = jvp_utf8_next(in, end, &codepoint))) {
if (codepoint == -1) return 0;
}
return codepoint != -1;
}
int jvp_utf8_encode_length(int codepoint) {
if (codepoint <= 0x7F) return 1;
else if (codepoint <= 0x7FF) return 2;
else if (codepoint <= 0xFFFF) return 3;
else return 4;
}
int jvp_utf8_encode(int codepoint, char* out) {
assert(codepoint >= 0 && codepoint <= 0x10FFFF);
char* start = out;
if (codepoint <= 0x7F) {
*out++ = codepoint;
} else if (codepoint <= 0x7FF) {
*out++ = 0xC0 + ((codepoint & 0x7C0) >> 6);
*out++ = 0x80 + ((codepoint & 0x03F));
} else if(codepoint <= 0xFFFF) {
*out++ = 0xE0 + ((codepoint & 0xF000) >> 12);
*out++ = 0x80 + ((codepoint & 0x0FC0) >> 6);
*out++ = 0x80 + ((codepoint & 0x003F));
} else {
*out++ = 0xF0 + ((codepoint & 0x1C0000) >> 18);
*out++ = 0x80 + ((codepoint & 0x03F000) >> 12);
*out++ = 0x80 + ((codepoint & 0x000FC0) >> 6);
*out++ = 0x80 + ((codepoint & 0x00003F));
}
assert(out - start == jvp_utf8_encode_length(codepoint));
return out - start;
}
-79
View File
@@ -1,79 +0,0 @@
#ifndef _LOCFILE_H
#define _LOCFILE_H
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <stdarg.h>
#include "jv_alloc.h"
typedef struct {
int start, end;
} location;
static const location UNKNOWN_LOCATION = {-1, -1};
struct locfile {
const char* data;
int length;
int* linemap;
int nlines;
};
static void locfile_init(struct locfile* l, const char* data, int length) {
l->data = data;
l->length = length;
l->nlines = 1;
for (int i=0; i<length; i++) {
if (data[i] == '\n') l->nlines++;
}
l->linemap = jv_mem_alloc(sizeof(int) * (l->nlines + 1));
l->linemap[0] = 0;
int line = 1;
for (int i=0; i<length; i++) {
if (data[i] == '\n') {
l->linemap[line] = i;
line++;
}
}
l->linemap[l->nlines] = length;
}
static void locfile_free(struct locfile* l) {
jv_mem_free(l->linemap);
}
static int locfile_get_line(struct locfile* l, int pos) {
assert(pos < l->length);
int line = 0;
while (l->linemap[line+1] < pos) line++;
assert(line < l->nlines);
return line;
}
static int locfile_line_length(struct locfile* l, int line) {
assert(line < l->nlines);
return l->linemap[line+1] - l->linemap[line];
}
static void locfile_locate(struct locfile* l, location loc, const char* fmt, ...) {
va_list fmtargs;
va_start(fmtargs, fmt);
vfprintf(stderr, fmt, fmtargs);
va_end(fmtargs);
fprintf(stderr, "\n");
if (loc.start == -1) {
fprintf(stderr, "<unknown location>\n");
return;
}
int startline = locfile_get_line(l, loc.start);
int offset = l->linemap[startline];
fprintf(stderr, "%.*s\n", locfile_line_length(l, startline), l->data + offset);
fprintf(stderr, "%*s", loc.start - offset, "");
for (int i = loc.start;
i < loc.end && i < offset + locfile_line_length(l, startline);
i++){
fprintf(stderr, "^");
}
fprintf(stderr, "\n");
}
#endif
+177
View File
@@ -0,0 +1,177 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_compare_version.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
#
# DESCRIPTION
#
# This macro compares two version strings. Due to the various number of
# minor-version numbers that can exist, and the fact that string
# comparisons are not compatible with numeric comparisons, this is not
# necessarily trivial to do in a autoconf script. This macro makes doing
# these comparisons easy.
#
# The six basic comparisons are available, as well as checking equality
# limited to a certain number of minor-version levels.
#
# The operator OP determines what type of comparison to do, and can be one
# of:
#
# eq - equal (test A == B)
# ne - not equal (test A != B)
# le - less than or equal (test A <= B)
# ge - greater than or equal (test A >= B)
# lt - less than (test A < B)
# gt - greater than (test A > B)
#
# Additionally, the eq and ne operator can have a number after it to limit
# the test to that number of minor versions.
#
# eq0 - equal up to the length of the shorter version
# ne0 - not equal up to the length of the shorter version
# eqN - equal up to N sub-version levels
# neN - not equal up to N sub-version levels
#
# When the condition is true, shell commands ACTION-IF-TRUE are run,
# otherwise shell commands ACTION-IF-FALSE are run. The environment
# variable 'ax_compare_version' is always set to either 'true' or 'false'
# as well.
#
# Examples:
#
# AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8])
# AX_COMPARE_VERSION([3.15],[lt],[3.15.8])
#
# would both be true.
#
# AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8])
# AX_COMPARE_VERSION([3.15],[gt],[3.15.8])
#
# would both be false.
#
# AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8])
#
# would be true because it is only comparing two minor versions.
#
# AX_COMPARE_VERSION([3.15.7],[eq0],[3.15])
#
# would be true because it is only comparing the lesser number of minor
# versions of the two values.
#
# Note: The characters that separate the version numbers do not matter. An
# empty string is the same as version 0. OP is evaluated by autoconf, not
# configure, so must be a string, not a variable.
#
# The author would like to acknowledge Guido Draheim whose advice about
# the m4_case and m4_ifvaln functions make this macro only include the
# portions necessary to perform the specific comparison specified by the
# OP argument in the final configure script.
#
# LICENSE
#
# Copyright (c) 2008 Tim Toolan <toolan@ele.uri.edu>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 11
dnl #########################################################################
AC_DEFUN([AX_COMPARE_VERSION], [
AC_REQUIRE([AC_PROG_AWK])
# Used to indicate true or false condition
ax_compare_version=false
# Convert the two version strings to be compared into a format that
# allows a simple string comparison. The end result is that a version
# string of the form 1.12.5-r617 will be converted to the form
# 0001001200050617. In other words, each number is zero padded to four
# digits, and non digits are removed.
AS_VAR_PUSHDEF([A],[ax_compare_version_A])
A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
-e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
-e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
-e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
-e 's/[[^0-9]]//g'`
AS_VAR_PUSHDEF([B],[ax_compare_version_B])
B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
-e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
-e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
-e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
-e 's/[[^0-9]]//g'`
dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary
dnl # then the first line is used to determine if the condition is true.
dnl # The sed right after the echo is to remove any indented white space.
m4_case(m4_tolower($2),
[lt],[
ax_compare_version=`echo "x$A
x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"`
],
[gt],[
ax_compare_version=`echo "x$A
x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"`
],
[le],[
ax_compare_version=`echo "x$A
x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"`
],
[ge],[
ax_compare_version=`echo "x$A
x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"`
],[
dnl Split the operator from the subversion count if present.
m4_bmatch(m4_substr($2,2),
[0],[
# A count of zero means use the length of the shorter version.
# Determine the number of characters in A and B.
ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'`
ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'`
# Set A to no more than B's length and B to no more than A's length.
A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"`
B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"`
],
[[0-9]+],[
# A count greater than zero means use only that many subversions
A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
],
[.+],[
AC_WARNING(
[illegal OP numeric parameter: $2])
],[])
# Pad zeros at end of numbers to make same length.
ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`"
B="$B`echo $A | sed 's/./0/g'`"
A="$ax_compare_version_tmp_A"
# Check for equality or inequality as necessary.
m4_case(m4_tolower(m4_substr($2,0,2)),
[eq],[
test "x$A" = "x$B" && ax_compare_version=true
],
[ne],[
test "x$A" != "x$B" && ax_compare_version=true
],[
AC_WARNING([illegal OP parameter: $2])
])
])
AS_VAR_POPDEF([A])dnl
AS_VAR_POPDEF([B])dnl
dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE.
if test "$ax_compare_version" = "true" ; then
m4_ifvaln([$4],[$4],[:])dnl
m4_ifvaln([$5],[else $5])dnl
fi
]) dnl AX_COMPARE_VERSION
+68
View File
@@ -0,0 +1,68 @@
# ===========================================================================
# Modified from
# http://www.gnu.org/software/autoconf-archive/ax_prog_perl_version.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PROG_BISON_VERSION([VERSION],[ACTION-IF-TRUE],[ACTION-IF-FALSE])
#
# DESCRIPTION
#
# Makes sure that bison supports the version indicated. If true the shell
# commands in ACTION-IF-TRUE are executed. If not the shell commands in
# ACTION-IF-FALSE are run. Note if $PERL is not set the macro will fail.
#
# Example:
#
# AC_PROG_YACC
# AX_PROG_BISON_VERSION([3.0.0],[ ... ],[ ... ])
#
# This will check to make sure that the bison you have supports at least
# version 3.0.0.
#
# NOTE: This macro uses the $YACC variable to perform the check.
# AX_WITH_YACC can be used to set that variable prior to running this
# macro. The $BISON_VERSION variable will be set with the detected
# version.
#
# LICENSE
#
# Copyright (c) 2009 Francesco Salvestrini <salvestrini@users.sourceforge.net>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 12
AC_DEFUN([AX_PROG_BISON_VERSION],[
AC_REQUIRE([AC_PROG_SED])
AC_REQUIRE([AC_PROG_GREP])
AS_IF([test -n "$YACC"],[
ax_bison_version="$1"
AC_MSG_CHECKING([for bison version])
changequote(<<,>>)
bison_version=`$YACC --version 2>&1 \
| $GREP bison \
| $SED -e 's/^[^0-9]*//' -e 's/[^0-9]*$//'`
changequote([,])
AC_MSG_RESULT($bison_version)
AC_SUBST([BISON_VERSION],[$bison_version])
AX_COMPARE_VERSION([$ax_bison_version],[le],[$bison_version],[
:
$2
],[
:
$3
])
],[
AC_MSG_WARN([could not find bison])
$3
])
])
-300
View File
@@ -1,300 +0,0 @@
#define _POSIX_SOURCE
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include "compile.h"
#include "jv.h"
#include "jv_parse.h"
#include "execute.h"
#include "config.h" /* Autoconf generated header file */
#include "jv_alloc.h"
int jq_testsuite(int argc, char* argv[]);
static const char* progname;
static void usage() {
fprintf(stderr, "\njq - commandline JSON processor [version %s]\n", PACKAGE_VERSION);
fprintf(stderr, "Usage: %s [options] <jq filter> [file...]\n\n", progname);
fprintf(stderr, "For a description of the command line options and\n");
fprintf(stderr, "how to write jq filters (and why you might want to)\n");
fprintf(stderr, "see the jq manpage, or the online documentation at\n");
fprintf(stderr, "http://stedolan.github.com/jq\n\n");
exit(1);
}
static void die() {
fprintf(stderr, "Use %s --help for help with command-line options,\n", progname);
fprintf(stderr, "or see the jq documentation at http://stedolan.github.com/jq\n");
exit(1);
}
static int isoptish(const char* text) {
return text[0] == '-' && (text[1] == '-' || isalpha(text[1]));
}
static int isoption(const char* text, char shortopt, const char* longopt) {
if (text[0] != '-') return 0;
if (strlen(text) == 2 && text[1] == shortopt) return 1;
if (text[1] == '-' && !strcmp(text+2, longopt)) return 1;
return 0;
}
enum {
SLURP = 1,
RAW_INPUT = 2,
PROVIDE_NULL = 4,
RAW_OUTPUT = 8,
COMPACT_OUTPUT = 16,
ASCII_OUTPUT = 32,
COLOUR_OUTPUT = 64,
NO_COLOUR_OUTPUT = 128,
FROM_FILE = 256,
/* debugging only */
DUMP_DISASM = 2048,
};
static int options = 0;
static struct bytecode* bc;
static void process(jv value, int flags) {
jq_state *jq = NULL;
jq_init(bc, value, &jq, flags);
jv result;
while (jv_is_valid(result = jq_next(jq))) {
if ((options & RAW_OUTPUT) && jv_get_kind(result) == JV_KIND_STRING) {
fwrite(jv_string_value(result), 1, jv_string_length(jv_copy(result)), stdout);
jv_free(result);
} else {
int dumpopts;
/* Disable colour by default on Windows builds as Windows
terminals tend not to display it correctly */
#ifdef WIN32
dumpopts = 0;
#else
dumpopts = isatty(fileno(stdout)) ? JV_PRINT_COLOUR : 0;
#endif
if (!(options & COMPACT_OUTPUT)) dumpopts |= JV_PRINT_PRETTY;
if (options & ASCII_OUTPUT) dumpopts |= JV_PRINT_ASCII;
if (options & COLOUR_OUTPUT) dumpopts |= JV_PRINT_COLOUR;
if (options & NO_COLOUR_OUTPUT) dumpopts &= ~JV_PRINT_COLOUR;
jv_dump(result, dumpopts);
}
printf("\n");
}
jv_free(result);
jq_teardown(&jq);
}
static jv slurp_file(const char* filename) {
FILE* file = fopen(filename, "r");
if (!file) {
return jv_invalid_with_msg(jv_string_fmt("Could not open %s: %s",
filename,
strerror(errno)));
}
jv data = jv_string("");
while (!feof(file) && !ferror(file)) {
char buf[4096];
size_t n = fread(buf, 1, sizeof(buf), file);
data = jv_string_concat(data, jv_string_sized(buf, (int)n));
}
int badread = ferror(file);
fclose(file);
if (badread) {
jv_free(data);
return jv_invalid_with_msg(jv_string_fmt("Error reading from %s",
filename));
}
return data;
}
FILE* current_input;
const char** input_filenames;
int ninput_files;
int next_input_idx;
static int read_more(char* buf, size_t size) {
while (!current_input || feof(current_input)) {
if (current_input) {
fclose(current_input);
current_input = 0;
}
if (next_input_idx == ninput_files) {
return 0;
}
if (!strcmp(input_filenames[next_input_idx], "-")) {
current_input = stdin;
} else {
current_input = fopen(input_filenames[next_input_idx], "r");
}
if (!current_input) {
fprintf(stderr, "%s: %s: %s\n", progname, input_filenames[next_input_idx], strerror(errno));
}
next_input_idx++;
}
if (!fgets(buf, size, current_input)) buf[0] = 0;
return 1;
}
int main(int argc, char* argv[]) {
int ret = 0;
if (argc) progname = argv[0];
if (argc > 1 && !strcmp(argv[1], "--run-tests")) {
return jq_testsuite(argc - 1, argv + 1);
}
const char* program = 0;
input_filenames = jv_mem_alloc(sizeof(const char*) * argc);
ninput_files = 0;
int further_args_are_files = 0;
int jq_flags = 0;
jv program_arguments = jv_array();
for (int i=1; i<argc; i++) {
if (further_args_are_files) {
input_filenames[ninput_files++] = argv[i];
} else if (!strcmp(argv[i], "--")) {
if (!program) usage();
further_args_are_files = 1;
} else if (!isoptish(argv[i])) {
if (program) {
input_filenames[ninput_files++] = argv[i];
} else {
program = argv[i];
}
} else if (isoption(argv[i], 's', "slurp")) {
options |= SLURP;
} else if (isoption(argv[i], 'r', "raw-output")) {
options |= RAW_OUTPUT;
} else if (isoption(argv[i], 'c', "compact-output")) {
options |= COMPACT_OUTPUT;
} else if (isoption(argv[i], 'C', "color-output")) {
options |= COLOUR_OUTPUT;
} else if (isoption(argv[i], 'M', "monochrome-output")) {
options |= NO_COLOUR_OUTPUT;
} else if (isoption(argv[i], 'a', "ascii-output")) {
options |= ASCII_OUTPUT;
} else if (isoption(argv[i], 'R', "raw-input")) {
options |= RAW_INPUT;
} else if (isoption(argv[i], 'n', "null-input")) {
options |= PROVIDE_NULL;
} else if (isoption(argv[i], 'f', "from-file")) {
options |= FROM_FILE;
} else if (isoption(argv[i], 0, "arg")) {
if (i >= argc - 2) {
fprintf(stderr, "%s: --arg takes two parameters (e.g. -a varname value)\n", progname);
die();
}
jv arg = jv_object();
arg = jv_object_set(arg, jv_string("name"), jv_string(argv[i+1]));
arg = jv_object_set(arg, jv_string("value"), jv_string(argv[i+2]));
program_arguments = jv_array_append(program_arguments, arg);
i += 2; // skip the next two arguments
} else if (isoption(argv[i], 0, "debug-dump-disasm")) {
options |= DUMP_DISASM;
} else if (isoption(argv[i], 0, "debug-trace")) {
jq_flags |= JQ_DEBUG_TRACE;
} else if (isoption(argv[i], 'h', "help")) {
usage();
} else if (isoption(argv[i], 'V', "version")) {
fprintf(stderr, "jq version %s\n", PACKAGE_VERSION);
return 0;
} else {
fprintf(stderr, "%s: Unknown option %s\n", progname, argv[i]);
die();
}
}
if (!program) usage();
if (ninput_files == 0) current_input = stdin;
if ((options & PROVIDE_NULL) && (options & (RAW_INPUT | SLURP))) {
fprintf(stderr, "%s: --null-input cannot be used with --raw-input or --slurp\n", progname);
die();
}
if (options & FROM_FILE) {
jv data = slurp_file(program);
if (!jv_is_valid(data)) {
data = jv_invalid_get_msg(data);
fprintf(stderr, "%s: %s\n", progname, jv_string_value(data));
jv_free(data);
return 1;
}
bc = jq_compile_args(jv_string_value(data), program_arguments);
jv_free(data);
} else {
bc = jq_compile_args(program, program_arguments);
}
if (!bc) return 1;
if (options & DUMP_DISASM) {
dump_disassembly(0, bc);
printf("\n");
}
if (options & PROVIDE_NULL) {
process(jv_null(), jq_flags);
} else {
jv slurped;
if (options & SLURP) {
if (options & RAW_INPUT) {
slurped = jv_string("");
} else {
slurped = jv_array();
}
}
struct jv_parser parser;
jv_parser_init(&parser);
char buf[4096];
while (read_more(buf, sizeof(buf))) {
if (options & RAW_INPUT) {
int len = strlen(buf);
if (len > 0) {
if (options & SLURP) {
slurped = jv_string_concat(slurped, jv_string(buf));
} else {
if (buf[len-1] == '\n') buf[len-1] = 0;
process(jv_string(buf), jq_flags);
}
}
} else {
jv_parser_set_buf(&parser, buf, strlen(buf), !feof(stdin));
jv value;
while (jv_is_valid((value = jv_parser_next(&parser)))) {
if (options & SLURP) {
slurped = jv_array_append(slurped, value);
} else {
process(value, jq_flags);
}
}
if (jv_invalid_has_msg(jv_copy(value))) {
jv msg = jv_invalid_get_msg(value);
fprintf(stderr, "parse error: %s\n", jv_string_value(msg));
jv_free(msg);
ret = 1;
break;
} else {
jv_free(value);
}
}
}
jv_parser_free(&parser);
if (ret != 0)
goto out;
if (options & SLURP) {
process(slurped, jq_flags);
}
}
out:
jv_mem_free(input_filenames);
bytecode_free(bc);
return ret;
}
+1
Submodule modules/oniguruma added at 6fa38f4084.
-31
View File
@@ -1,31 +0,0 @@
#include "opcode.h"
// flags, length
#define NONE 0, 1
#define CONSTANT OP_HAS_CONSTANT, 2
#define VARIABLE (OP_HAS_VARIABLE | OP_HAS_BINDING), 3
#define BRANCH OP_HAS_BRANCH, 2
#define CFUNC (OP_HAS_CFUNC | OP_HAS_BINDING), 3
#define UFUNC (OP_HAS_UFUNC | OP_HAS_BINDING | OP_IS_CALL_PSEUDO), 4
#define DEFINITION (OP_IS_CALL_PSEUDO | OP_HAS_BINDING), 0
#define CLOSURE_REF_IMM (OP_IS_CALL_PSEUDO | OP_HAS_BINDING), 2
#define OP(name, imm, in, out) \
{name, #name, imm, in, out},
static const struct opcode_description opcode_descriptions[] = {
#include "opcode_list.h"
};
static const struct opcode_description invalid_opcode_description = {
-1, "#INVALID", 0, 0, 0, 0
};
const struct opcode_description* opcode_describe(opcode op) {
if ((int)op >= 0 && (int)op < NUM_OPCODES) {
return &opcode_descriptions[op];
} else {
return &invalid_opcode_description;
}
}
-41
View File
@@ -1,41 +0,0 @@
#ifndef OPCODE_H
#define OPCODE_H
#include <assert.h>
typedef enum {
#define OP(name, imm, in, out) name,
#include "opcode_list.h"
#undef OP
} opcode;
enum {
NUM_OPCODES =
#define OP(name, imm, in, out) +1
#include "opcode_list.h"
#undef OP
};
enum {
OP_HAS_CONSTANT = 2,
OP_HAS_VARIABLE = 4,
OP_HAS_BRANCH = 8,
OP_HAS_CFUNC = 32,
OP_HAS_UFUNC = 64,
OP_IS_CALL_PSEUDO = 128,
OP_HAS_BINDING = 1024,
};
struct opcode_description {
opcode op;
const char* name;
int flags;
// length in 16-bit units
int length;
int stack_in, stack_out;
};
const struct opcode_description* opcode_describe(opcode op);
#endif
-499
View File
@@ -1,499 +0,0 @@
%{
#include <stdio.h>
#include <string.h>
#include "compile.h"
#include "jv_alloc.h"
#define YYMALLOC jv_mem_alloc
#define YYFREE jv_mem_free
struct lexer_param;
%}
%code requires {
#include "locfile.h"
#define YYLTYPE location
#define YYLLOC_DEFAULT(Loc, Rhs, N) \
do { \
if (N) { \
(Loc).start = YYRHSLOC(Rhs, 1).start; \
(Loc).end = YYRHSLOC(Rhs, N).end; \
} else { \
(Loc).start = YYRHSLOC(Rhs, 0).end; \
(Loc).end = YYRHSLOC(Rhs, 0).end; \
} \
} while (0)
}
%locations
%error-verbose
%define api.pure
%union {
jv literal;
block blk;
}
%destructor { jv_free($$); } <literal>
%destructor { block_free($$); } <blk>
%parse-param {block* answer}
%parse-param {int* errors}
%parse-param {struct locfile* locations}
%parse-param {struct lexer_param* lexer_param_ptr}
%lex-param {block* answer}
%lex-param {int* errors}
%lex-param {struct locfile* locations}
%lex-param {struct lexer_param* lexer_param_ptr}
%token INVALID_CHARACTER
%token <literal> IDENT
%token <literal> LITERAL
%token <literal> FORMAT
%token EQ "=="
%token NEQ "!="
%token DEFINEDOR "//"
%token AS "as"
%token DEF "def"
%token IF "if"
%token THEN "then"
%token ELSE "else"
%token ELSE_IF "elif"
%token FOLD "fold"
%token END "end"
%token AND "and"
%token OR "or"
%token SETPIPE "|="
%token SETPLUS "+="
%token SETMINUS "-="
%token SETMULT "*="
%token SETDIV "/="
%token SETDEFINEDOR "//="
%token LESSEQ "<="
%token GREATEREQ ">="
%token QQSTRING_START
%token <literal> QQSTRING_TEXT
%token QQSTRING_INTERP_START
%token QQSTRING_INTERP_END
%token QQSTRING_END
/* revolting hack */
%left ';'
%right '|'
%left ','
%right "//"
%nonassoc '=' SETPIPE SETPLUS SETMINUS SETMULT SETDIV SETDEFINEDOR
%left OR
%left AND
%nonassoc NEQ EQ '<' '>' LESSEQ GREATEREQ
%left '+' '-'
%left '*' '/'
%type <blk> Exp Term MkDict MkDictPair ExpD ElseBody QQString FuncDef FuncDefs String
%{
#include "lexer.h"
struct lexer_param {
yyscan_t lexer;
};
#define FAIL(loc, msg) \
do { \
location l = loc; \
yyerror(&l, answer, errors, locations, lexer_param_ptr, msg); \
/*YYERROR*/; \
} while (0)
void yyerror(YYLTYPE* loc, block* answer, int* errors,
struct locfile* locations, struct lexer_param* lexer_param_ptr, const char *s){
(*errors)++;
locfile_locate(locations, *loc, "error: %s", s);
}
int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, block* answer, int* errors,
struct locfile* locations, struct lexer_param* lexer_param_ptr) {
yyscan_t lexer = lexer_param_ptr->lexer;
while (1) {
int tok = jq_yylex(yylval, yylloc, lexer);
if (tok == INVALID_CHARACTER) {
FAIL(*yylloc, "Invalid character");
} else {
if ((tok == LITERAL || tok == QQSTRING_TEXT) && !jv_is_valid(yylval->literal)) {
jv msg = jv_invalid_get_msg(jv_copy(yylval->literal));
if (jv_get_kind(msg) == JV_KIND_STRING) {
FAIL(*yylloc, jv_string_value(msg));
} else {
FAIL(*yylloc, "Invalid literal");
}
jv_free(msg);
jv_free(yylval->literal);
yylval->literal = jv_null();
}
return tok;
}
}
}
static block gen_dictpair(block k, block v) {
return BLOCK(gen_subexp(k), gen_subexp(v), gen_op_simple(INSERT));
}
static block gen_index(block obj, block key) {
return BLOCK(gen_subexp(key), obj, gen_op_simple(INDEX));
}
static block gen_binop(block a, block b, int op) {
const char* funcname = 0;
switch (op) {
case '+': funcname = "_plus"; break;
case '-': funcname = "_minus"; break;
case '*': funcname = "_multiply"; break;
case '/': funcname = "_divide"; break;
case EQ: funcname = "_equal"; break;
case NEQ: funcname = "_notequal"; break;
case '<': funcname = "_less"; break;
case '>': funcname = "_greater"; break;
case LESSEQ: funcname = "_lesseq"; break;
case GREATEREQ: funcname = "_greatereq"; break;
}
assert(funcname);
return gen_call(funcname, BLOCK(gen_lambda(a), gen_lambda(b)));
}
static block gen_format(block a, jv fmt) {
return BLOCK(a, gen_call("format", BLOCK(gen_lambda(gen_const(fmt)))));
}
static block gen_update(block object, block val, int optype) {
block tmp = block_bind(gen_op_var_unbound(STOREV, "tmp"),
gen_noop(), OP_HAS_VARIABLE);
return BLOCK(gen_op_simple(DUP),
val,
tmp,
gen_call("_modify", BLOCK(gen_lambda(object),
gen_lambda(gen_binop(gen_noop(),
gen_op_var_bound(LOADV, tmp),
optype)))));
}
%}
%%
TopLevel:
Exp {
*answer = $1;
} |
FuncDefs {
*answer = $1;
}
FuncDefs:
/* empty */ {
$$ = gen_noop();
} |
FuncDef FuncDefs {
$$ = block_join($1, $2);
}
Exp:
FuncDef Exp %prec ';' {
$$ = block_bind($1, $2, OP_IS_CALL_PSEUDO);
} |
Term "as" '$' IDENT '|' Exp {
$$ = gen_var_binding($1, jv_string_value($4), $6);
jv_free($4);
} |
"fold" Term "as" '$' IDENT '(' Exp ')' {
$$ = gen_fold(jv_string_value($5), $2, $7);
jv_free($5);
} |
"if" Exp "then" Exp ElseBody {
$$ = gen_cond($2, $4, $5);
} |
"if" Exp error {
FAIL(@$, "Possibly unterminated 'if' statment");
$$ = $2;
} |
Exp '=' Exp {
$$ = gen_call("_assign", BLOCK(gen_lambda($1), gen_lambda($3)));
} |
Exp "or" Exp {
$$ = gen_or($1, $3);
} |
Exp "and" Exp {
$$ = gen_and($1, $3);
} |
Exp "//" Exp {
$$ = gen_definedor($1, $3);
} |
Exp "//=" Exp {
$$ = gen_update($1, gen_definedor(gen_noop(), $3), 0);
} |
Exp "|=" Exp {
$$ = gen_call("_modify", BLOCK(gen_lambda($1), gen_lambda($3)));
} |
Exp '|' Exp {
$$ = block_join($1, $3);
} |
Exp ',' Exp {
$$ = gen_both($1, $3);
} |
Exp '+' Exp {
$$ = gen_binop($1, $3, '+');
} |
Exp "+=" Exp {
$$ = gen_update($1, $3, '+');
} |
'-' Exp {
$$ = BLOCK($2, gen_call("_negate", gen_noop()));
} |
Exp '-' Exp {
$$ = gen_binop($1, $3, '-');
} |
Exp "-=" Exp {
$$ = gen_update($1, $3, '-');
} |
Exp '*' Exp {
$$ = gen_binop($1, $3, '*');
} |
Exp "*=" Exp {
$$ = gen_update($1, $3, '*');
} |
Exp '/' Exp {
$$ = gen_binop($1, $3, '/');
} |
Exp "/=" Exp {
$$ = gen_update($1, $3, '/');
} |
Exp "==" Exp {
$$ = gen_binop($1, $3, EQ);
} |
Exp "!=" Exp {
$$ = gen_binop($1, $3, NEQ);
} |
Exp '<' Exp {
$$ = gen_binop($1, $3, '<');
} |
Exp '>' Exp {
$$ = gen_binop($1, $3, '>');
} |
Exp "<=" Exp {
$$ = gen_binop($1, $3, LESSEQ);
} |
Exp ">=" Exp {
$$ = gen_binop($1, $3, GREATEREQ);
} |
Term {
$$ = $1;
}
FuncDef:
"def" IDENT ':' Exp ';' {
$$ = gen_function(jv_string_value($2), gen_noop(), $4);
jv_free($2);
} |
"def" IDENT '(' IDENT ')' ':' Exp ';' {
$$ = gen_function(jv_string_value($2),
gen_op_block_unbound(CLOSURE_PARAM, jv_string_value($4)),
$7);
jv_free($2);
jv_free($4);
} |
"def" IDENT '(' IDENT ';' IDENT ')' ':' Exp ';' {
$$ = gen_function(jv_string_value($2),
BLOCK(gen_op_block_unbound(CLOSURE_PARAM, jv_string_value($4)),
gen_op_block_unbound(CLOSURE_PARAM, jv_string_value($6))),
$9);
jv_free($2);
jv_free($4);
jv_free($6);
}
String:
QQSTRING_START { $<literal>$ = jv_string("text"); } QQString QQSTRING_END {
$$ = $3;
jv_free($<literal>2);
} |
FORMAT QQSTRING_START { $<literal>$ = $1; } QQString QQSTRING_END {
$$ = $4;
jv_free($<literal>3);
}
QQString:
/* empty */ {
$$ = gen_const(jv_string(""));
} |
QQString QQSTRING_TEXT {
$$ = gen_binop($1, gen_const($2), '+');
} |
QQString QQSTRING_INTERP_START Exp QQSTRING_INTERP_END {
$$ = gen_binop($1, gen_format($3, jv_copy($<literal>0)), '+');
}
ElseBody:
"elif" Exp "then" Exp ElseBody {
$$ = gen_cond($2, $4, $5);
} |
"else" Exp "end" {
$$ = $2;
}
ExpD:
ExpD '|' ExpD {
$$ = block_join($1, $3);
} |
Term {
$$ = $1;
}
Term:
'.' {
$$ = gen_noop();
} |
Term '.' IDENT {
$$ = gen_index($1, gen_const($3));
} |
'.' IDENT {
$$ = gen_index(gen_noop(), gen_const($2));
} |
/* FIXME: string literals */
Term '[' Exp ']' {
$$ = gen_index($1, $3);
} |
Term '[' ']' {
$$ = block_join($1, gen_op_simple(EACH));
} |
LITERAL {
$$ = gen_const($1);
} |
String {
$$ = $1;
} |
FORMAT {
$$ = gen_format(gen_noop(), $1);
} |
'(' Exp ')' {
$$ = $2;
} |
'[' Exp ']' {
$$ = gen_collect($2);
} |
'[' ']' {
$$ = gen_const(jv_array());
} |
'{' MkDict '}' {
$$ = BLOCK(gen_subexp(gen_const(jv_object())), $2, gen_op_simple(POP));
} |
'$' IDENT {
$$ = gen_location(@$, gen_op_var_unbound(LOADV, jv_string_value($2)));
jv_free($2);
} |
IDENT {
$$ = gen_location(@$, gen_call(jv_string_value($1), gen_noop()));
jv_free($1);
} |
IDENT '(' Exp ')' {
$$ = gen_call(jv_string_value($1), gen_lambda($3));
$$ = gen_location(@1, $$);
jv_free($1);
} |
IDENT '(' Exp ';' Exp ')' {
$$ = gen_call(jv_string_value($1), BLOCK(gen_lambda($3), gen_lambda($5)));
$$ = gen_location(@1, $$);
jv_free($1);
} |
'(' error ')' { $$ = gen_noop(); } |
'[' error ']' { $$ = gen_noop(); } |
Term '[' error ']' { $$ = $1; } |
'{' error '}' { $$ = gen_noop(); }
MkDict:
{
$$=gen_noop();
} |
MkDictPair { $$ = $1; }
| MkDictPair ',' MkDict { $$=block_join($1, $3); }
| error ',' MkDict { $$ = $3; }
MkDictPair
: IDENT ':' ExpD {
$$ = gen_dictpair(gen_const($1), $3);
}
| String ':' ExpD {
$$ = gen_dictpair($1, $3);
}
| String {
$$ = gen_dictpair($1, BLOCK(gen_op_simple(POP), gen_op_simple(DUP2),
gen_op_simple(DUP2), gen_op_simple(INDEX)));
}
| IDENT {
$$ = gen_dictpair(gen_const(jv_copy($1)),
gen_index(gen_noop(), gen_const($1)));
}
| '(' Exp ')' ':' ExpD {
$$ = gen_dictpair($2, $5);
}
| '(' error ')' ':' ExpD { $$ = $5; }
%%
int jq_parse(struct locfile* locations, block* answer) {
struct lexer_param scanner;
YY_BUFFER_STATE buf;
jq_yylex_init_extra(0, &scanner.lexer);
buf = jq_yy_scan_bytes(locations->data, locations->length, scanner.lexer);
int errors = 0;
*answer = gen_noop();
yyparse(answer, &errors, locations, &scanner);
jq_yy_delete_buffer(buf, scanner.lexer);
jq_yylex_destroy(scanner.lexer);
if (errors > 0) {
block_free(*answer);
*answer = gen_noop();
}
return errors;
}
int jq_parse_library(struct locfile* locations, block* answer) {
int errs = jq_parse(locations, answer);
if (errs) return errs;
if (!block_has_only_binders(*answer, OP_IS_CALL_PSEUDO)) {
locfile_locate(locations, UNKNOWN_LOCATION, "error: library should only have function definitions, not a main expression");
return 1;
}
return 0;
}
+20 -8
View File
@@ -1,6 +1,6 @@
#!/bin/sh
# This script is used to cross-compile binaries for
# This script is used to cross-compile binaries for
# platforms other than the current one
# Usage: $0 <platformname> <configure options>
@@ -13,19 +13,31 @@
set -e
cd `dirname "$0"`/../build
jobs=-j4
case "X$1" in
X-j*) jobs=$1; shift;;
esac
plat="$1"
[ -z "$plat" ] && exit 1
shift
case "$plat" in
*/*) echo "platform name must not be a path"; exit 1;;
*..*) echo "platform name must not be a path"; exit 1;;
*) plat=$PWD/$plat;;
esac
[ -d "$plat" ] || mkdir "$plat"
rm -rf "$plat/tmp"
mkdir "$plat/tmp"
cd "$plat/tmp"
mkdir install_other
../../../configure \
--prefix="`pwd`/install_other" \
--bindir="`pwd`/.." \
"$@"
make install-binaries
../../../configure "$@"
make "$jobs" DESTDIR=$plat install
set -x
for jq in `find . -type f \( -name jq -o -name jq.exe \) -print`; do
cp "$jq" ..
done
cd ..
rm -rf tmp
rm -rf tmp
@@ -6,13 +6,11 @@ mask = lambda n: (1 << n) - 1
def print_table(type, name, t):
assert len(t) == 256
print("static const %s %s[] =" % (type, name))
first = True
for i in range(0,len(t),16):
print ((" {" if i == 0 else " ") +
", ".join("0x%02x"%n for n in t[i:i+16]) +
("," if i + 16 < 256 else "};"))
", ".join("0x%02x"%n for n in t[i:i+16]) +
("," if i + 16 < len(t) else "};"))
def utf8info(c):
@@ -23,10 +21,11 @@ def utf8info(c):
if 0xE0 <= c <= 0xEF: return 3, mask(4)
if 0xF0 <= c <= 0xF4: return 4, mask(3)
if 0xF4 <= c <= 0xFF: return 0, 0
table = lambda i: [utf8info(c)[i] for c in range(256)]
print("#define UTF8_CONTINUATION_BYTE ((unsigned char)255)")
print_table("unsigned char", "utf8_coding_length", table(0))
print_table("unsigned char", "utf8_coding_bits", table(1))
print_table("int", "utf8_first_codepoint", [0, 0x0, 0x80, 0x800, 0x10000])
+29
View File
@@ -0,0 +1,29 @@
#!/bin/sh
# This script builds the website from the docs directory of
# the current branch and copies it over to the gh-pages
# branch.
set -eu
set -o xtrace
# build website
scriptdir=`dirname "$0"`
cd "$scriptdir"/../docs
rm -rf output
rake build
cd ..
# copy to /tmp
tmpdir=$(mktemp -d -t jq.website.XXXXXXXXXX)
cp -r docs/output/* "$tmpdir"
cp .gitignore "$tmpdir"
# copy to gh-pages
git checkout gh-pages
cp -r "$tmpdir"/* .
cp "$tmpdir"/.gitignore .
# clean up
rm -rf "$tmpdir"
echo SUCCESS
+10
View File
@@ -0,0 +1,10 @@
#!/bin/sh
set -e
cd `dirname "$0"`
if git rev-parse --verify -q jq-1.0 > /dev/null 2>&1; then
git describe --tags --match 'jq-*' --dirty | sed 's/^jq-//'
else
b=`git rev-parse --abbrev-ref HEAD`
c=`git describe --always --dirty`
echo "${b}-${c}"
fi
-32
View File
@@ -1,32 +0,0 @@
#!/usr/bin/env bash
# RUN ME after pulling the code from git!
#
# This script is handy after pulling the code out of git without having
# to remember all the typing needed to build up and tear down all the
# crap that autotools puts in your source repo. The intent is to keep
# all generated files out of git.
if [ "clean" == "$1" ]; then
make distclean || echo "continuing..."
rm -rf tmp autom4te.cache config
rm -f INSTALL Makefile.in aclocal.m4 configure config.h.in ChangeLog
rm -f jv_utf8_tables.gen.h lexer.c lexer.h parser.c parser.h
elif [ "superclean" == "$1" ]; then
# if autoconf errors during distcheck, it leaves files that need chmod'ing
ver=$(tr -d '\n' <VERSION)
if [ "x${ver}" != "x" ]; then
if [ -d jq-${ver} ]; then
chmod -R u+w jq-${ver}
rm -rf jq-${ver}
fi
rm -f jq-${ver}*
fi
else
autoreconf --install
./configure --prefix=/opt/junk
make check
mkdir tmp
make DESTDIR=./tmp install
make distcheck
fi
+41
View File
@@ -0,0 +1,41 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: jq Release Signing Key 0xAF19040C71523402
mQINBFYayakBEADL6biudAZ3V1//e3gdWMN6lbz+m5o6avu1vnbtCul/MxOF2Ygd
SeXCn5gV3+F+xdrA3/Mhv9cWXzzDTp0D2U75mHw1n4OcArFvKm/RV5yOlc/wvblp
WfWd/hCIIZhdHpRWdCko2ByXx9XlBRn46nGyxCFScLcHbicPjq2kIpZ7oad29gs4
bThj65G5XS48FyqixGHy0o2S0nQXNIyB1XTPm4mwHNAeOMFaYj6nhb6b5vu+RhlK
syirTGU7pZYd13FM5y9NZrbxfKnGz5bdKPgb4jRi3YmBTKRzlW4IZl3SGO3kPi9a
wJR4vP+cf1eEAWulrt9i4DA3/3/lpPpFh5bSo7nKW49PdOjfLWzBLtCsVhJReF97
sSPVpNmf6RrfBXnPlEBw+aU4wGRbmpA9AGV2rKsvxZbU2AqDS93Pn6S0u4XNNnjH
TGxe2P9gSEH+xNuEyFcDbt0XP6Te3vSE7oMGIPhXq1FKuXygEQGV2fXa2Dovxi+q
YTvbtzG5PV5lQqeexoNMUHzgHVWib/NIt7JTkBflJt33re7oayZd5DSE5zy/4n5d
LH9prYJWqVGgb92Lzlk6uYDp3ztBlFdoRR+6L25iUCPRq5yS7J4Rk3ahask2CsQc
aANz5xkESnS5DcakDoVtbiC1UY8eM+vXui/UF2uYCTLrz+SIIZJHPQ0fdQARAQAB
tC5qcSBSZWxlYXNlIFNpZ25pbmcgS2V5IDxqcUBzdGVkb2xhbi5naXRodWIuaW8+
iQI4BBMBAgAiBQJWGsmpAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRCv
GQQMcVI0AoHwD/4s1L10OiimSELwTZ3x+btmKdaFBdlUhjBZd/GDE3P1pV+63D2+
LhLpZLQ3yOrplUDHGBG02Hx7/lY2YE5rRVNMyR8FqD9aMrOwQE3uERjkwFQ7Q69r
S6kFLiOxUWDXNQ0wXeZ/Na6uYi6AI/oCYWnDIO3lugDUoXtHanYqK1BvJsBEvWpe
UB18VcqxBQuOMPD+xNzVDSFn1uYiKKBkv4XJNLHRqdLpwmAVcLDkKTHWEy+223CZ
4zwahQKw9wPdUlakXP7v+wIxzGXaGk0yJOsYVPykQ4AkoMgvqqxyx23d6hjncR1o
36muLAiL+qELZ/rxUytduaK1Owr8cNJgPzRAEbeSRdw2hZYyEnHgNPC3atUN0wIk
khzP/GHMBYIU90CdiWjGvjJeHv047Ty4S9PEYPZLQx1s8cdIeozEFt/lTqFp+9Si
f2DWUKHpzQ3wfUudTD4pzSy28XJ760Kq54f1cf2CWqp577xrxRfcKKoyufF8pwqf
sAno03N6MpxiK0qVwZ/0Qb2BfAI2rpxxc98qhuErlBE8WjPj7M93eaHNMTtCqCIG
Hke6kMjYuwGu8NK/O0SqGqsHoXxxIvlZNda9MCPJo9xl77dphurOq/D/d9rfy/Uk
5D8ssNUBhM3s6sQl27L1avnSS12UuRdGSQwU33XbAuNG7y0a/zRnX+GqE4kCHAQQ
AQIABgUCVhrKpwAKCRD5uhQ7lf9tgo26D/0WFFkhmUjSV9K/q8zSSJhuQfzoeM+n
Z2DfYBfKdawbJH9/Yfg1nIFzih2lnvzk/kx8WbLSDMb0sHn6ZUZ6cVoBvrBxSgah
bwPF9M8Xf4J/oBYHq8ZYjPHOWnHbEPuoNzPreqOhtSLBtP5dfZlEI6DLR2+WKj22
EmHfmBFoKZ90N2MQWQLV98DAFfsxS7Bqc9xSCbh405qCIGr/4r4P0BaIdJ2jW/9k
AHwnsmJnf5lI7dn8BEMYgM3vcG4dyaWNf+eoI3cJnq+Y782KoyFjof4t1bLF2H1C
vbiJ9xWv4uCeTVlTwiVJFkSUxBgmsyVofcboHF7/06HtVXDpG/ihZEOoqNPKPD4d
56V2t0hEulUpyqfs0Ic8r+sGWgvDCSqAVrXak2n0ULJ+RkpRB6ekcgOY7HdYKX1H
UifaytQSxjUBXfo9HAC0Br2fyGh9s5zBcnrIrWHxwQw/RCIIv9CkZB7s6/NFYBKw
Q27xTpXjHnGoEHNAA2xSyMXw9VoH3qoze/1iraK0zSFGAXpmL57HMBnOrLj7oq+O
tB/cLd9o4+XFJjXHGAsXoOD5cCADkgMSMcouvPFKySfK0Kz5ScWVSsc5FvG44j/L
T1WvjBgIrNAeQJ2efPYVmg5f/ALkjgnKy+lkafBk4OwXtWZCTf+9vcOF7FQ2B6N+
7qQPymxSJxBSEg==
=AiyG
-----END PGP PUBLIC KEY BLOCK-----
+17
View File
@@ -0,0 +1,17 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQIcBAABAgAGBQJWGzhJAAoJEK8ZBAxxUjQC8xMQAMgSl+2aYa/c/LuYKDWtVnHO
G16rAq+oruc/IrEwEKqcwqTvK8M7xlAxUt5aPtAY0kRkvxadFtX8vZy1SEqAFcC5
sw7J+Oswl+5dJF0Y3j3I0hA6JuOe/+RP4r64pGlwQ0mVIJuTWqinzO9JqTOskeXy
5vSN50A0vFXzDu661UFr1v8q5+b8WhIrJhuOZtaPap33Gu9bS6fz93VBm4LE3a04
KjDydbNUoyA5HX4QVTgFON8oeVJevtqV3krnsU/ncOeTB0ThT9yywcq8HCbh7dqo
EhfyATOmk3RZf3RsSAOG5CZ9cFjof6/SqVG8Cbp14MRVMkKi37mvHkqFER/WRtsv
Ul1OzFfv8Jwv+cItTSB5c80kbbRfrqwf6NgZW9oTxZP3G3I5JjCTYhCaWlzO0wZ1
QAAJDBAv5GNB4rn9LXGdj2DhcCh00lJY83Bpup4LRc2RuJuJH7IUIkfRW4CAVoRd
p6w5W4jYNdrrTkhfkNxSqi7FtKN23+eD2r0knPvhsWxyUcXrGhFqaImHmzQWIsX5
AviEK+nQUcuhTKolsN/97NPkRYUT9C4IVNdI8m1+EsAuwGodSvRrUwBIOoVQlYA7
MFLZZ23Su/8T5NnruP+iXmy0Y3Nf9W+GLHNn3H+9027zAs5Esd2Hy4R6W65BwWuI
yYHFx8O6bi5ke72ByCUI
=ru7X
-----END PGP SIGNATURE-----
+17
View File
@@ -0,0 +1,17 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQIcBAABAgAGBQJWGzhxAAoJEK8ZBAxxUjQCb2EP/08Lgfoc0rDv5IirCjXIFWxM
8C56aVfaF/8gaG75SuN3QUVBuWx3VB60Cgh/msTFrZ/jkWr+tYArNzwNAjI8a9T8
nE40SJH3kvwVrr9ALSgk9fEvikfZVKwYTc0k4h1hBataE5Z+7Di7VYPUmdLTd/ih
dcJfDe6zPcYmaW6fl0glP2GLaDuLI3vxAid0MzDS1RU52z+usc/fjXWmaJwPVp76
Sd8/Uz3X6ZiFwpkfhp6XTcqkQhMZd4GS9cjnPAdRp9HFLI7S2UJ4RNj/YQIHrhQL
5Ko3KdXEWeSvD8wcr8VcZ66NfmyCls0diEU+TUv1I7VmLzVQGx9/4/uVWpfxry9D
8MLEHEJTTDT5W3hX47g29JRFJzv8PUyugkpXjQrpSoFbe/3vRxZeQNO9rjTx9t3x
hdkWIjbwTg8SGH0XK+UNfR50A3VlrlPDpW5Ju2Io7/OuKRWN4i6ktFx0akFMmHUV
D5u/FhEux7kJCNHnF7a7YJ1Ys4OSPUzoH3z35zhyVcW+iiX7KIKHNamWaPBw3iYa
MwYVKHT6NUQiVQbTZvWJZXGArEnwq/z6jAjRQNKoTjbcVoYJunY/DZcJjnRIux9T
yYnTa7IbpWZmWZWQfnb8zuSoXnhaSHZItIeUklH4K03xjpEXW7pGPLPznyDoBQeC
1WVcwpviS/Y24eSmmxaA
=MlHu
-----END PGP SIGNATURE-----
+17
View File
@@ -0,0 +1,17 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQIcBAABAgAGBQJWGzh+AAoJEK8ZBAxxUjQCyb4QALrsqZ/QkI2a/uVPnwAh22B4
mtbplxOS8swCB4g56tG+JMuria9l1ACmpbc9eTJ/Q9z9LLwq3vBkpy0utAQp/iAQ
ijZbTG7E3S/LtOzZ5MSbkGeyuDWu4YCI7DuxTZH+R43fiA/ShHUHf7rO/vofAjTu
MZr7TpBRjut5htbkNrUKoYjK97hehvY0S3h1oqMSSuHS4Em9xMvv5bAsEn37+L3g
o5Y5kHQ55Lu3qH1Uk87VMz+gtO4pxN+ZrNNrY2lX/hwnV7p5YDza2H0uOopBrTi4
X99x9JzdHoSrySRwS1ZDc+XYDgXP7JO9qDmNh18nXJlyCWFzDHajQS+4Hn0O5zM0
PHWasVC8tmxT0XXZlG1kPuaCkg0BFh1NXNjCUa7Ru9XHfOkaW4TyKGQa3eboyx56
q7MDvODUd3JSW4xmLJ7NFSYRCPMRiCMorQ8u8afy2OWt2W13M8OIH378dMcFoubW
GB00i127dhuI95lwNsTV1seKO59bMbAJjP7ITqqDiOafg6AmTric6BJNakSsrc66
yCzhOfxqwfeRekPSirrf8nv9D7dW45yLEiXn9Irn+KghdL4KCLCB8dyc6OalITVF
c01SK5xNzPRfFVzTqMdmi/dYpDL0KSMwg3O3DhPQ0LrRZDXKXj6A4KGAthpVLmRr
IHj2hlGlr4hqLXUU1wE5
=I3PU
-----END PGP SIGNATURE-----
+17
View File
@@ -0,0 +1,17 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQIcBAABAgAGBQJWGziCAAoJEK8ZBAxxUjQCkGcQAMpxoK6aHzDIeVjp5kQ4MOFu
dOE0xjXlPpudUfUORKqfsnPvvxJTvqlDrUhMq6d6S1Eic9ZAbfpmHGbw02tvQ7+4
hvyy/KbfBUcLZRIwZ1eej/rFUXd2fmxPwoj07SpTOgjKF+8duUzSlxBg+Kes77pj
ZuMO3KUa3isaOp+kufh0+miAqHisEWzQWCfHBrVIwW63L2bf2ZSUvp4JqwfRKfr2
3hBfoll0M+iaLHr4/wGUIxRL+23afTtvQikyOXzB3rKXf+QmDePZ29isZVg94yi4
/XiDVmDM/6GpfI7u0fIoDcEgH+LE35HL/CT4zA8IzA/QwB5bCO1bPEA7DfDQq01R
oghTvH5Qu0eu8tjap7EXAmch25nPys4NzPoIRnbu4i4wQUsFqGzmSFKEuU6pwDIm
lsEBPbHRcGcaui2KidUNi7iQmje819KgRDhRxX65Bye9sKsD/HvMzQRce1RFYQg3
uqISuhWu8qj67J/ii2zFF+lo5HgHLqzXKcye1kY5KYq2dTIa3khq89Xkf3trsnNL
IKZ+8P2eiVDjDr3UPIvVCX1JvNTdcQDMUlmoKk8g1qwuTp2PTi+c6FKicZGUMMnv
o/hThK2JwnL/Iv0bJHvBU6aCXSnKLTLIdT02UvUppiN/GTMHsagvE0DRA1B1yFim
/o/n4edysfzI1Pxe0b3c
=ZOqW
-----END PGP SIGNATURE-----
Loaded 100 of 201 files, more files were not shown because too many files have changed in this diff. Show more