Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5b5cbefb8 | ||
|
|
365c1000e7 | ||
|
|
f957a5d639 | ||
|
|
f98c2b375d | ||
|
|
70335ccd4f | ||
|
|
4723a173f5 | ||
|
|
c4ee746b16 | ||
|
|
5843bb350f | ||
|
|
b60c9eb3e8 | ||
|
|
068300229b | ||
|
|
66f7ce5ac3 | ||
|
|
3045979f6c | ||
|
|
d66fbd218b | ||
|
|
b5edbf7ffa | ||
|
|
6b55baa00f | ||
|
|
7f251344b7 | ||
|
|
21309bc6d7 | ||
|
|
8295baf284 | ||
|
|
ec84f28630 | ||
|
|
701a47c82e | ||
|
|
616f365e5a | ||
|
|
ceb2684f2f | ||
|
|
b9c340a211 | ||
|
|
3a964e2025 | ||
|
|
3d49fc59dd | ||
|
|
16e8d0b1ab | ||
|
|
5856a2d2c0 | ||
|
|
227f62e013 | ||
|
|
89244cc3ea | ||
|
|
3a43e2ff07 | ||
|
|
81f328f1aa | ||
|
|
f5a7bba986 | ||
|
|
66ef8e2c24 | ||
|
|
1628bbf95f | ||
|
|
812703139c | ||
|
|
54add5ac9a | ||
|
|
f183b57ed5 | ||
|
|
dc4dfdff17 | ||
|
|
f55034d314 | ||
|
|
930899e12d | ||
|
|
579518c78d | ||
|
|
fa45a5121c | ||
|
|
862566a48f | ||
|
|
f9f4d2d1e5 | ||
|
|
b74379532d | ||
|
|
1e5e0c9fe2 | ||
|
|
05899f8b3e | ||
|
|
a2a6f2d896 | ||
|
|
1c350c67d7 | ||
|
|
2348b7245e | ||
|
|
6e27de4f74 | ||
|
|
e5dafaea44 | ||
|
|
fd4f4f2087 | ||
|
|
6c89186437 | ||
|
|
32c4759e6b | ||
|
|
6366cfd7a4 | ||
|
|
9985c01975 | ||
|
|
e6371712ff | ||
|
|
d7e35101c5 | ||
|
|
1defaa7b00 | ||
|
|
815b4c9772 | ||
|
|
aaf305868c | ||
|
|
8cc31f0f49 | ||
|
|
a011ac6392 | ||
|
|
505e23124f | ||
|
|
e7f6d1e6d0 | ||
|
|
a220482de6 | ||
|
|
e16bd17571 | ||
|
|
25d47ca08e | ||
|
|
5108a451ca | ||
|
|
ec7647c4ab | ||
|
|
8aecf82bfe | ||
|
|
10cbb9b580 | ||
|
|
4a316fbb5a | ||
|
|
7811ef1e17 | ||
|
|
b04cd6aada | ||
|
|
1146b8b84a | ||
|
|
292f2d3208 | ||
|
|
3cbefde376 | ||
|
|
0b42457929 | ||
|
|
51a81c96f1 | ||
|
|
6083581fea | ||
|
|
164b877bfa | ||
|
|
b9c2a326ba | ||
|
|
bdc1feb50e | ||
|
|
4ef04e5b5c | ||
|
|
0f5345e515 | ||
|
|
c95b4a8ab4 | ||
|
|
520b429ca0 | ||
|
|
d3343d5113 | ||
|
|
2e96fb2c9b | ||
|
|
24a5e5b1b1 | ||
|
|
74ecb88935 | ||
|
|
33874eb513 | ||
|
|
1de56bc5df | ||
|
|
8a79f1d0a3 | ||
|
|
f4f5d8882d | ||
|
|
4451c08007 | ||
|
|
89c57f7936 | ||
|
|
6af7857ccd | ||
|
|
dff96aebcf | ||
|
|
8af52aaf52 | ||
|
|
d66e434fb4 | ||
|
|
3700b457aa | ||
|
|
11f084f9a7 | ||
|
|
454a9dc042 | ||
|
|
ff458803ce | ||
|
|
110e009996 | ||
|
|
7b6a018dff | ||
|
|
a50e548cc5 | ||
|
|
4b258f7d31 | ||
|
|
d1cb8ee0ad | ||
|
|
c7f063188f | ||
|
|
a6460f4fe2 | ||
|
|
2e257563a6 | ||
|
|
ad0090964b | ||
|
|
cbdaeb4062 | ||
|
|
cf1306f469 | ||
|
|
7675f7434a | ||
|
|
821d6404b6 | ||
|
|
e3cb1f76cd | ||
|
|
ef12efbf8c | ||
|
|
adb9b9b8a7 | ||
|
|
07f94f82a2 | ||
|
|
215b4c0fe1 | ||
|
|
89963e1370 | ||
|
|
5d40f3a7c0 | ||
|
|
5e0e7a7ebd | ||
|
|
dad6e42934 | ||
|
|
7d938487dd | ||
|
|
fcfacb932d | ||
|
|
6906d291c5 | ||
|
|
943090846f | ||
|
|
2dc8621d05 | ||
|
|
b6cc00fa71 | ||
|
|
9e2d9b6419 | ||
|
|
3210b29bba | ||
|
|
ddad9618dc | ||
|
|
24005287f4 | ||
|
|
1dcfc2f547 | ||
|
|
7d6d4066dd | ||
|
|
4c22bda09b | ||
|
|
9d62c6fd0c | ||
|
|
5e0db6dd65 | ||
|
|
551d875be1 | ||
|
|
4f8567476d | ||
|
|
ffa2832e33 | ||
|
|
0f7759f831 | ||
|
|
ccfba00178 | ||
|
|
3e8183fcd5 | ||
|
|
0df387f6b5 | ||
|
|
4104c4fa1c | ||
|
|
33a85679b9 | ||
|
|
a4b9552c82 | ||
|
|
b82c231900 | ||
|
|
3d2ab93b11 | ||
|
|
c86ef36769 | ||
|
|
3b8d08177f | ||
|
|
0164ff0bbc | ||
|
|
a4baac2256 | ||
|
|
1e5e9f3ef8 | ||
|
|
d58d85af9e | ||
|
|
10e8d34fd3 | ||
|
|
ebc090ad15 | ||
|
|
8cef5a37ab | ||
|
|
8afdeee785 | ||
|
|
a83a9e0bc2 | ||
|
|
0d414471bb | ||
|
|
91fb3df495 | ||
|
|
373ef71feb | ||
|
|
ca78a746e6 | ||
|
|
1e13e1e06e | ||
|
|
42ff8a6959 | ||
|
|
2e92c3e568 | ||
|
|
5389fdb651 | ||
|
|
7a295b30e0 | ||
|
|
cca3e92854 | ||
|
|
4d05dc55a3 | ||
|
|
aeb52e29d6 | ||
|
|
97602456e3 | ||
|
|
8b5ff40402 | ||
|
|
d630597e87 | ||
|
|
60d1ecb58a | ||
|
|
d927a2c185 | ||
|
|
6e7cf81d74 | ||
|
|
736f1751ee | ||
|
|
28aab9ca79 | ||
|
|
972c048149 | ||
|
|
902aa39fce | ||
|
|
22f55aa585 | ||
|
|
157c95b988 | ||
|
|
426913f127 | ||
|
|
c4cc62a053 | ||
|
|
862696a778 | ||
|
|
86bc662bd2 | ||
|
|
ae7f8d6ab9 | ||
|
|
7dc34b92af | ||
|
|
cbfc0d6130 | ||
|
|
c308b2881f | ||
|
|
c959d1fca1 | ||
|
|
63511a874f | ||
|
|
90c705f138 | ||
|
|
b67bad82cb | ||
|
|
6981b46338 | ||
|
|
752e00bc66 | ||
|
|
00f018a054 | ||
|
|
56344670f4 | ||
|
|
5df20f4954 | ||
|
|
a9c613e87d | ||
|
|
7538ef34be | ||
|
|
5c62a4b805 | ||
|
|
559863ca68 | ||
|
|
845ad5e969 | ||
|
|
243b1f8e5e | ||
|
|
5bfb9781f7 | ||
|
|
906d2537b9 | ||
|
|
bbb287f54b | ||
|
|
e51e916e31 | ||
|
|
46e3125e26 | ||
|
|
c02fcc8fef | ||
|
|
25d4cbd1b3 | ||
|
|
3234a7681e | ||
|
|
36077da66a | ||
|
|
9e1fd8cf4d | ||
|
|
a55085b662 | ||
|
|
e0f9b6a5cd | ||
|
|
0053aa868c | ||
|
|
fab2048648 | ||
|
|
56ae88d9d5 | ||
|
|
1cdcff1c01 | ||
|
|
8ca07a08c3 | ||
|
|
2775b90b20 | ||
|
|
ae312bd7fe | ||
|
|
9017b83d4e | ||
|
|
02cf1831e9 | ||
|
|
d237de7b30 | ||
|
|
84d3203dd1 | ||
|
|
a3234034b5 | ||
|
|
b748eae035 | ||
|
|
a6656edc7c | ||
|
|
b4a9ea56ae | ||
|
|
fdbc91e3c4 | ||
|
|
bd67bb8273 | ||
|
|
54a0470c42 | ||
|
|
3dd790c408 | ||
|
|
be11b2768f | ||
|
|
2075bec60f | ||
|
|
44c2382402 | ||
|
|
fd041c2064 | ||
|
|
c6495f6632 | ||
|
|
7243989c52 | ||
|
|
46613af64c | ||
|
|
79000644c6 | ||
|
|
b349e7d9a8 | ||
|
|
6c8882caf3 | ||
|
|
30e00820a7 | ||
|
|
0f81e1bcd0 | ||
|
|
cb376b27f8 | ||
|
|
dc5e77ef8e | ||
|
|
72735167f9 | ||
|
|
89791a000b | ||
|
|
3411167c03 | ||
|
|
85f0e30c81 | ||
|
|
1796a716ea | ||
|
|
07d8d5c5ef | ||
|
|
0b29b44cab | ||
|
|
a0a350f468 | ||
|
|
4a57b84db0 | ||
|
|
f7a2af7052 | ||
|
|
456bafa82f | ||
|
|
7a8e3c759e | ||
|
|
b70bea8d34 | ||
|
|
d177944b75 | ||
|
|
9bd55487ea | ||
|
|
23e2e2eab3 | ||
|
|
8d2d5e37e5 | ||
|
|
287e2c96ed | ||
|
|
f8d9478517 | ||
|
|
1ba8c2cfa6 | ||
|
|
d654724fef | ||
|
|
3375089013 | ||
|
|
9f13afa20f | ||
|
|
908c10928b | ||
|
|
c321c3b86b | ||
|
|
f87521183f | ||
|
|
8a561120c4 | ||
|
|
20ca21cb0d | ||
|
|
2d1a75f550 | ||
|
|
8cddb7c681 | ||
|
|
4249bbf0d5 | ||
|
|
8a57c27e92 | ||
|
|
8706b6b16a | ||
|
|
32c08d48f3 | ||
|
|
fc52e78ed4 | ||
|
|
eb12f0358e | ||
|
|
a696c6b551 | ||
|
|
0d437e25de | ||
|
|
6744664ff4 | ||
|
|
ef5bd5a6de | ||
|
|
2159f9f5e0 | ||
|
|
2518b3a34f | ||
|
|
c3d6d5fd37 | ||
|
|
a25950a58c | ||
|
|
f8fed0f0bc | ||
|
|
89545ea9d0 | ||
|
|
a2f99d43c3 | ||
|
|
a7878a8d1a | ||
|
|
c73ad74be0 | ||
|
|
53993a9942 | ||
|
|
e1b20b48f0 | ||
|
|
14bc1f6526 | ||
|
|
2e2538ccb8 | ||
|
|
ae27178352 | ||
|
|
0f89270d08 | ||
|
|
10f5a3448d | ||
|
|
50b85c2911 | ||
|
|
38b939688a | ||
|
|
01fc8168e9 | ||
|
|
3362fb3406 | ||
|
|
8c3d503d54 | ||
|
|
2bb9fc5dda | ||
|
|
ea3e947b50 | ||
|
|
538e012e85 | ||
|
|
918ada06dc | ||
|
|
cb2737a433 | ||
|
|
c38e5b1b2c | ||
|
|
089041b090 | ||
|
|
cadf8c3cb0 | ||
|
|
6b6e3f4262 | ||
|
|
6e88d419ba | ||
|
|
ab4bf05300 | ||
|
|
ecac7bd3a1 | ||
|
|
1d620c0de3 | ||
|
|
f68815d5ad | ||
|
|
666aeda82c | ||
|
|
5be80b81eb | ||
|
|
10477fc2d4 | ||
|
|
d8672e1b2a | ||
|
|
a68958e5dc | ||
|
|
824f7df404 | ||
|
|
4bcff40828 | ||
|
|
80a9937e48 | ||
|
|
b963ebaf1d | ||
|
|
eb45372414 | ||
|
|
539dccae90 | ||
|
|
6458910ba3 | ||
|
|
ef9b591215 | ||
|
|
f845808813 | ||
|
|
25719b5596 | ||
|
|
8780bc0b8e | ||
|
|
821cd31e67 | ||
|
|
5a863bf010 | ||
|
|
d0ca11d665 | ||
|
|
7d3a44a1e2 | ||
|
|
7fce34292e | ||
|
|
9113282c27 | ||
|
|
78a8419428 | ||
|
|
ff9a61ead2 | ||
|
|
3a647d3e47 | ||
|
|
1f17ef3623 | ||
|
|
a6030ab374 | ||
|
|
9f4d7e2fb8 | ||
|
|
ba1acbe961 | ||
|
|
9deee38dc8 | ||
|
|
436941d48b | ||
|
|
e1c5a2f575 | ||
|
|
a5e9086676 | ||
|
|
1204e328df | ||
|
|
3e1baf5916 | ||
|
|
beb0d081bb | ||
|
|
4b7c701fdd | ||
|
|
233e32208c | ||
|
|
63e31c2a35 | ||
|
|
f9349becab | ||
|
|
ff5cf0abc7 | ||
|
|
8ff935c01a | ||
|
|
5d9d1b1020 | ||
|
|
8725d9fa3e | ||
|
|
9ae2d66d21 | ||
|
|
0c762925b2 | ||
|
|
ad52026550 | ||
|
|
cf7895876b | ||
|
|
f902d5fae6 | ||
|
|
98e3ebc378 | ||
|
|
dde43f796e | ||
|
|
7ee3b724d1 | ||
|
|
e151a300d0 | ||
|
|
f58f771660 | ||
|
|
ea63d5d3c2 | ||
|
|
ea0ffe24f8 | ||
|
|
061a604a2a | ||
|
|
f741074267 | ||
|
|
de5952d67e | ||
|
|
a03f4802ef | ||
|
|
778ba9f7ab | ||
|
|
676e0ce38e | ||
|
|
088a42fc53 | ||
|
|
63dbac28ad | ||
|
|
e9a1de47b4 | ||
|
|
d14fca0cc6 | ||
|
|
bb83813f51 | ||
|
|
8225d4e0c5 | ||
|
|
d45195ab5c | ||
|
|
73bd347fcf | ||
|
|
c9dbe090c5 | ||
|
|
61cc0d4fb1 | ||
|
|
15c4a7f95f | ||
|
|
20e629284f | ||
|
|
e73951f3d1 | ||
|
|
fdf843c08b | ||
|
|
cf145ec65e | ||
|
|
4889844d0c | ||
|
|
dc7857c585 | ||
|
|
d65dbf89c9 | ||
|
|
ed2b3e26fb | ||
|
|
46436bd870 | ||
|
|
1dbe9317bc | ||
|
|
ef4f3a54fe | ||
|
|
9af03c2562 | ||
|
|
c10e5f4e73 | ||
|
|
01f676041d | ||
|
|
6856ab8a69 | ||
|
|
8212750fe9 | ||
|
|
35b6b949e3 | ||
|
|
d1ea3ab89d | ||
|
|
ae625d0de7 | ||
|
|
5fb82d1018 | ||
|
|
f9d1b94496 | ||
|
|
854ff5643a | ||
|
|
072ebb911b | ||
|
|
d46f5d29fa | ||
|
|
69aa0003af | ||
|
|
41a093c1f2 | ||
|
|
022a418894 | ||
|
|
d056668f4f | ||
|
|
917334d18a | ||
|
|
7a83f1c416 | ||
|
|
6f0a9521e1 | ||
|
|
aee5c3ecb0 | ||
|
|
da0d575649 | ||
|
|
74d2216da2 | ||
|
|
769314a8a2 | ||
|
|
831be04027 | ||
|
|
1a1adf73e8 | ||
|
|
68f41097b9 | ||
|
|
4402c6d806 | ||
|
|
2aa8a43c5b | ||
|
|
219bb9ecb7 | ||
|
|
88fd2ee4f2 | ||
|
|
6c3683dfe9 | ||
|
|
36e495da1e | ||
|
|
15faf9dc3b | ||
|
|
59302fd208 | ||
|
|
24202d1ecf | ||
|
|
336f4e27e6 | ||
|
|
fe29d3d3fa | ||
|
|
3d33412e9a | ||
|
|
fb9196021e | ||
|
|
b23fae9ee3 | ||
|
|
8b41415b07 | ||
|
|
1fa55a3fae | ||
|
|
a45c937f80 | ||
|
|
6ed3adb091 | ||
|
|
106fdf5114 | ||
|
|
99f170adc3 | ||
|
|
f60d83c15f | ||
|
|
36a47bae56 | ||
|
|
dc8528af0f | ||
|
|
e12d0ffd1e | ||
|
|
a71138a43a | ||
|
|
cb976b9a50 | ||
|
|
060eb39bf9 | ||
|
|
ab363e9e50 | ||
|
|
41a8ae7557 | ||
|
|
1956abbedf | ||
|
|
2003a0440f | ||
|
|
a0274cc46e | ||
|
|
3b384740b9 | ||
|
|
4d40a47eab | ||
|
|
18e828f17c | ||
|
|
0966230ba8 | ||
|
|
669f4ab4c3 | ||
|
|
3455714410 | ||
|
|
32ea50d336 | ||
|
|
5ac6a460fa | ||
|
|
f147b7fae5 | ||
|
|
474386a1d9 | ||
|
|
7fd2c2d08b | ||
|
|
5412f3f1c1 | ||
|
|
014b45b4a9 | ||
|
|
30ea390b77 | ||
|
|
00f244385b | ||
|
|
7b671b95d2 | ||
|
|
1535f23455 | ||
|
|
4ba0c8baef | ||
|
|
a7dd3ab793 | ||
|
|
f6f7d4d973 | ||
|
|
f4ae5c883b | ||
|
|
74a14f5de7 | ||
|
|
fee21c959a | ||
|
|
4b48054f41 | ||
|
|
17a319d120 | ||
|
|
3a1dab5396 | ||
|
|
dac081e183 | ||
|
|
489fcdc089 | ||
|
|
3ba7c97b2a | ||
|
|
54635000c5 | ||
|
|
426edff09c | ||
|
|
b37ce20c2a | ||
|
|
cac14a531d | ||
|
|
ae7a042876 | ||
|
|
eb165459aa | ||
|
|
04bc2ef7cf | ||
|
|
09104ce531 | ||
|
|
9fa2173825 | ||
|
|
346da34432 | ||
|
|
fa316ac430 | ||
|
|
77936a594d | ||
|
|
4e07eac356 | ||
|
|
d018e43ddc | ||
|
|
8cee66e609 | ||
|
|
3c4248192d | ||
|
|
255f8ef5be | ||
|
|
20b32db5af | ||
|
|
b634722c8a | ||
|
|
c9e8581f45 | ||
|
|
da129f6664 | ||
|
|
884e6c7d8b | ||
|
|
5aadaa79eb | ||
|
|
cf562961b7 | ||
|
|
63bed9bdf1 | ||
|
|
5989dbdfcf | ||
|
|
db19a11399 | ||
|
|
6c734cb609 | ||
|
|
ef41d1cb57 | ||
|
|
08b4a34a8e | ||
|
|
1fc5656762 | ||
|
|
91cfc34ae4 | ||
|
|
a0b942a7f5 | ||
|
|
6a401c8262 | ||
|
|
d235f32bc9 | ||
|
|
bdbfa7e32c | ||
|
|
78976b3504 | ||
|
|
8d4748c8df | ||
|
|
da723d3e11 | ||
|
|
0feeb7d0d4 | ||
|
|
9e53f36a74 | ||
|
|
7e7c08da47 | ||
|
|
2f6b89ef70 | ||
|
|
4e3024cb61 | ||
|
|
c427bf6a94 | ||
|
|
dae2422fd1 | ||
|
|
f98e3e6c26 | ||
|
|
fe99532f8b | ||
|
|
41a4968c90 | ||
|
|
1cdaabf2dd | ||
|
|
82d8253c19 | ||
|
|
c1717d6e12 | ||
|
|
f0d1c39b5b | ||
|
|
111aea3f0a | ||
|
|
37cfc912c1 | ||
|
|
8c2e228c74 | ||
|
|
8630fb02bb | ||
|
|
5052ab4e2b | ||
|
|
a44f739356 | ||
|
|
f44ecf3872 | ||
|
|
1c9e03f800 | ||
|
|
5d9ec83805 | ||
|
|
3a295c659b | ||
|
|
d253414783 | ||
|
|
8b1b503609 | ||
|
|
ff48bd6ec5 | ||
|
|
54b9c9bdb2 | ||
|
|
3dcdc582ea | ||
|
|
7c4171d414 | ||
|
|
1d839ff9df | ||
|
|
3403d07912 | ||
|
|
e8643787cf | ||
|
|
298b2a6033 | ||
|
|
c791428905 | ||
|
|
dc2fe63e42 | ||
|
|
7af88962ee | ||
|
|
3216d7683a | ||
|
|
e4094c8664 | ||
|
|
b49d65a276 | ||
|
|
824ce76cec | ||
|
|
2a18f97d12 | ||
|
|
8c4d29ee38 | ||
|
|
2c13f4fe72 | ||
|
|
94931040a8 | ||
|
|
b78a4cdc93 | ||
|
|
da09544bb0 | ||
|
|
ce17b6bd53 | ||
|
|
fe03bea191 | ||
|
|
0ed6347d47 | ||
|
|
3f86e97f70 | ||
|
|
69fa279e3c | ||
|
|
bbf4e05fde | ||
|
|
05d90517b0 | ||
|
|
5f5c1dc5a6 | ||
|
|
e0524644f8 | ||
|
|
81e2336ace | ||
|
|
25bf1a0169 | ||
|
|
c8ab67be27 | ||
|
|
6c34288ebf | ||
|
|
2ffbb9d6b7 | ||
|
|
dad608d5c0 | ||
|
|
04b939625b | ||
|
|
5dac485458 | ||
|
|
2c4ccd122e | ||
|
|
b90ae078b8 | ||
|
|
cc8761dbde | ||
|
|
08cc591884 | ||
|
|
1bc4d04f43 | ||
|
|
d4018192a9 | ||
|
|
19ddbfeca9 | ||
|
|
4fed6763fc | ||
|
|
73446a9cce | ||
|
|
dcf1ac0d1f | ||
|
|
364c58d13f | ||
|
|
8cfe11e4e2 | ||
|
|
40378a18f7 | ||
|
|
7fb5d8c973 | ||
|
|
6e373942e5 | ||
|
|
f0b982795c | ||
|
|
cbd422d56e | ||
|
|
03598bb5d6 | ||
|
|
983a53a643 |
No files matched your search
+26
-7
@@ -1,28 +1,47 @@
|
||||
*.o
|
||||
*.a
|
||||
*.lo
|
||||
*.la
|
||||
*.lai
|
||||
*.so
|
||||
*.so.*
|
||||
*~
|
||||
.*.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
|
||||
|
||||
# Autotools junk
|
||||
.libs
|
||||
.deps
|
||||
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
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
sudo: false
|
||||
|
||||
language: c
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- compiler: gcc
|
||||
env: COVERAGE="--disable-valgrind --enable-gcov"
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libonig-dev
|
||||
- valgrind
|
||||
|
||||
before_install:
|
||||
- rm lexer.h lexer.c parser.h parser.c
|
||||
|
||||
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:
|
||||
- autoreconf -i
|
||||
- ./configure
|
||||
YACC="usr/bin/bison -y"
|
||||
$COVERAGE
|
||||
|
||||
script:
|
||||
- make -j4 BISON_PKGDATADIR=$(pwd)/usr/share/bison
|
||||
- make check -j4
|
||||
|
||||
after_script:
|
||||
- |
|
||||
if [ -n "$COVERAGE" ]; then
|
||||
rm -rf .libs usr # don't care about coverage for libjq and bison
|
||||
coveralls -e lexer.c -e parser.c -e jv_dtoa.c --gcov-options '\-lp'
|
||||
fi
|
||||
|
||||
after_failure:
|
||||
- cat test-suite.log
|
||||
- cat tests/*.log
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
@@ -1,6 +1,73 @@
|
||||
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>
|
||||
David Tolnay <dtolnay@gmail.com>
|
||||
|
||||
Contributions by:
|
||||
Andrew Rodland <andrew@cleverdomain.org> - bug fixes
|
||||
Ankur <ankz.kothari@gmail.com> - bug fixes
|
||||
Anthony Shortland <anthony.shortland@me.com> - rpmbuild target
|
||||
Brendan Macmillan <melbourne.research@gmail.com> - bug fixes, load library from ~/.jq
|
||||
David R. MacIver <david@drmaciver.com> - bug fixes
|
||||
David Tolnay <dtolnay@gmail.com> - destructuring, build improvements
|
||||
Filippo Giunchedi <fgiunchedi@gmail.com> - bug fixes
|
||||
Filippo Valsorda <filippo.valsorda@gmail.com> - recursive object merge (`*`)
|
||||
Jack Pearkes <jackpearkes@gmail.com> - update tutorial
|
||||
Jingwen Owen Ou <jingweno@gmail.com> - jqplay.org and link to it
|
||||
Joe Littlejohn <joe.littlejohn@nokia.com> - bug fixes
|
||||
Juan Guerrero <juan.guerrero.lozano@gmail.com> - bug fixes
|
||||
Kenny Shen <kenny.shen@zalora.com> - doc fixes
|
||||
Lee Thompson <stagr.lee@gmail.com> - autoconf stuff
|
||||
Markus Lanthaler <mark_lanthaler@gmx.net> - doc fixes
|
||||
Michael Daines <michael@mdaines.com> - add sqrt; doc fixes
|
||||
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
|
||||
polyester <paul@cleanclothes.org> - automake version update
|
||||
Rémy Léone <remy.leone@gmail.com> - add .travis.yml
|
||||
Ryoichi KATO <ryo1kato@gmail.com> - doc fixes
|
||||
Santiago Lapresta <santiago.lapresta@gmail.com> - join, arrays, all, any, other filters
|
||||
pkoppstein <pkoppstein@gmail.com> - various builtins, improvements
|
||||
13ren <melbourne.research@gmail.com>
|
||||
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
|
||||
Assaf Gordon <assafgordon@gmail.com> - error handling
|
||||
cdnbacon <mike@busbud.com>
|
||||
Charles Merriam <charles.merriam@gmail.com>
|
||||
Colin von Heuring <colin@janrain.com>
|
||||
Damian Gryski <damian@gryski.com>
|
||||
David Haguenauer <ml@kurokatta.org>
|
||||
Doug Luce <doug@github.con.com> - build
|
||||
Eiichi Sato <sato.eiichi@gmail.com>
|
||||
Hanfei Shen <qqshfox@gmail.com>
|
||||
Ian Miell <ian.miell@gmail.com>
|
||||
i <isomorphisms@sdf.org>
|
||||
James Andariese <james.andariese@locationlabs.com> - Dockerfile
|
||||
jkleint <jkleint@gmail.com>
|
||||
Joel Purra <code+github@joelpurra.com>
|
||||
Kim De Mey <kim.demey@gmail.com> - build
|
||||
Kim Toms <kim.toms@bplglobal.net>
|
||||
LCD 47 <lcd047@gmail.com>
|
||||
Lee Thompson <thompson@dtosolutions.com> - rpm
|
||||
Marc Abramowitz <marc@marc-abramowitz.com>
|
||||
Marc Bruggmann <marcbr@spotify.com>
|
||||
Maxime Biais <maxime.biais@gmail.com> - build
|
||||
Mike Fletcher <john.m.fletcher@bankofamerica.com>
|
||||
Sebastian Freundt <freundt@ga-group.nl> - build
|
||||
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>
|
||||
@@ -25,7 +25,7 @@ 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
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
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 http://www.geocities.jp/kosako3/oniguruma/archive/onig-5.9.6.tar.gz && \
|
||||
sha512sum onig-5.9.6.tar.gz | grep 4a181ea6f0e1a018bbaf6c87e666dfffd1ef4b8f5dcead07fa0b6564a76174e7e01854173924668433ae74c455dbced6a0e1b43e9066f0499b4a57e855e1a2b2 && \
|
||||
tar zxvf onig-5.9.6.tar.gz && \
|
||||
(cd onig-5.9.6 && \
|
||||
./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 onig-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 onig-5.9.6 && \
|
||||
rm -rf /var/lib/apt/lists/* /var/lib/gems
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/jq"]
|
||||
+105
-30
@@ -1,48 +1,100 @@
|
||||
|
||||
### 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 = jq_parser.h builtin.h bytecode.h compile.h exec_stack.h \
|
||||
libm.h jv_alloc.h jv_dtoa.h jv_unicode.h locfile.h \
|
||||
opcode_list.h parser.y jv_utf8_tables.h lexer.l util.h linker.h
|
||||
|
||||
LIBJQ_SRC = locfile.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_file.c \
|
||||
jv_alloc.c jq_test.c util.c linker.c ${LIBJQ_INCS}
|
||||
|
||||
### C build options
|
||||
|
||||
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
|
||||
if MAINTAINER_MODE
|
||||
BUILT_SOURCES = lexer.h lexer.c parser.h parser.c version.h
|
||||
lexer.c: lexer.l
|
||||
flex -o lexer.c --header-file=lexer.h $<
|
||||
$(AM_V_LEX) flex -o lexer.c --header-file=lexer.h $<
|
||||
lexer.h: lexer.c
|
||||
else
|
||||
BUILT_SOURCES =
|
||||
.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 = -export-symbols-regex '^j[qv]_' -version-info 1:4:0
|
||||
|
||||
include_HEADERS = jv.h jq.h
|
||||
|
||||
### Running tests under Valgrind
|
||||
|
||||
if ENABLE_VALGRIND
|
||||
NO_VALGRIND =
|
||||
else
|
||||
NO_VALGRIND = 1
|
||||
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 = 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 version.h 2>/dev/null`" = "x$$ver" || touch .remake-version-h
|
||||
version.h: .remake-version-h
|
||||
$(AM_V_GEN) $(generate_ver); echo "$$ver" > $@
|
||||
main.c: version.h
|
||||
|
||||
bin_PROGRAMS = jq
|
||||
jq_SOURCES = ${JQ_SRC} main.c
|
||||
jq_SOURCES = main.c version.h
|
||||
jq_LDFLAGS = -static-libtool-libs
|
||||
jq_LDADD = libjq.la -lm
|
||||
|
||||
if ENABLE_ALL_STATIC
|
||||
jq_LDFLAGS += -all-static
|
||||
endif
|
||||
|
||||
### Tests (make check)
|
||||
|
||||
TESTS = tests/all.test
|
||||
TEST_LOG_COMPILER = ${srcdir}/tests/run
|
||||
TESTS = tests/mantest tests/jqtest tests/onigtest tests/shtest
|
||||
TESTS_ENVIRONMENT = NO_VALGRIND=$(NO_VALGRIND)
|
||||
|
||||
|
||||
### Building the manpage
|
||||
@@ -56,20 +108,23 @@ 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; }
|
||||
$(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; }
|
||||
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\
|
||||
$(AM_V_GEN) ( cd ${abs_srcdir}/docs; '$(BUNDLER)' exec rake manpage_default ) > $@ || { rm -f $@; false; }
|
||||
real_docs: jq.1 jq.1.prebuilt
|
||||
@if cmp jq.1 $(srcdir)/jq.1.default > /dev/null; then\
|
||||
rm -f jq.1; $(MAKE) $(AM_MAKEFLAGS) jq.1;\
|
||||
fi
|
||||
else
|
||||
jq.1: $(srcdir)/jq.1.default
|
||||
cp $^ $@
|
||||
jq.1: $(srcdir)/jq.1.prebuilt
|
||||
$(AM_V_GEN) 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
|
||||
@echo "A pre-built, possibly out-of-date manpage used." > /dev/stderr
|
||||
false
|
||||
endif
|
||||
|
||||
@@ -93,24 +148,33 @@ DOC_FILES = docs/content docs/public docs/templates docs/site.yml \
|
||||
# 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)
|
||||
EXTRA_DIST = $(man_MANS) $(TESTS) $(TEST_LOG_COMPILER) jq.spec \
|
||||
$(DOC_FILES) scripts/version parser.h parser.c lexer.h \
|
||||
lexer.c tests/onig.supp tests/torture/input0.json \
|
||||
tests/modules/.jq tests/modules/a.jq tests/modules/b/b.jq \
|
||||
tests/modules/c/c.jq tests/modules/c/d.jq \
|
||||
tests/modules/lib/jq/e/e.jq tests/modules/lib/jq/f.jq \
|
||||
tests/setup tests/jq.test tests/onig.test \
|
||||
tests/modules/data.json \
|
||||
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 \
|
||||
jq.1.prebuilt
|
||||
|
||||
|
||||
# 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 +183,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 *.gcno *.gcda *.gcov
|
||||
|
||||
clean-local: clean-local-docs clean-local-gcov
|
||||
rm -f version.h .remake-version-h
|
||||
|
||||
.PHONY: clean-local-docs clean-local-gcov
|
||||
+1646
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,88 @@
|
||||
|
||||
Release history
|
||||
|
||||
* jq version 1.0 was released on Sun Oct 21 2012
|
||||
* jq version 1.1 was released on Sun Oct 21 2012
|
||||
* jq version 1.2 was released on Thu Dec 20 2012
|
||||
* jq version 1.3 was released on Sun May 19 2013
|
||||
* jq version 1.4 was released on Mon Jun 9 2014
|
||||
|
||||
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
|
||||
|
||||
@@ -4,20 +4,61 @@ jq
|
||||
jq is a command-line JSON processor.
|
||||
|
||||
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
|
||||
|
||||
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 (note that jq's
|
||||
tests require regexp support to pass). To build, run:
|
||||
|
||||
autoreconf -i # if building from git
|
||||
./configure
|
||||
make
|
||||
sudo make install (optionally)
|
||||
make -j8
|
||||
make check
|
||||
|
||||
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:
|
||||
To build without bison or flex, add `--disable-maintainer-mode` to the
|
||||
./configure invocation:
|
||||
|
||||
autoreconf
|
||||
./configure --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 distclean
|
||||
scripts/crosscompile <name-of-build> <configure-options>
|
||||
|
||||
Use the --host= and --target= ./configure options to select a
|
||||
cross-compilation environment. See also the wiki.
|
||||
|
||||
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/).
|
||||
Vendored
+1255
File diff suppressed because it is too large.
Load diff
+20676
File diff suppressed because it is too large.
Load diff
+20676
File diff suppressed because it is too large.
Load diff
+20676
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,550 @@
|
||||
# This file was generated by Autom4te Thu Apr 10 10:06:43 UTC 2014.
|
||||
# It contains the lists of macros which have been traced.
|
||||
# It can be safely removed.
|
||||
|
||||
@request = (
|
||||
bless( [
|
||||
'0',
|
||||
1,
|
||||
[
|
||||
'/usr/share/autoconf'
|
||||
],
|
||||
[
|
||||
'/usr/share/autoconf/autoconf/autoconf.m4f',
|
||||
'-',
|
||||
'/usr/share/aclocal-1.14/internal/ac-config-macro-dirs.m4',
|
||||
'/usr/share/aclocal/argz.m4',
|
||||
'/usr/share/aclocal/libtool.m4',
|
||||
'/usr/share/aclocal/ltdl.m4',
|
||||
'/usr/share/aclocal/ltoptions.m4',
|
||||
'/usr/share/aclocal/ltsugar.m4',
|
||||
'/usr/share/aclocal/ltversion.m4',
|
||||
'/usr/share/aclocal/lt~obsolete.m4',
|
||||
'/usr/share/aclocal-1.14/amversion.m4',
|
||||
'/usr/share/aclocal-1.14/ar-lib.m4',
|
||||
'/usr/share/aclocal-1.14/auxdir.m4',
|
||||
'/usr/share/aclocal-1.14/cond.m4',
|
||||
'/usr/share/aclocal-1.14/depend.m4',
|
||||
'/usr/share/aclocal-1.14/depout.m4',
|
||||
'/usr/share/aclocal-1.14/init.m4',
|
||||
'/usr/share/aclocal-1.14/install-sh.m4',
|
||||
'/usr/share/aclocal-1.14/lead-dot.m4',
|
||||
'/usr/share/aclocal-1.14/maintainer.m4',
|
||||
'/usr/share/aclocal-1.14/make.m4',
|
||||
'/usr/share/aclocal-1.14/missing.m4',
|
||||
'/usr/share/aclocal-1.14/options.m4',
|
||||
'/usr/share/aclocal-1.14/prog-cc-c-o.m4',
|
||||
'/usr/share/aclocal-1.14/runlog.m4',
|
||||
'/usr/share/aclocal-1.14/sanity.m4',
|
||||
'/usr/share/aclocal-1.14/silent.m4',
|
||||
'/usr/share/aclocal-1.14/strip.m4',
|
||||
'/usr/share/aclocal-1.14/substnot.m4',
|
||||
'/usr/share/aclocal-1.14/tar.m4',
|
||||
'config/m4/check-math-func.m4',
|
||||
'config/m4/find-func-no-libs.m4',
|
||||
'config/m4/find-func-no-libs2.m4',
|
||||
'config/m4/find-func.m4',
|
||||
'config/m4/misc.m4',
|
||||
'configure.ac'
|
||||
],
|
||||
{
|
||||
'AM_MAINTAINER_MODE' => 1,
|
||||
'AC_LIBLTDL_CONVENIENCE' => 1,
|
||||
'AC_LTDL_ENABLE_INSTALL' => 1,
|
||||
'LT_PATH_NM' => 1,
|
||||
'AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH' => 1,
|
||||
'_LT_PROG_ECHO_BACKSLASH' => 1,
|
||||
'LT_SYS_DLOPEN_SELF' => 1,
|
||||
'_LTDL_SETUP' => 1,
|
||||
'LT_SYS_DLSEARCH_PATH' => 1,
|
||||
'AC_LIBTOOL_F77' => 1,
|
||||
'm4_pattern_forbid' => 1,
|
||||
'm4_pattern_allow' => 1,
|
||||
'LT_SYS_MODULE_PATH' => 1,
|
||||
'_LT_LIBOBJ' => 1,
|
||||
'AC_CHECK_LIBM' => 1,
|
||||
'_LT_PATH_TOOL_PREFIX' => 1,
|
||||
'AC_LIBTOOL_LANG_RC_CONFIG' => 1,
|
||||
'AC_FIND_FUNC' => 1,
|
||||
'LT_SYS_DLOPEN_DEPLIBS' => 1,
|
||||
'AC_LIB_LTDL' => 1,
|
||||
'gl_FUNC_ARGZ' => 1,
|
||||
'LT_LIB_DLLOAD' => 1,
|
||||
'AM_ENABLE_SHARED' => 1,
|
||||
'AC_PROG_LD_RELOAD_FLAG' => 1,
|
||||
'AC_LIBTOOL_OBJDIR' => 1,
|
||||
'_LT_PROG_LTMAIN' => 1,
|
||||
'LTSUGAR_VERSION' => 1,
|
||||
'AC_LIBTOOL_SYS_OLD_ARCHIVE' => 1,
|
||||
'AC_LIBTOOL_RC' => 1,
|
||||
'LT_LANG' => 1,
|
||||
'_AM_PROG_CC_C_O' => 1,
|
||||
'LTDL_INIT' => 1,
|
||||
'_LT_COMPILER_BOILERPLATE' => 1,
|
||||
'AM_PROG_INSTALL_STRIP' => 1,
|
||||
'LTOPTIONS_VERSION' => 1,
|
||||
'AC_LIBTOOL_DLOPEN' => 1,
|
||||
'_LT_AC_PROG_ECHO_BACKSLASH' => 1,
|
||||
'_LT_COMPILER_OPTION' => 1,
|
||||
'_AM_SET_OPTION' => 1,
|
||||
'_LT_AC_LANG_GCJ_CONFIG' => 1,
|
||||
'LT_CMD_MAX_LEN' => 1,
|
||||
'AM_SET_DEPDIR' => 1,
|
||||
'AC_PROG_LD_GNU' => 1,
|
||||
'AC_PATH_MAGIC' => 1,
|
||||
'_LT_CC_BASENAME' => 1,
|
||||
'AM_MISSING_PROG' => 1,
|
||||
'LT_OUTPUT' => 1,
|
||||
'AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE' => 1,
|
||||
'AC_PATH_TOOL_PREFIX' => 1,
|
||||
'LT_INIT' => 1,
|
||||
'_LT_AC_LANG_F77_CONFIG' => 1,
|
||||
'AC_WITH_LTDL' => 1,
|
||||
'AC_LIBTOOL_POSTDEP_PREDEP' => 1,
|
||||
'AC_LIBTOOL_LANG_C_CONFIG' => 1,
|
||||
'AC_LIBTOOL_PROG_CC_C_O' => 1,
|
||||
'_LT_AC_TRY_DLOPEN_SELF' => 1,
|
||||
'LT_LIB_M' => 1,
|
||||
'LT_SYS_MODULE_EXT' => 1,
|
||||
'AC_LTDL_DLSYM_USCORE' => 1,
|
||||
'AC_DEFUN' => 1,
|
||||
'_AC_PROG_LIBTOOL' => 1,
|
||||
'_LT_PROG_F77' => 1,
|
||||
'AC_LIBTOOL_SYS_DYNAMIC_LINKER' => 1,
|
||||
'AM_SILENT_RULES' => 1,
|
||||
'AC_LIBTOOL_LANG_CXX_CONFIG' => 1,
|
||||
'AM_DEP_TRACK' => 1,
|
||||
'AM_PROG_LD' => 1,
|
||||
'AC_LIBTOOL_SYS_LIB_STRIP' => 1,
|
||||
'AC_LTDL_SHLIBPATH' => 1,
|
||||
'AM_RUN_LOG' => 1,
|
||||
'AC_DISABLE_STATIC' => 1,
|
||||
'AU_DEFUN' => 1,
|
||||
'include' => 1,
|
||||
'_LT_AC_SYS_COMPILER' => 1,
|
||||
'AC_LIBTOOL_PROG_COMPILER_NO_RTTI' => 1,
|
||||
'LT_AC_PROG_GCJ' => 1,
|
||||
'AC_LIBTOOL_COMPILER_OPTION' => 1,
|
||||
'AC_LTDL_SYMBOL_USCORE' => 1,
|
||||
'AC_LIBTOOL_PICMODE' => 1,
|
||||
'LT_AC_PROG_SED' => 1,
|
||||
'_LT_AC_FILE_LTDLL_C' => 1,
|
||||
'LT_AC_PROG_EGREP' => 1,
|
||||
'AC_PROG_LD' => 1,
|
||||
'_AM_PROG_TAR' => 1,
|
||||
'AM_SET_CURRENT_AUTOMAKE_VERSION' => 1,
|
||||
'_m4_warn' => 1,
|
||||
'AC_LIBTOOL_SYS_MAX_CMD_LEN' => 1,
|
||||
'_LT_AC_CHECK_DLFCN' => 1,
|
||||
'LT_SUPPORTED_TAG' => 1,
|
||||
'_AC_AM_CONFIG_HEADER_HOOK' => 1,
|
||||
'AC_LIBTOOL_CONFIG' => 1,
|
||||
'_LT_AC_LANG_F77' => 1,
|
||||
'LTDL_INSTALLABLE' => 1,
|
||||
'AC_CONFIG_MACRO_DIR_TRACE' => 1,
|
||||
'AC_LIBTOOL_DLOPEN_SELF' => 1,
|
||||
'_AM_OUTPUT_DEPENDENCY_COMMANDS' => 1,
|
||||
'AC_LTDL_SYS_DLOPEN_DEPLIBS' => 1,
|
||||
'_LT_LINKER_OPTION' => 1,
|
||||
'LTOBSOLETE_VERSION' => 1,
|
||||
'AC_LTDL_SYSSEARCHPATH' => 1,
|
||||
'AC_ENABLE_SHARED' => 1,
|
||||
'AM_AUX_DIR_EXPAND' => 1,
|
||||
'_LT_AC_TAGVAR' => 1,
|
||||
'LT_AC_PROG_RC' => 1,
|
||||
'LT_FUNC_DLSYM_USCORE' => 1,
|
||||
'LT_SYS_SYMBOL_USCORE' => 1,
|
||||
'AC_LIBTOOL_PROG_COMPILER_PIC' => 1,
|
||||
'LTDL_CONVENIENCE' => 1,
|
||||
'AC_PROG_EGREP' => 1,
|
||||
'AM_PROG_AR' => 1,
|
||||
'AC_ENABLE_FAST_INSTALL' => 1,
|
||||
'AX_PROG_BISON_VERSION' => 1,
|
||||
'_LT_WITH_SYSROOT' => 1,
|
||||
'AC_FIND_FUNC_NO_LIBS2' => 1,
|
||||
'AM_INIT_AUTOMAKE' => 1,
|
||||
'AC_LTDL_OBJDIR' => 1,
|
||||
'AC_PROG_LIBTOOL' => 1,
|
||||
'_LT_AC_LOCK' => 1,
|
||||
'AC_LIBTOOL_PROG_LD_SHLIBS' => 1,
|
||||
'AC_LTDL_SHLIBEXT' => 1,
|
||||
'upcase' => 1,
|
||||
'LT_PROG_GCJ' => 1,
|
||||
'AX_COMPARE_VERSION' => 1,
|
||||
'AC_LTDL_DLLIB' => 1,
|
||||
'_LT_AC_LANG_RC_CONFIG' => 1,
|
||||
'AC_CONFIG_MACRO_DIR' => 1,
|
||||
'_LT_PROG_CXX' => 1,
|
||||
'AM_PROG_CC_C_O' => 1,
|
||||
'AM_PROG_NM' => 1,
|
||||
'LT_PATH_LD' => 1,
|
||||
'_AM_IF_OPTION' => 1,
|
||||
'_AM_MANGLE_OPTION' => 1,
|
||||
'AM_DISABLE_SHARED' => 1,
|
||||
'm4_include' => 1,
|
||||
'_AM_SET_OPTIONS' => 1,
|
||||
'_LT_AC_SYS_LIBPATH_AIX' => 1,
|
||||
'AM_ENABLE_STATIC' => 1,
|
||||
'AC_DEFUN_ONCE' => 1,
|
||||
'_AM_AUTOCONF_VERSION' => 1,
|
||||
'AC_DEPLIBS_CHECK_METHOD' => 1,
|
||||
'AM_PROG_LIBTOOL' => 1,
|
||||
'AC_DISABLE_SHARED' => 1,
|
||||
'AM_SUBST_NOTMAKE' => 1,
|
||||
'_LT_AC_PROG_CXXCPP' => 1,
|
||||
'AC_LTDL_PREOPEN' => 1,
|
||||
'_LT_LINKER_BOILERPLATE' => 1,
|
||||
'AC_LIBTOOL_SETUP' => 1,
|
||||
'AC_CHECK_MATH_FUNC' => 1,
|
||||
'AM_SANITY_CHECK' => 1,
|
||||
'_LT_AC_LANG_CXX' => 1,
|
||||
'_LT_AC_TAGCONFIG' => 1,
|
||||
'LT_WITH_LTDL' => 1,
|
||||
'LT_CONFIG_LTDL_DIR' => 1,
|
||||
'_LT_REQUIRED_DARWIN_CHECKS' => 1,
|
||||
'AC_LIBTOOL_FC' => 1,
|
||||
'AC_LIBTOOL_SYS_HARD_LINK_LOCKS' => 1,
|
||||
'AM_OUTPUT_DEPENDENCY_COMMANDS' => 1,
|
||||
'AM_MISSING_HAS_RUN' => 1,
|
||||
'AM_PROG_INSTALL_SH' => 1,
|
||||
'AC_LIBTOOL_WIN32_DLL' => 1,
|
||||
'AC_ENABLE_STATIC' => 1,
|
||||
'_LT_PREPARE_SED_QUOTE_VARS' => 1,
|
||||
'_AM_SUBST_NOTMAKE' => 1,
|
||||
'_LT_AC_SHELL_INIT' => 1,
|
||||
'AM_SET_LEADING_DOT' => 1,
|
||||
'LTVERSION_VERSION' => 1,
|
||||
'AC_LIBLTDL_INSTALLABLE' => 1,
|
||||
'LT_PROG_RC' => 1,
|
||||
'_AM_DEPENDENCIES' => 1,
|
||||
'LT_PROG_GO' => 1,
|
||||
'AC_LIBTOOL_GCJ' => 1,
|
||||
'gl_PREREQ_ARGZ' => 1,
|
||||
'_AM_CONFIG_MACRO_DIRS' => 1,
|
||||
'AC_FIND_FUNC_NO_LIBS' => 1,
|
||||
'AC_LIBTOOL_CXX' => 1,
|
||||
'AM_DISABLE_STATIC' => 1,
|
||||
'AC_LIBTOOL_LANG_F77_CONFIG' => 1,
|
||||
'AM_AUTOMAKE_VERSION' => 1,
|
||||
'AC_LIBTOOL_LINKER_OPTION' => 1,
|
||||
'AM_CONDITIONAL' => 1,
|
||||
'_LT_AC_LANG_GCJ' => 1,
|
||||
'AC_PROG_NM' => 1,
|
||||
'AC_DISABLE_FAST_INSTALL' => 1,
|
||||
'_LT_AC_LANG_CXX_CONFIG' => 1,
|
||||
'_LT_AC_LANG_C_CONFIG' => 1,
|
||||
'AM_MAKE_INCLUDE' => 1,
|
||||
'_LT_PROG_FC' => 1,
|
||||
'AC_LIBTOOL_LANG_GCJ_CONFIG' => 1
|
||||
}
|
||||
], 'Autom4te::Request' ),
|
||||
bless( [
|
||||
'1',
|
||||
1,
|
||||
[
|
||||
'/usr/share/autoconf'
|
||||
],
|
||||
[
|
||||
'/usr/share/autoconf/autoconf/autoconf.m4f',
|
||||
'aclocal.m4',
|
||||
'configure.ac'
|
||||
],
|
||||
{
|
||||
'AC_FC_PP_DEFINE' => 1,
|
||||
'AC_INIT' => 1,
|
||||
'AM_XGETTEXT_OPTION' => 1,
|
||||
'AC_CONFIG_LIBOBJ_DIR' => 1,
|
||||
'AM_PROG_CC_C_O' => 1,
|
||||
'include' => 1,
|
||||
'AC_LIBSOURCE' => 1,
|
||||
'AM_PROG_FC_C_O' => 1,
|
||||
'AM_GNU_GETTEXT' => 1,
|
||||
'AC_CANONICAL_HOST' => 1,
|
||||
'AM_POT_TOOLS' => 1,
|
||||
'AM_NLS' => 1,
|
||||
'_AM_MAKEFILE_INCLUDE' => 1,
|
||||
'AM_CONDITIONAL' => 1,
|
||||
'AH_OUTPUT' => 1,
|
||||
'_AM_COND_ELSE' => 1,
|
||||
'_AM_COND_IF' => 1,
|
||||
'AM_AUTOMAKE_VERSION' => 1,
|
||||
'AM_SILENT_RULES' => 1,
|
||||
'AM_INIT_AUTOMAKE' => 1,
|
||||
'AC_PROG_LIBTOOL' => 1,
|
||||
'AM_PROG_MOC' => 1,
|
||||
'AM_PROG_CXX_C_O' => 1,
|
||||
'AC_CONFIG_LINKS' => 1,
|
||||
'm4_sinclude' => 1,
|
||||
'AC_CONFIG_SUBDIRS' => 1,
|
||||
'AM_PROG_AR' => 1,
|
||||
'AM_GNU_GETTEXT_INTL_SUBDIR' => 1,
|
||||
'AC_CONFIG_HEADERS' => 1,
|
||||
'AC_SUBST_TRACE' => 1,
|
||||
'_AM_SUBST_NOTMAKE' => 1,
|
||||
'AM_MAKEFILE_INCLUDE' => 1,
|
||||
'AM_EXTRA_RECURSIVE_TARGETS' => 1,
|
||||
'AC_CANONICAL_SYSTEM' => 1,
|
||||
'AM_PROG_MKDIR_P' => 1,
|
||||
'AC_SUBST' => 1,
|
||||
'AM_PATH_GUILE' => 1,
|
||||
'LT_INIT' => 1,
|
||||
'sinclude' => 1,
|
||||
'AM_PROG_F77_C_O' => 1,
|
||||
'LT_CONFIG_LTDL_DIR' => 1,
|
||||
'_LT_AC_TAGCONFIG' => 1,
|
||||
'AC_DEFINE_TRACE_LITERAL' => 1,
|
||||
'm4_pattern_forbid' => 1,
|
||||
'm4_pattern_allow' => 1,
|
||||
'AC_FC_PP_SRCEXT' => 1,
|
||||
'AC_FC_FREEFORM' => 1,
|
||||
'AC_CANONICAL_BUILD' => 1,
|
||||
'LT_SUPPORTED_TAG' => 1,
|
||||
'AM_ENABLE_MULTILIB' => 1,
|
||||
'_m4_warn' => 1,
|
||||
'AC_CONFIG_FILES' => 1,
|
||||
'AC_CONFIG_AUX_DIR' => 1,
|
||||
'AC_FC_SRCEXT' => 1,
|
||||
'AC_CANONICAL_TARGET' => 1,
|
||||
'_AM_COND_ENDIF' => 1,
|
||||
'm4_include' => 1,
|
||||
'AM_MAINTAINER_MODE' => 1,
|
||||
'AC_REQUIRE_AUX_FILE' => 1
|
||||
}
|
||||
], 'Autom4te::Request' ),
|
||||
bless( [
|
||||
'2',
|
||||
1,
|
||||
[
|
||||
'/usr/share/autoconf'
|
||||
],
|
||||
[
|
||||
'/usr/share/autoconf/autoconf/autoconf.m4f',
|
||||
'-',
|
||||
'/usr/share/aclocal-1.14/internal/ac-config-macro-dirs.m4',
|
||||
'/usr/share/aclocal/argz.m4',
|
||||
'/usr/share/aclocal/ltdl.m4',
|
||||
'/usr/share/aclocal-1.14/amversion.m4',
|
||||
'/usr/share/aclocal-1.14/ar-lib.m4',
|
||||
'/usr/share/aclocal-1.14/auxdir.m4',
|
||||
'/usr/share/aclocal-1.14/cond.m4',
|
||||
'/usr/share/aclocal-1.14/depend.m4',
|
||||
'/usr/share/aclocal-1.14/depout.m4',
|
||||
'/usr/share/aclocal-1.14/init.m4',
|
||||
'/usr/share/aclocal-1.14/install-sh.m4',
|
||||
'/usr/share/aclocal-1.14/lead-dot.m4',
|
||||
'/usr/share/aclocal-1.14/maintainer.m4',
|
||||
'/usr/share/aclocal-1.14/make.m4',
|
||||
'/usr/share/aclocal-1.14/missing.m4',
|
||||
'/usr/share/aclocal-1.14/options.m4',
|
||||
'/usr/share/aclocal-1.14/prog-cc-c-o.m4',
|
||||
'/usr/share/aclocal-1.14/runlog.m4',
|
||||
'/usr/share/aclocal-1.14/sanity.m4',
|
||||
'/usr/share/aclocal-1.14/silent.m4',
|
||||
'/usr/share/aclocal-1.14/strip.m4',
|
||||
'/usr/share/aclocal-1.14/substnot.m4',
|
||||
'/usr/share/aclocal-1.14/tar.m4',
|
||||
'config/m4/check-math-func.m4',
|
||||
'config/m4/find-func-no-libs.m4',
|
||||
'config/m4/find-func-no-libs2.m4',
|
||||
'config/m4/find-func.m4',
|
||||
'config/m4/libtool.m4',
|
||||
'config/m4/ltoptions.m4',
|
||||
'config/m4/ltsugar.m4',
|
||||
'config/m4/ltversion.m4',
|
||||
'config/m4/lt~obsolete.m4',
|
||||
'config/m4/misc.m4',
|
||||
'configure.ac'
|
||||
],
|
||||
{
|
||||
'AC_LIBTOOL_DLOPEN_SELF' => 1,
|
||||
'_AM_OUTPUT_DEPENDENCY_COMMANDS' => 1,
|
||||
'AC_LTDL_SYS_DLOPEN_DEPLIBS' => 1,
|
||||
'_LT_LINKER_OPTION' => 1,
|
||||
'AC_ENABLE_SHARED' => 1,
|
||||
'AC_LTDL_SYSSEARCHPATH' => 1,
|
||||
'LTOBSOLETE_VERSION' => 1,
|
||||
'_LT_AC_TAGVAR' => 1,
|
||||
'AM_AUX_DIR_EXPAND' => 1,
|
||||
'LT_AC_PROG_RC' => 1,
|
||||
'AC_LIBTOOL_CONFIG' => 1,
|
||||
'_LT_AC_LANG_F77' => 1,
|
||||
'AC_CONFIG_MACRO_DIR_TRACE' => 1,
|
||||
'LTDL_INSTALLABLE' => 1,
|
||||
'_AM_PROG_TAR' => 1,
|
||||
'AM_SET_CURRENT_AUTOMAKE_VERSION' => 1,
|
||||
'_m4_warn' => 1,
|
||||
'AC_LIBTOOL_SYS_MAX_CMD_LEN' => 1,
|
||||
'_LT_AC_CHECK_DLFCN' => 1,
|
||||
'LT_SUPPORTED_TAG' => 1,
|
||||
'_AC_AM_CONFIG_HEADER_HOOK' => 1,
|
||||
'_LT_AC_FILE_LTDLL_C' => 1,
|
||||
'LT_AC_PROG_EGREP' => 1,
|
||||
'AC_PROG_LD' => 1,
|
||||
'_LT_AC_LANG_RC_CONFIG' => 1,
|
||||
'AC_LTDL_DLLIB' => 1,
|
||||
'AC_CONFIG_MACRO_DIR' => 1,
|
||||
'_LT_PROG_CXX' => 1,
|
||||
'AM_PROG_CC_C_O' => 1,
|
||||
'AM_PROG_NM' => 1,
|
||||
'LT_PATH_LD' => 1,
|
||||
'AM_INIT_AUTOMAKE' => 1,
|
||||
'AC_LTDL_OBJDIR' => 1,
|
||||
'AC_PROG_LIBTOOL' => 1,
|
||||
'_LT_AC_LOCK' => 1,
|
||||
'AC_LIBTOOL_PROG_LD_SHLIBS' => 1,
|
||||
'AC_LTDL_SHLIBEXT' => 1,
|
||||
'LT_PROG_GCJ' => 1,
|
||||
'upcase' => 1,
|
||||
'AX_COMPARE_VERSION' => 1,
|
||||
'AC_LIBTOOL_PROG_COMPILER_PIC' => 1,
|
||||
'LTDL_CONVENIENCE' => 1,
|
||||
'AC_ENABLE_FAST_INSTALL' => 1,
|
||||
'AM_PROG_AR' => 1,
|
||||
'AC_PROG_EGREP' => 1,
|
||||
'AX_PROG_BISON_VERSION' => 1,
|
||||
'_LT_WITH_SYSROOT' => 1,
|
||||
'AC_FIND_FUNC_NO_LIBS2' => 1,
|
||||
'LT_FUNC_DLSYM_USCORE' => 1,
|
||||
'LT_SYS_SYMBOL_USCORE' => 1,
|
||||
'_LT_AC_TAGCONFIG' => 1,
|
||||
'LT_WITH_LTDL' => 1,
|
||||
'_LT_REQUIRED_DARWIN_CHECKS' => 1,
|
||||
'LT_CONFIG_LTDL_DIR' => 1,
|
||||
'AC_LIBTOOL_FC' => 1,
|
||||
'AM_SUBST_NOTMAKE' => 1,
|
||||
'_LT_AC_PROG_CXXCPP' => 1,
|
||||
'AC_LTDL_PREOPEN' => 1,
|
||||
'AC_CHECK_MATH_FUNC' => 1,
|
||||
'_LT_LINKER_BOILERPLATE' => 1,
|
||||
'AC_LIBTOOL_SETUP' => 1,
|
||||
'AM_SANITY_CHECK' => 1,
|
||||
'_LT_AC_LANG_CXX' => 1,
|
||||
'AC_DEFUN_ONCE' => 1,
|
||||
'AM_ENABLE_STATIC' => 1,
|
||||
'_AM_AUTOCONF_VERSION' => 1,
|
||||
'AM_PROG_LIBTOOL' => 1,
|
||||
'AC_DEPLIBS_CHECK_METHOD' => 1,
|
||||
'AC_DISABLE_SHARED' => 1,
|
||||
'_AM_IF_OPTION' => 1,
|
||||
'_AM_MANGLE_OPTION' => 1,
|
||||
'AM_DISABLE_SHARED' => 1,
|
||||
'_AM_SET_OPTIONS' => 1,
|
||||
'm4_include' => 1,
|
||||
'_LT_AC_SYS_LIBPATH_AIX' => 1,
|
||||
'_LT_AC_LANG_GCJ' => 1,
|
||||
'AC_PROG_NM' => 1,
|
||||
'AC_DISABLE_FAST_INSTALL' => 1,
|
||||
'_LT_AC_LANG_CXX_CONFIG' => 1,
|
||||
'_LT_PROG_FC' => 1,
|
||||
'AM_MAKE_INCLUDE' => 1,
|
||||
'_LT_AC_LANG_C_CONFIG' => 1,
|
||||
'AC_LIBTOOL_LANG_GCJ_CONFIG' => 1,
|
||||
'gl_PREREQ_ARGZ' => 1,
|
||||
'_AM_CONFIG_MACRO_DIRS' => 1,
|
||||
'AC_FIND_FUNC_NO_LIBS' => 1,
|
||||
'AM_DISABLE_STATIC' => 1,
|
||||
'AC_LIBTOOL_CXX' => 1,
|
||||
'AC_LIBTOOL_LANG_F77_CONFIG' => 1,
|
||||
'AM_AUTOMAKE_VERSION' => 1,
|
||||
'AC_LIBTOOL_LINKER_OPTION' => 1,
|
||||
'AM_CONDITIONAL' => 1,
|
||||
'_LT_AC_SHELL_INIT' => 1,
|
||||
'AM_SET_LEADING_DOT' => 1,
|
||||
'LTVERSION_VERSION' => 1,
|
||||
'LT_PROG_RC' => 1,
|
||||
'_AM_DEPENDENCIES' => 1,
|
||||
'AC_LIBLTDL_INSTALLABLE' => 1,
|
||||
'LT_PROG_GO' => 1,
|
||||
'AC_LIBTOOL_GCJ' => 1,
|
||||
'AM_MISSING_HAS_RUN' => 1,
|
||||
'AC_LIBTOOL_SYS_HARD_LINK_LOCKS' => 1,
|
||||
'AM_OUTPUT_DEPENDENCY_COMMANDS' => 1,
|
||||
'AM_PROG_INSTALL_SH' => 1,
|
||||
'AC_LIBTOOL_WIN32_DLL' => 1,
|
||||
'_LT_PREPARE_SED_QUOTE_VARS' => 1,
|
||||
'_AM_SUBST_NOTMAKE' => 1,
|
||||
'AC_ENABLE_STATIC' => 1,
|
||||
'LT_SYS_MODULE_PATH' => 1,
|
||||
'_LT_PATH_TOOL_PREFIX' => 1,
|
||||
'AC_CHECK_LIBM' => 1,
|
||||
'_LT_LIBOBJ' => 1,
|
||||
'AC_LIBTOOL_LANG_RC_CONFIG' => 1,
|
||||
'LT_SYS_DLSEARCH_PATH' => 1,
|
||||
'AC_LIBTOOL_F77' => 1,
|
||||
'm4_pattern_forbid' => 1,
|
||||
'm4_pattern_allow' => 1,
|
||||
'_LT_PROG_ECHO_BACKSLASH' => 1,
|
||||
'AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH' => 1,
|
||||
'LT_SYS_DLOPEN_SELF' => 1,
|
||||
'_LTDL_SETUP' => 1,
|
||||
'AC_LIBLTDL_CONVENIENCE' => 1,
|
||||
'AM_MAINTAINER_MODE' => 1,
|
||||
'AC_LTDL_ENABLE_INSTALL' => 1,
|
||||
'LT_PATH_NM' => 1,
|
||||
'LT_LANG' => 1,
|
||||
'_AM_PROG_CC_C_O' => 1,
|
||||
'LTDL_INIT' => 1,
|
||||
'_LT_COMPILER_BOILERPLATE' => 1,
|
||||
'AM_ENABLE_SHARED' => 1,
|
||||
'AC_LIBTOOL_OBJDIR' => 1,
|
||||
'AC_PROG_LD_RELOAD_FLAG' => 1,
|
||||
'LTSUGAR_VERSION' => 1,
|
||||
'_LT_PROG_LTMAIN' => 1,
|
||||
'AC_LIBTOOL_RC' => 1,
|
||||
'AC_LIBTOOL_SYS_OLD_ARCHIVE' => 1,
|
||||
'gl_FUNC_ARGZ' => 1,
|
||||
'LT_LIB_DLLOAD' => 1,
|
||||
'AC_FIND_FUNC' => 1,
|
||||
'LT_SYS_DLOPEN_DEPLIBS' => 1,
|
||||
'AC_LIB_LTDL' => 1,
|
||||
'AM_MISSING_PROG' => 1,
|
||||
'LT_OUTPUT' => 1,
|
||||
'AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE' => 1,
|
||||
'AC_PATH_TOOL_PREFIX' => 1,
|
||||
'LT_INIT' => 1,
|
||||
'_LT_CC_BASENAME' => 1,
|
||||
'_AM_SET_OPTION' => 1,
|
||||
'_LT_AC_LANG_GCJ_CONFIG' => 1,
|
||||
'LT_CMD_MAX_LEN' => 1,
|
||||
'AM_SET_DEPDIR' => 1,
|
||||
'AC_PATH_MAGIC' => 1,
|
||||
'AC_PROG_LD_GNU' => 1,
|
||||
'AM_PROG_INSTALL_STRIP' => 1,
|
||||
'LTOPTIONS_VERSION' => 1,
|
||||
'_LT_AC_PROG_ECHO_BACKSLASH' => 1,
|
||||
'AC_LIBTOOL_DLOPEN' => 1,
|
||||
'_LT_COMPILER_OPTION' => 1,
|
||||
'AC_DISABLE_STATIC' => 1,
|
||||
'AU_DEFUN' => 1,
|
||||
'include' => 1,
|
||||
'_LT_AC_SYS_COMPILER' => 1,
|
||||
'LT_AC_PROG_GCJ' => 1,
|
||||
'AC_LIBTOOL_PROG_COMPILER_NO_RTTI' => 1,
|
||||
'AC_LIBTOOL_COMPILER_OPTION' => 1,
|
||||
'AC_LIBTOOL_PICMODE' => 1,
|
||||
'AC_LTDL_SYMBOL_USCORE' => 1,
|
||||
'LT_AC_PROG_SED' => 1,
|
||||
'_LT_PROG_F77' => 1,
|
||||
'_AC_PROG_LIBTOOL' => 1,
|
||||
'AC_LIBTOOL_SYS_DYNAMIC_LINKER' => 1,
|
||||
'AM_SILENT_RULES' => 1,
|
||||
'AC_LIBTOOL_LANG_CXX_CONFIG' => 1,
|
||||
'AC_LIBTOOL_SYS_LIB_STRIP' => 1,
|
||||
'AM_PROG_LD' => 1,
|
||||
'AM_DEP_TRACK' => 1,
|
||||
'AC_LTDL_SHLIBPATH' => 1,
|
||||
'AM_RUN_LOG' => 1,
|
||||
'AC_LIBTOOL_PROG_CC_C_O' => 1,
|
||||
'AC_LIBTOOL_LANG_C_CONFIG' => 1,
|
||||
'_LT_AC_TRY_DLOPEN_SELF' => 1,
|
||||
'LT_SYS_MODULE_EXT' => 1,
|
||||
'LT_LIB_M' => 1,
|
||||
'AC_LTDL_DLSYM_USCORE' => 1,
|
||||
'AC_DEFUN' => 1,
|
||||
'_LT_AC_LANG_F77_CONFIG' => 1,
|
||||
'AC_WITH_LTDL' => 1,
|
||||
'AC_LIBTOOL_POSTDEP_PREDEP' => 1
|
||||
}
|
||||
], 'Autom4te::Request' )
|
||||
);
|
||||
|
||||
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
@@ -1,21 +1,10 @@
|
||||
#ifndef BUILTIN_H
|
||||
#define BUILTIN_H
|
||||
|
||||
#include "jq.h"
|
||||
#include "bytecode.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[]);
|
||||
|
||||
int builtins_bind(jq_state *, block*);
|
||||
|
||||
#endif
|
||||
+58
-25
@@ -3,17 +3,64 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "bytecode.h"
|
||||
#include "opcode.h"
|
||||
#include "jv_alloc.h"
|
||||
|
||||
static int bytecode_operation_length(uint16_t* codeptr) {
|
||||
// flags, length
|
||||
#define NONE 0, 1
|
||||
#define CONSTANT OP_HAS_CONSTANT, 2
|
||||
#define VARIABLE (OP_HAS_VARIABLE | OP_HAS_BINDING), 3
|
||||
#define GLOBAL (OP_HAS_CONSTANT | OP_HAS_VARIABLE | OP_HAS_BINDING | OP_IS_CALL_PSEUDO), 4
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int bytecode_operation_length(uint16_t* codeptr) {
|
||||
int length = opcode_describe(*codeptr)->length;
|
||||
if (*codeptr == CALL_JQ) {
|
||||
if (*codeptr == CALL_JQ || *codeptr == TAIL_CALL_JQ) {
|
||||
length += codeptr[1] * 2;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
static 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);
|
||||
}
|
||||
}
|
||||
|
||||
static void symbol_table_free(struct symbol_table* syms) {
|
||||
jv_mem_free(syms->cfunctions);
|
||||
jv_free(syms->cfunc_names);
|
||||
jv_mem_free(syms);
|
||||
}
|
||||
|
||||
void dump_disassembly(int indent, struct bytecode* bc) {
|
||||
if (bc->nclosures > 0) {
|
||||
printf("%*s[params: ", indent, "");
|
||||
@@ -37,16 +84,6 @@ void dump_disassembly(int indent, struct bytecode* bc) {
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static struct bytecode* getlevel(struct bytecode* bc, int level) {
|
||||
while (level > 0) {
|
||||
bc = bc->parent;
|
||||
@@ -62,17 +99,17 @@ void dump_operation(struct bytecode* bc, uint16_t* codeptr) {
|
||||
printf("%s", op->name);
|
||||
if (op->length > 1) {
|
||||
uint16_t imm = bc->code[pc++];
|
||||
if (op->op == CALL_JQ) {
|
||||
if (op->op == CALL_JQ || op->op == TAIL_CALL_JQ) {
|
||||
for (int i=0; i<imm+1; i++) {
|
||||
uint16_t level = bc->code[pc++];
|
||||
uint16_t idx = bc->code[pc++];
|
||||
jv name;
|
||||
if (idx & ARG_NEWCLOSURE) {
|
||||
idx &= ~ARG_NEWCLOSURE;
|
||||
name = jv_object_get(jv_copy(getlevel(bc,level)->subfunctions[idx]->debuginfo),
|
||||
name = jv_object_get(jv_copy(getlevel(bc,level)->subfunctions[idx]->debuginfo),
|
||||
jv_string("name"));
|
||||
} else {
|
||||
name = jv_array_get(jv_object_get(jv_copy(getlevel(bc,level)->debuginfo),
|
||||
name = jv_array_get(jv_object_get(jv_copy(getlevel(bc,level)->debuginfo),
|
||||
jv_string("params")), idx);
|
||||
}
|
||||
printf(" %s:%d",
|
||||
@@ -96,8 +133,8 @@ void dump_operation(struct bytecode* bc, uint16_t* codeptr) {
|
||||
} else if (op->flags & OP_HAS_VARIABLE) {
|
||||
uint16_t v = bc->code[pc++];
|
||||
jv name = jv_array_get(jv_object_get(jv_copy(getlevel(bc,imm)->debuginfo), jv_string("locals")), v);
|
||||
printf(" $%s:%d",
|
||||
jv_string_value(name),
|
||||
printf(" $%s:%d",
|
||||
jv_string_value(name),
|
||||
v);
|
||||
jv_free(name);
|
||||
if (imm) {
|
||||
@@ -106,16 +143,12 @@ void dump_operation(struct bytecode* bc, uint16_t* codeptr) {
|
||||
} else {
|
||||
printf(" %d", imm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void symbol_table_free(struct symbol_table* syms) {
|
||||
jv_mem_free(syms->cfunctions);
|
||||
jv_free(syms->cfunc_names);
|
||||
jv_mem_free(syms);
|
||||
}
|
||||
}
|
||||
|
||||
void bytecode_free(struct bytecode* bc) {
|
||||
if (!bc)
|
||||
return;
|
||||
jv_mem_free(bc->code);
|
||||
jv_free(bc->constants);
|
||||
for (int i=0; i<bc->nsubfunctions; i++)
|
||||
|
||||
+48
-4
@@ -3,10 +3,55 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "jv.h"
|
||||
#include "opcode.h"
|
||||
#include "builtin.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,
|
||||
// NOTE: Not actually part of any op -- a pseudo-op flag for special
|
||||
// handling of `break`.
|
||||
OP_BIND_WILDCARD = 2048,
|
||||
};
|
||||
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);
|
||||
|
||||
|
||||
#define MAX_CFUNCTION_ARGS 10
|
||||
typedef void (*cfunction_ptr)();
|
||||
struct cfunction {
|
||||
cfunction_ptr fptr;
|
||||
const char* name;
|
||||
int nargs;
|
||||
};
|
||||
|
||||
struct symbol_table {
|
||||
struct cfunction* cfunctions;
|
||||
int ncfunctions;
|
||||
@@ -39,10 +84,9 @@ struct bytecode {
|
||||
};
|
||||
|
||||
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);
|
||||
int bytecode_operation_length(uint16_t* codeptr);
|
||||
void bytecode_free(struct bytecode* bc);
|
||||
|
||||
#endif
|
||||
Executable
+102
@@ -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 onig-5.9.5
|
||||
echo "Downloading oniguruma 5.9.5"
|
||||
curl http://www.geocities.jp/kosako3/oniguruma/archive/onig-5.9.5.tar.gz | tar xz
|
||||
cd onig-5.9.5
|
||||
|
||||
# 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 onig-5.9.5
|
||||
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"
|
||||
@@ -2,13 +2,9 @@
|
||||
#define COMPILE_H
|
||||
#include <stdint.h>
|
||||
#include "jv.h"
|
||||
#include "opcode.h"
|
||||
#include "bytecode.h"
|
||||
#include "locfile.h"
|
||||
|
||||
struct bytecode;
|
||||
struct symbol_table;
|
||||
struct cfunction;
|
||||
|
||||
struct inst;
|
||||
typedef struct inst inst;
|
||||
|
||||
@@ -18,41 +14,68 @@ typedef struct block {
|
||||
inst* last;
|
||||
} block;
|
||||
|
||||
block gen_location(location, block);
|
||||
block gen_location(location, struct locfile*, block);
|
||||
|
||||
block gen_noop();
|
||||
int block_is_noop(block b);
|
||||
block gen_op_simple(opcode op);
|
||||
block gen_const(jv constant);
|
||||
block gen_const_global(jv constant, const char *name);
|
||||
int block_is_const(block b);
|
||||
int block_is_const_inf(block b);
|
||||
jv_kind block_const_kind(block b);
|
||||
jv block_const(block b);
|
||||
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_op_unbound(opcode op, const char* name);
|
||||
block gen_op_bound(opcode op, block binder);
|
||||
block gen_op_var_fresh(opcode op, const char* name);
|
||||
|
||||
block gen_module(block metadata);
|
||||
jv block_module_meta(block b);
|
||||
block gen_import(const char* name, block metadata, const char *as, int is_data);
|
||||
block gen_function(const char* name, block formals, block body);
|
||||
block gen_param_regular(const char* name);
|
||||
block gen_param(const char* name);
|
||||
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_const_object(block expr);
|
||||
block gen_collect(block expr);
|
||||
block gen_reduce(const char* varname, block source, block init, block body);
|
||||
block gen_reduce(block source, block matcher, block init, block body);
|
||||
block gen_foreach(block source, block matcher, block init, block update, block extract);
|
||||
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_array_matcher(block left, block curr);
|
||||
block gen_object_matcher(block name, block curr);
|
||||
block gen_destructure(block var, block matcher, block body);
|
||||
|
||||
block gen_cond(block cond, block iftrue, block iffalse);
|
||||
block gen_try_handler(block handler);
|
||||
block gen_try(block exp, block handler);
|
||||
block gen_label(const char *label, block exp);
|
||||
|
||||
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_and_imports(block, int bindflags);
|
||||
int block_has_only_binders(block, int bindflags);
|
||||
int block_has_main(block);
|
||||
int block_is_funcdef(block b);
|
||||
int block_is_single(block b);
|
||||
block block_bind(block binder, block body, int bindflags);
|
||||
block block_bind_library(block binder, block body, int bindflags, const char* libname);
|
||||
block block_bind_referenced(block binder, block body, int bindflags);
|
||||
block block_drop_unreferenced(block body);
|
||||
|
||||
int block_compile(block, struct locfile*, struct bytecode**);
|
||||
jv block_take_imports(block* body);
|
||||
|
||||
int block_compile(block, struct bytecode**, struct locfile*);
|
||||
|
||||
void block_free(block);
|
||||
|
||||
@@ -68,10 +91,11 @@ void block_free(block);
|
||||
#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_8(b1,b2,b3,b4,b5,b6,b7,b8) (block_join(BLOCK_7(b1,b2,b3,b4,b5,b6,b7),(b8)))
|
||||
|
||||
#define BLOCK_IDX(_1,_2,_3,_4,_5,_6,_7,NAME,...) NAME
|
||||
#define BLOCK_IDX(_1,_2,_3,_4,_5,_6,_7,_8,NAME,...) NAME
|
||||
#define BLOCK(...) \
|
||||
BLOCK_IDX(__VA_ARGS__, BLOCK_7, BLOCK_6, BLOCK_5, BLOCK_4, BLOCK_3, BLOCK_2, BLOCK_1)(__VA_ARGS__)
|
||||
BLOCK_IDX(__VA_ARGS__, BLOCK_8, BLOCK_7, BLOCK_6, BLOCK_5, BLOCK_4, BLOCK_3, BLOCK_2, BLOCK_1)(__VA_ARGS__)
|
||||
|
||||
|
||||
#endif
|
||||
-32
@@ -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
|
||||
@@ -0,0 +1,10 @@
|
||||
config.guess
|
||||
config.sub
|
||||
compile
|
||||
depcomp
|
||||
install-sh
|
||||
ltmain.sh
|
||||
missing
|
||||
ylwrap
|
||||
test-driver
|
||||
ar-lib
|
||||
Executable
+270
@@ -0,0 +1,270 @@
|
||||
#! /bin/sh
|
||||
# Wrapper for Microsoft lib.exe
|
||||
|
||||
me=ar-lib
|
||||
scriptversion=2012-03-01.08; # UTC
|
||||
|
||||
# Copyright (C) 2010-2013 Free Software Foundation, Inc.
|
||||
# Written by Peter Rosin <peda@lysator.liu.se>.
|
||||
#
|
||||
# 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>.
|
||||
|
||||
|
||||
# func_error message
|
||||
func_error ()
|
||||
{
|
||||
echo "$me: $1" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
file_conv=
|
||||
|
||||
# func_file_conv build_file
|
||||
# Convert a $build file to $host form and store it in $file
|
||||
# Currently only supports Windows hosts.
|
||||
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 in
|
||||
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_at_file at_file operation archive
|
||||
# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE
|
||||
# for each of them.
|
||||
# When interpreting the content of the @FILE, do NOT use func_file_conv,
|
||||
# since the user would need to supply preconverted file names to
|
||||
# binutils ar, at least for MinGW.
|
||||
func_at_file ()
|
||||
{
|
||||
operation=$2
|
||||
archive=$3
|
||||
at_file_contents=`cat "$1"`
|
||||
eval set x "$at_file_contents"
|
||||
shift
|
||||
|
||||
for member
|
||||
do
|
||||
$AR -NOLOGO $operation:"$member" "$archive" || exit $?
|
||||
done
|
||||
}
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
func_error "no command. Try '$0 --help' for more information."
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<EOF
|
||||
Usage: $me [--help] [--version] PROGRAM ACTION ARCHIVE [MEMBER...]
|
||||
|
||||
Members may be specified in a file named with @FILE.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "$me, version $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
if test $# -lt 3; then
|
||||
func_error "you must specify a program, an action and an archive"
|
||||
fi
|
||||
|
||||
AR=$1
|
||||
shift
|
||||
while :
|
||||
do
|
||||
if test $# -lt 2; then
|
||||
func_error "you must specify a program, an action and an archive"
|
||||
fi
|
||||
case $1 in
|
||||
-lib | -LIB \
|
||||
| -ltcg | -LTCG \
|
||||
| -machine* | -MACHINE* \
|
||||
| -subsystem* | -SUBSYSTEM* \
|
||||
| -verbose | -VERBOSE \
|
||||
| -wx* | -WX* )
|
||||
AR="$AR $1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
action=$1
|
||||
shift
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
orig_archive=$1
|
||||
shift
|
||||
func_file_conv "$orig_archive"
|
||||
archive=$file
|
||||
|
||||
# strip leading dash in $action
|
||||
action=${action#-}
|
||||
|
||||
delete=
|
||||
extract=
|
||||
list=
|
||||
quick=
|
||||
replace=
|
||||
index=
|
||||
create=
|
||||
|
||||
while test -n "$action"
|
||||
do
|
||||
case $action in
|
||||
d*) delete=yes ;;
|
||||
x*) extract=yes ;;
|
||||
t*) list=yes ;;
|
||||
q*) quick=yes ;;
|
||||
r*) replace=yes ;;
|
||||
s*) index=yes ;;
|
||||
S*) ;; # the index is always updated implicitly
|
||||
c*) create=yes ;;
|
||||
u*) ;; # TODO: don't ignore the update modifier
|
||||
v*) ;; # TODO: don't ignore the verbose modifier
|
||||
*)
|
||||
func_error "unknown action specified"
|
||||
;;
|
||||
esac
|
||||
action=${action#?}
|
||||
done
|
||||
|
||||
case $delete$extract$list$quick$replace,$index in
|
||||
yes,* | ,yes)
|
||||
;;
|
||||
yesyes*)
|
||||
func_error "more than one action specified"
|
||||
;;
|
||||
*)
|
||||
func_error "no action specified"
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -n "$delete"; then
|
||||
if test ! -f "$orig_archive"; then
|
||||
func_error "archive not found"
|
||||
fi
|
||||
for member
|
||||
do
|
||||
case $1 in
|
||||
@*)
|
||||
func_at_file "${1#@}" -REMOVE "$archive"
|
||||
;;
|
||||
*)
|
||||
func_file_conv "$1"
|
||||
$AR -NOLOGO -REMOVE:"$file" "$archive" || exit $?
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
elif test -n "$extract"; then
|
||||
if test ! -f "$orig_archive"; then
|
||||
func_error "archive not found"
|
||||
fi
|
||||
if test $# -gt 0; then
|
||||
for member
|
||||
do
|
||||
case $1 in
|
||||
@*)
|
||||
func_at_file "${1#@}" -EXTRACT "$archive"
|
||||
;;
|
||||
*)
|
||||
func_file_conv "$1"
|
||||
$AR -NOLOGO -EXTRACT:"$file" "$archive" || exit $?
|
||||
;;
|
||||
esac
|
||||
done
|
||||
else
|
||||
$AR -NOLOGO -LIST "$archive" | sed -e 's/\\/\\\\/g' | while read member
|
||||
do
|
||||
$AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $?
|
||||
done
|
||||
fi
|
||||
|
||||
elif test -n "$quick$replace"; then
|
||||
if test ! -f "$orig_archive"; then
|
||||
if test -z "$create"; then
|
||||
echo "$me: creating $orig_archive"
|
||||
fi
|
||||
orig_archive=
|
||||
else
|
||||
orig_archive=$archive
|
||||
fi
|
||||
|
||||
for member
|
||||
do
|
||||
case $1 in
|
||||
@*)
|
||||
func_file_conv "${1#@}"
|
||||
set x "$@" "@$file"
|
||||
;;
|
||||
*)
|
||||
func_file_conv "$1"
|
||||
set x "$@" "$file"
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
shift
|
||||
done
|
||||
|
||||
if test -n "$orig_archive"; then
|
||||
$AR -NOLOGO -OUT:"$archive" "$orig_archive" "$@" || exit $?
|
||||
else
|
||||
$AR -NOLOGO -OUT:"$archive" "$@" || exit $?
|
||||
fi
|
||||
|
||||
elif test -n "$list"; then
|
||||
if test ! -f "$orig_archive"; then
|
||||
func_error "archive not found"
|
||||
fi
|
||||
$AR -NOLOGO -LIST "$archive" || exit $?
|
||||
fi
|
||||
+7
-3
@@ -1,10 +1,9 @@
|
||||
#! /bin/sh
|
||||
# Wrapper for compilers which do not understand '-c -o'.
|
||||
|
||||
scriptversion=2012-03-05.13; # UTC
|
||||
scriptversion=2012-10-14.11; # UTC
|
||||
|
||||
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009, 2010, 2012 Free
|
||||
# Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
|
||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -113,6 +112,11 @@ func_cl_dashl ()
|
||||
lib=$dir/$lib.lib
|
||||
break
|
||||
fi
|
||||
if test -f "$dir/lib$lib.a"; then
|
||||
found=yes
|
||||
lib=$dir/lib$lib.a
|
||||
break
|
||||
fi
|
||||
done
|
||||
IFS=$save_IFS
|
||||
|
||||
|
||||
+1558
File diff suppressed because it is too large.
Load diff
+1791
File diff suppressed because it is too large.
Load diff
+270
-187
@@ -1,10 +1,9 @@
|
||||
#! /bin/sh
|
||||
# depcomp - compile a program generating dependencies as side-effects
|
||||
|
||||
scriptversion=2012-03-27.16; # UTC
|
||||
scriptversion=2013-05-30.07; # UTC
|
||||
|
||||
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010,
|
||||
# 2011, 2012 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2013 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
|
||||
@@ -28,9 +27,9 @@ scriptversion=2012-03-27.16; # UTC
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
|
||||
@@ -57,11 +56,65 @@ EOF
|
||||
;;
|
||||
esac
|
||||
|
||||
# Get the directory component of the given path, and save it in the
|
||||
# global variables '$dir'. Note that this directory component will
|
||||
# be either empty or ending with a '/' character. This is deliberate.
|
||||
set_dir_from ()
|
||||
{
|
||||
case $1 in
|
||||
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
|
||||
*) dir=;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Get the suffix-stripped basename of the given path, and save it the
|
||||
# global variable '$base'.
|
||||
set_base_from ()
|
||||
{
|
||||
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
|
||||
}
|
||||
|
||||
# If no dependency file was actually created by the compiler invocation,
|
||||
# we still have to create a dummy depfile, to avoid errors with the
|
||||
# Makefile "include basename.Plo" scheme.
|
||||
make_dummy_depfile ()
|
||||
{
|
||||
echo "#dummy" > "$depfile"
|
||||
}
|
||||
|
||||
# Factor out some common post-processing of the generated depfile.
|
||||
# Requires the auxiliary global variable '$tmpdepfile' to be set.
|
||||
aix_post_process_depfile ()
|
||||
{
|
||||
# If the compiler actually managed to produce a dependency file,
|
||||
# post-process it.
|
||||
if test -f "$tmpdepfile"; then
|
||||
# Each line is of the form 'foo.o: dependency.h'.
|
||||
# Do two passes, one to just change these to
|
||||
# $object: dependency.h
|
||||
# and one to simply output
|
||||
# dependency.h:
|
||||
# which is needed to avoid the deleted-header problem.
|
||||
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
|
||||
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
|
||||
} > "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
else
|
||||
make_dummy_depfile
|
||||
fi
|
||||
}
|
||||
|
||||
# A tabulation character.
|
||||
tab=' '
|
||||
# A newline character.
|
||||
nl='
|
||||
'
|
||||
# Character ranges might be problematic outside the C locale.
|
||||
# These definitions help.
|
||||
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
lower=abcdefghijklmnopqrstuvwxyz
|
||||
digits=0123456789
|
||||
alpha=${upper}${lower}
|
||||
|
||||
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
||||
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
||||
@@ -75,6 +128,9 @@ tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
||||
|
||||
rm -f "$tmpdepfile"
|
||||
|
||||
# Avoid interferences from the environment.
|
||||
gccflag= dashmflag=
|
||||
|
||||
# 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
|
||||
@@ -86,32 +142,32 @@ if test "$depmode" = hp; then
|
||||
fi
|
||||
|
||||
if test "$depmode" = dashXmstdout; then
|
||||
# This is just like dashmstdout with a different argument.
|
||||
dashmflag=-xM
|
||||
depmode=dashmstdout
|
||||
# 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
|
||||
# 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
|
||||
# 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
|
||||
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
|
||||
gccflag=-qmakedep=gcc,-MF
|
||||
depmode=gcc
|
||||
fi
|
||||
|
||||
case "$depmode" in
|
||||
@@ -134,8 +190,7 @@ gcc3)
|
||||
done
|
||||
"$@"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
@@ -143,13 +198,17 @@ gcc3)
|
||||
;;
|
||||
|
||||
gcc)
|
||||
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
|
||||
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
|
||||
## (see the conditional assignment to $gccflag above).
|
||||
## 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).
|
||||
## -MM, not -M (despite what the docs say). Also, it might not be
|
||||
## supported by the other compilers which use the 'gcc' depmode.
|
||||
## - Using -M directly means running the compiler twice (even worse
|
||||
## than renaming).
|
||||
if test -z "$gccflag"; then
|
||||
@@ -157,15 +216,14 @@ gcc)
|
||||
fi
|
||||
"$@" -Wp,"$gccflag$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
if test $stat -ne 0; then
|
||||
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.
|
||||
# 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.
|
||||
@@ -174,15 +232,15 @@ gcc)
|
||||
## 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"
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
@@ -200,8 +258,7 @@ sgi)
|
||||
"$@" -MDupdate "$tmpdepfile"
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
@@ -209,7 +266,6 @@ sgi)
|
||||
|
||||
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
|
||||
@@ -217,19 +273,15 @@ sgi)
|
||||
# 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"
|
||||
| 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"
|
||||
| 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"
|
||||
make_dummy_depfile
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
@@ -247,9 +299,8 @@ aix)
|
||||
# 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$//'`
|
||||
set_dir_from "$object"
|
||||
set_base_from "$object"
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$base.u
|
||||
@@ -262,9 +313,7 @@ aix)
|
||||
"$@" -M
|
||||
fi
|
||||
stat=$?
|
||||
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
exit $stat
|
||||
fi
|
||||
@@ -273,65 +322,113 @@ aix)
|
||||
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"
|
||||
aix_post_process_depfile
|
||||
;;
|
||||
|
||||
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.
|
||||
tcc)
|
||||
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
|
||||
# FIXME: That version still under development at the moment of writing.
|
||||
# Make that this statement remains true also for stable, released
|
||||
# versions.
|
||||
# It will wrap lines (doesn't matter whether long or short) with a
|
||||
# trailing '\', as in:
|
||||
#
|
||||
# foo.o : \
|
||||
# foo.c \
|
||||
# foo.h \
|
||||
#
|
||||
# It will put a trailing '\' even on the last line, and will use leading
|
||||
# spaces rather than leading tabs (at least since its commit 0394caf7
|
||||
# "Emit spaces for -MD").
|
||||
"$@" -MD -MF "$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
if test $stat -ne 0; then
|
||||
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 \'.
|
||||
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
|
||||
# We have to change lines of the first kind to '$object: \'.
|
||||
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
|
||||
# And for each line of the second kind, we have to emit a 'dep.h:'
|
||||
# dummy dependency, to avoid the deleted-header problem.
|
||||
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
## The order of this option in the case statement is important, since the
|
||||
## shell code in configure will try each of these formats in the order
|
||||
## listed in this file. A plain '-MD' option would be understood by many
|
||||
## compilers, so we must ensure this comes after the gcc and icc options.
|
||||
pgcc)
|
||||
# Portland's C compiler understands '-MD'.
|
||||
# Will always output deps to 'file.d' where file is the root name of the
|
||||
# source file under compilation, even if file resides in a subdirectory.
|
||||
# The object file name does not affect the name of the '.d' file.
|
||||
# pgcc 10.2 will output
|
||||
# foo.o: sub/foo.c sub/foo.h
|
||||
# and will wrap long lines using '\' :
|
||||
# foo.o: sub/foo.c ... \
|
||||
# sub/foo.h ... \
|
||||
# ...
|
||||
set_dir_from "$object"
|
||||
# Use the source, not the object, to determine the base name, since
|
||||
# that's sadly what pgcc will do too.
|
||||
set_base_from "$source"
|
||||
tmpdepfile=$base.d
|
||||
|
||||
# For projects that build the same source file twice into different object
|
||||
# files, the pgcc approach of using the *source* file root name can cause
|
||||
# problems in parallel builds. Use a locking strategy to avoid stomping on
|
||||
# the same $tmpdepfile.
|
||||
lockdir=$base.d-lock
|
||||
trap "
|
||||
echo '$0: caught signal, cleaning up...' >&2
|
||||
rmdir '$lockdir'
|
||||
exit 1
|
||||
" 1 2 13 15
|
||||
numtries=100
|
||||
i=$numtries
|
||||
while test $i -gt 0; do
|
||||
# mkdir is a portable test-and-set.
|
||||
if mkdir "$lockdir" 2>/dev/null; then
|
||||
# This process acquired the lock.
|
||||
"$@" -MD
|
||||
stat=$?
|
||||
# Release the lock.
|
||||
rmdir "$lockdir"
|
||||
break
|
||||
else
|
||||
# If the lock is being held by a different process, wait
|
||||
# until the winning process is done or we timeout.
|
||||
while test -d "$lockdir" && test $i -gt 0; do
|
||||
sleep 1
|
||||
i=`expr $i - 1`
|
||||
done
|
||||
fi
|
||||
i=`expr $i - 1`
|
||||
done
|
||||
trap - 1 2 13 15
|
||||
if test $i -le 0; then
|
||||
echo "$0: failed to acquire lock after $numtries attempts" >&2
|
||||
echo "$0: check lockdir '$lockdir'" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test $stat -ne 0; then
|
||||
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"
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
@@ -342,9 +439,8 @@ hp2)
|
||||
# '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$//'`
|
||||
set_dir_from "$object"
|
||||
set_base_from "$object"
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir.libs/$base.d
|
||||
@@ -355,8 +451,7 @@ hp2)
|
||||
"$@" +Maked
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2"
|
||||
exit $stat
|
||||
fi
|
||||
@@ -366,76 +461,61 @@ hp2)
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
|
||||
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
|
||||
# Add 'dependent.h:' lines.
|
||||
sed -ne '2,${
|
||||
s/^ *//
|
||||
s/ \\*$//
|
||||
s/$/:/
|
||||
p
|
||||
}' "$tmpdepfile" >> "$depfile"
|
||||
s/^ *//
|
||||
s/ \\*$//
|
||||
s/$/:/
|
||||
p
|
||||
}' "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
echo "#dummy" > "$depfile"
|
||||
make_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$//'`
|
||||
# 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.
|
||||
set_dir_from "$object"
|
||||
set_base_from "$object"
|
||||
|
||||
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
|
||||
if test "$libtool" = yes; then
|
||||
# Libtool 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$base.o.d # libtool 1.5
|
||||
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
|
||||
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
|
||||
"$@" -Wc,-MD
|
||||
else
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
tmpdepfile3=$dir$base.d
|
||||
"$@" -MD
|
||||
fi
|
||||
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
|
||||
exit $stat
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
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"
|
||||
;;
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
# Same post-processing that is required for AIX mode.
|
||||
aix_post_process_depfile
|
||||
;;
|
||||
|
||||
msvc7)
|
||||
if test "$libtool" = yes; then
|
||||
@@ -446,8 +526,7 @@ msvc7)
|
||||
"$@" $showIncludes > "$tmpdepfile"
|
||||
stat=$?
|
||||
grep -v '^Note: including file: ' "$tmpdepfile"
|
||||
if test "$stat" = 0; then :
|
||||
else
|
||||
if test $stat -ne 0; then
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
@@ -473,6 +552,7 @@ $ {
|
||||
G
|
||||
p
|
||||
}' >> "$depfile"
|
||||
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
@@ -524,13 +604,14 @@ dashmstdout)
|
||||
# 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"
|
||||
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"
|
||||
# Some versions of the HPUX 10.20 sed can't process this sed invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
tr ' ' "$nl" < "$tmpdepfile" \
|
||||
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
@@ -583,10 +664,12 @@ makedepend)
|
||||
# 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"
|
||||
# Some versions of the HPUX 10.20 sed can't process the last invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed '1,2d' "$tmpdepfile" \
|
||||
| tr ' ' "$nl" \
|
||||
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
|
||||
| sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
||||
;;
|
||||
|
||||
@@ -622,10 +705,10 @@ cpp)
|
||||
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"
|
||||
"$@" -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"
|
||||
@@ -657,15 +740,15 @@ msvisualcpp)
|
||||
shift
|
||||
;;
|
||||
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
||||
set fnord "$@"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
set fnord "$@"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
set fnord "$@" "$arg"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
"$@" -E 2>/dev/null |
|
||||
|
||||
+7
-7
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2011-01-19.21; # UTC
|
||||
scriptversion=2011-11-20.07; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
@@ -35,7 +35,7 @@ scriptversion=2011-01-19.21; # UTC
|
||||
# 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
|
||||
# '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
|
||||
@@ -156,7 +156,7 @@ while test $# -ne 0; do
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-t) dst_arg=$2
|
||||
# Protect names problematic for `test' and other utilities.
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
@@ -190,7 +190,7 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
||||
fi
|
||||
shift # arg
|
||||
dst_arg=$arg
|
||||
# Protect names problematic for `test' and other utilities.
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
@@ -202,7 +202,7 @@ if test $# -eq 0; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call `install-sh -d' without argument.
|
||||
# It's OK to call 'install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
@@ -240,7 +240,7 @@ fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names problematic for `test' and other utilities.
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $src in
|
||||
-* | [=\(\)!]) src=./$src;;
|
||||
esac
|
||||
@@ -354,7 +354,7 @@ do
|
||||
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.
|
||||
# other-writable 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
|
||||
|
||||
+9661
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,2 @@
|
||||
libtool.m4
|
||||
lt*.m4
|
||||
@@ -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])
|
||||
])
|
||||
@@ -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])])
|
||||
@@ -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)
|
||||
])
|
||||
@@ -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
|
||||
])
|
||||
Vendored
+7997
File diff suppressed because it is too large.
Load diff
Vendored
+384
@@ -0,0 +1,384 @@
|
||||
# Helper functions for option handling. -*- Autoconf -*-
|
||||
#
|
||||
# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
|
||||
# Inc.
|
||||
# Written by Gary V. Vaughan, 2004
|
||||
#
|
||||
# This file is free software; the Free Software Foundation gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 7 ltoptions.m4
|
||||
|
||||
# This is to help aclocal find these macros, as it can't see m4_define.
|
||||
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
|
||||
|
||||
|
||||
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
|
||||
# ------------------------------------------
|
||||
m4_define([_LT_MANGLE_OPTION],
|
||||
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
|
||||
|
||||
|
||||
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
|
||||
# ---------------------------------------
|
||||
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
|
||||
# matching handler defined, dispatch to it. Other OPTION-NAMEs are
|
||||
# saved as a flag.
|
||||
m4_define([_LT_SET_OPTION],
|
||||
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
|
||||
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
|
||||
_LT_MANGLE_DEFUN([$1], [$2]),
|
||||
[m4_warning([Unknown $1 option `$2'])])[]dnl
|
||||
])
|
||||
|
||||
|
||||
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
|
||||
# ------------------------------------------------------------
|
||||
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
|
||||
m4_define([_LT_IF_OPTION],
|
||||
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
|
||||
|
||||
|
||||
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
|
||||
# -------------------------------------------------------
|
||||
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
|
||||
# are set.
|
||||
m4_define([_LT_UNLESS_OPTIONS],
|
||||
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
|
||||
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
|
||||
[m4_define([$0_found])])])[]dnl
|
||||
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
|
||||
])[]dnl
|
||||
])
|
||||
|
||||
|
||||
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
|
||||
# ----------------------------------------
|
||||
# OPTION-LIST is a space-separated list of Libtool options associated
|
||||
# with MACRO-NAME. If any OPTION has a matching handler declared with
|
||||
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
|
||||
# the unknown option and exit.
|
||||
m4_defun([_LT_SET_OPTIONS],
|
||||
[# Set options
|
||||
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
|
||||
[_LT_SET_OPTION([$1], _LT_Option)])
|
||||
|
||||
m4_if([$1],[LT_INIT],[
|
||||
dnl
|
||||
dnl Simply set some default values (i.e off) if boolean options were not
|
||||
dnl specified:
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
|
||||
])
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
|
||||
])
|
||||
dnl
|
||||
dnl If no reference was made to various pairs of opposing options, then
|
||||
dnl we run the default mode handler for the pair. For example, if neither
|
||||
dnl `shared' nor `disable-shared' was passed, we enable building of shared
|
||||
dnl archives by default:
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
|
||||
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
|
||||
[_LT_ENABLE_FAST_INSTALL])
|
||||
])
|
||||
])# _LT_SET_OPTIONS
|
||||
|
||||
|
||||
## --------------------------------- ##
|
||||
## Macros to handle LT_INIT options. ##
|
||||
## --------------------------------- ##
|
||||
|
||||
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
|
||||
# -----------------------------------------
|
||||
m4_define([_LT_MANGLE_DEFUN],
|
||||
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
|
||||
|
||||
|
||||
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
|
||||
# -----------------------------------------------
|
||||
m4_define([LT_OPTION_DEFINE],
|
||||
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
|
||||
])# LT_OPTION_DEFINE
|
||||
|
||||
|
||||
# dlopen
|
||||
# ------
|
||||
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
|
||||
])
|
||||
|
||||
AU_DEFUN([AC_LIBTOOL_DLOPEN],
|
||||
[_LT_SET_OPTION([LT_INIT], [dlopen])
|
||||
AC_DIAGNOSE([obsolete],
|
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you
|
||||
put the `dlopen' option into LT_INIT's first parameter.])
|
||||
])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
|
||||
|
||||
|
||||
# win32-dll
|
||||
# ---------
|
||||
# Declare package support for building win32 dll's.
|
||||
LT_OPTION_DEFINE([LT_INIT], [win32-dll],
|
||||
[enable_win32_dll=yes
|
||||
|
||||
case $host in
|
||||
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
|
||||
AC_CHECK_TOOL(AS, as, false)
|
||||
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
|
||||
AC_CHECK_TOOL(OBJDUMP, objdump, false)
|
||||
;;
|
||||
esac
|
||||
|
||||
test -z "$AS" && AS=as
|
||||
_LT_DECL([], [AS], [1], [Assembler program])dnl
|
||||
|
||||
test -z "$DLLTOOL" && DLLTOOL=dlltool
|
||||
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
|
||||
|
||||
test -z "$OBJDUMP" && OBJDUMP=objdump
|
||||
_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
|
||||
])# win32-dll
|
||||
|
||||
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
|
||||
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
|
||||
_LT_SET_OPTION([LT_INIT], [win32-dll])
|
||||
AC_DIAGNOSE([obsolete],
|
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you
|
||||
put the `win32-dll' option into LT_INIT's first parameter.])
|
||||
])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
|
||||
|
||||
|
||||
# _LT_ENABLE_SHARED([DEFAULT])
|
||||
# ----------------------------
|
||||
# implement the --enable-shared flag, and supports the `shared' and
|
||||
# `disable-shared' LT_INIT options.
|
||||
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
|
||||
m4_define([_LT_ENABLE_SHARED],
|
||||
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
|
||||
AC_ARG_ENABLE([shared],
|
||||
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
|
||||
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
|
||||
[p=${PACKAGE-default}
|
||||
case $enableval in
|
||||
yes) enable_shared=yes ;;
|
||||
no) enable_shared=no ;;
|
||||
*)
|
||||
enable_shared=no
|
||||
# Look at the argument we got. We use all the common list separators.
|
||||
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
|
||||
for pkg in $enableval; do
|
||||
IFS="$lt_save_ifs"
|
||||
if test "X$pkg" = "X$p"; then
|
||||
enable_shared=yes
|
||||
fi
|
||||
done
|
||||
IFS="$lt_save_ifs"
|
||||
;;
|
||||
esac],
|
||||
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
|
||||
|
||||
_LT_DECL([build_libtool_libs], [enable_shared], [0],
|
||||
[Whether or not to build shared libraries])
|
||||
])# _LT_ENABLE_SHARED
|
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
|
||||
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
|
||||
|
||||
# Old names:
|
||||
AC_DEFUN([AC_ENABLE_SHARED],
|
||||
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
|
||||
])
|
||||
|
||||
AC_DEFUN([AC_DISABLE_SHARED],
|
||||
[_LT_SET_OPTION([LT_INIT], [disable-shared])
|
||||
])
|
||||
|
||||
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
|
||||
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AM_ENABLE_SHARED], [])
|
||||
dnl AC_DEFUN([AM_DISABLE_SHARED], [])
|
||||
|
||||
|
||||
|
||||
# _LT_ENABLE_STATIC([DEFAULT])
|
||||
# ----------------------------
|
||||
# implement the --enable-static flag, and support the `static' and
|
||||
# `disable-static' LT_INIT options.
|
||||
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
|
||||
m4_define([_LT_ENABLE_STATIC],
|
||||
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
|
||||
AC_ARG_ENABLE([static],
|
||||
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
|
||||
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
|
||||
[p=${PACKAGE-default}
|
||||
case $enableval in
|
||||
yes) enable_static=yes ;;
|
||||
no) enable_static=no ;;
|
||||
*)
|
||||
enable_static=no
|
||||
# Look at the argument we got. We use all the common list separators.
|
||||
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
|
||||
for pkg in $enableval; do
|
||||
IFS="$lt_save_ifs"
|
||||
if test "X$pkg" = "X$p"; then
|
||||
enable_static=yes
|
||||
fi
|
||||
done
|
||||
IFS="$lt_save_ifs"
|
||||
;;
|
||||
esac],
|
||||
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
|
||||
|
||||
_LT_DECL([build_old_libs], [enable_static], [0],
|
||||
[Whether or not to build static libraries])
|
||||
])# _LT_ENABLE_STATIC
|
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
|
||||
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
|
||||
|
||||
# Old names:
|
||||
AC_DEFUN([AC_ENABLE_STATIC],
|
||||
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
|
||||
])
|
||||
|
||||
AC_DEFUN([AC_DISABLE_STATIC],
|
||||
[_LT_SET_OPTION([LT_INIT], [disable-static])
|
||||
])
|
||||
|
||||
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
|
||||
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AM_ENABLE_STATIC], [])
|
||||
dnl AC_DEFUN([AM_DISABLE_STATIC], [])
|
||||
|
||||
|
||||
|
||||
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
|
||||
# ----------------------------------
|
||||
# implement the --enable-fast-install flag, and support the `fast-install'
|
||||
# and `disable-fast-install' LT_INIT options.
|
||||
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
|
||||
m4_define([_LT_ENABLE_FAST_INSTALL],
|
||||
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
|
||||
AC_ARG_ENABLE([fast-install],
|
||||
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
|
||||
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
|
||||
[p=${PACKAGE-default}
|
||||
case $enableval in
|
||||
yes) enable_fast_install=yes ;;
|
||||
no) enable_fast_install=no ;;
|
||||
*)
|
||||
enable_fast_install=no
|
||||
# Look at the argument we got. We use all the common list separators.
|
||||
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
|
||||
for pkg in $enableval; do
|
||||
IFS="$lt_save_ifs"
|
||||
if test "X$pkg" = "X$p"; then
|
||||
enable_fast_install=yes
|
||||
fi
|
||||
done
|
||||
IFS="$lt_save_ifs"
|
||||
;;
|
||||
esac],
|
||||
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
|
||||
|
||||
_LT_DECL([fast_install], [enable_fast_install], [0],
|
||||
[Whether or not to optimize for fast installation])dnl
|
||||
])# _LT_ENABLE_FAST_INSTALL
|
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
|
||||
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
|
||||
|
||||
# Old names:
|
||||
AU_DEFUN([AC_ENABLE_FAST_INSTALL],
|
||||
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
|
||||
AC_DIAGNOSE([obsolete],
|
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
|
||||
the `fast-install' option into LT_INIT's first parameter.])
|
||||
])
|
||||
|
||||
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
|
||||
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
|
||||
AC_DIAGNOSE([obsolete],
|
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
|
||||
the `disable-fast-install' option into LT_INIT's first parameter.])
|
||||
])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
|
||||
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
|
||||
|
||||
|
||||
# _LT_WITH_PIC([MODE])
|
||||
# --------------------
|
||||
# implement the --with-pic flag, and support the `pic-only' and `no-pic'
|
||||
# LT_INIT options.
|
||||
# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
|
||||
m4_define([_LT_WITH_PIC],
|
||||
[AC_ARG_WITH([pic],
|
||||
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
|
||||
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
|
||||
[lt_p=${PACKAGE-default}
|
||||
case $withval in
|
||||
yes|no) pic_mode=$withval ;;
|
||||
*)
|
||||
pic_mode=default
|
||||
# Look at the argument we got. We use all the common list separators.
|
||||
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
|
||||
for lt_pkg in $withval; do
|
||||
IFS="$lt_save_ifs"
|
||||
if test "X$lt_pkg" = "X$lt_p"; then
|
||||
pic_mode=yes
|
||||
fi
|
||||
done
|
||||
IFS="$lt_save_ifs"
|
||||
;;
|
||||
esac],
|
||||
[pic_mode=default])
|
||||
|
||||
test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
|
||||
|
||||
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
|
||||
])# _LT_WITH_PIC
|
||||
|
||||
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
|
||||
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
|
||||
|
||||
# Old name:
|
||||
AU_DEFUN([AC_LIBTOOL_PICMODE],
|
||||
[_LT_SET_OPTION([LT_INIT], [pic-only])
|
||||
AC_DIAGNOSE([obsolete],
|
||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you
|
||||
put the `pic-only' option into LT_INIT's first parameter.])
|
||||
])
|
||||
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
|
||||
|
||||
## ----------------- ##
|
||||
## LTDL_INIT Options ##
|
||||
## ----------------- ##
|
||||
|
||||
m4_define([_LTDL_MODE], [])
|
||||
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
|
||||
[m4_define([_LTDL_MODE], [nonrecursive])])
|
||||
LT_OPTION_DEFINE([LTDL_INIT], [recursive],
|
||||
[m4_define([_LTDL_MODE], [recursive])])
|
||||
LT_OPTION_DEFINE([LTDL_INIT], [subproject],
|
||||
[m4_define([_LTDL_MODE], [subproject])])
|
||||
|
||||
m4_define([_LTDL_TYPE], [])
|
||||
LT_OPTION_DEFINE([LTDL_INIT], [installable],
|
||||
[m4_define([_LTDL_TYPE], [installable])])
|
||||
LT_OPTION_DEFINE([LTDL_INIT], [convenience],
|
||||
[m4_define([_LTDL_TYPE], [convenience])])
|
||||
Vendored
+123
@@ -0,0 +1,123 @@
|
||||
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
|
||||
#
|
||||
# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
|
||||
# Written by Gary V. Vaughan, 2004
|
||||
#
|
||||
# This file is free software; the Free Software Foundation gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 6 ltsugar.m4
|
||||
|
||||
# This is to help aclocal find these macros, as it can't see m4_define.
|
||||
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
|
||||
|
||||
|
||||
# lt_join(SEP, ARG1, [ARG2...])
|
||||
# -----------------------------
|
||||
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
|
||||
# associated separator.
|
||||
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
|
||||
# versions in m4sugar had bugs.
|
||||
m4_define([lt_join],
|
||||
[m4_if([$#], [1], [],
|
||||
[$#], [2], [[$2]],
|
||||
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
|
||||
m4_define([_lt_join],
|
||||
[m4_if([$#$2], [2], [],
|
||||
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
|
||||
|
||||
|
||||
# lt_car(LIST)
|
||||
# lt_cdr(LIST)
|
||||
# ------------
|
||||
# Manipulate m4 lists.
|
||||
# These macros are necessary as long as will still need to support
|
||||
# Autoconf-2.59 which quotes differently.
|
||||
m4_define([lt_car], [[$1]])
|
||||
m4_define([lt_cdr],
|
||||
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
|
||||
[$#], 1, [],
|
||||
[m4_dquote(m4_shift($@))])])
|
||||
m4_define([lt_unquote], $1)
|
||||
|
||||
|
||||
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
|
||||
# ------------------------------------------
|
||||
# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
|
||||
# Note that neither SEPARATOR nor STRING are expanded; they are appended
|
||||
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
|
||||
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
|
||||
# than defined and empty).
|
||||
#
|
||||
# This macro is needed until we can rely on Autoconf 2.62, since earlier
|
||||
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
|
||||
m4_define([lt_append],
|
||||
[m4_define([$1],
|
||||
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
|
||||
|
||||
|
||||
|
||||
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
|
||||
# ----------------------------------------------------------
|
||||
# Produce a SEP delimited list of all paired combinations of elements of
|
||||
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
|
||||
# has the form PREFIXmINFIXSUFFIXn.
|
||||
# Needed until we can rely on m4_combine added in Autoconf 2.62.
|
||||
m4_define([lt_combine],
|
||||
[m4_if(m4_eval([$# > 3]), [1],
|
||||
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
|
||||
[[m4_foreach([_Lt_prefix], [$2],
|
||||
[m4_foreach([_Lt_suffix],
|
||||
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
|
||||
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
|
||||
|
||||
|
||||
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
|
||||
# -----------------------------------------------------------------------
|
||||
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
|
||||
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
|
||||
m4_define([lt_if_append_uniq],
|
||||
[m4_ifdef([$1],
|
||||
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
|
||||
[lt_append([$1], [$2], [$3])$4],
|
||||
[$5])],
|
||||
[lt_append([$1], [$2], [$3])$4])])
|
||||
|
||||
|
||||
# lt_dict_add(DICT, KEY, VALUE)
|
||||
# -----------------------------
|
||||
m4_define([lt_dict_add],
|
||||
[m4_define([$1($2)], [$3])])
|
||||
|
||||
|
||||
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
|
||||
# --------------------------------------------
|
||||
m4_define([lt_dict_add_subkey],
|
||||
[m4_define([$1($2:$3)], [$4])])
|
||||
|
||||
|
||||
# lt_dict_fetch(DICT, KEY, [SUBKEY])
|
||||
# ----------------------------------
|
||||
m4_define([lt_dict_fetch],
|
||||
[m4_ifval([$3],
|
||||
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
|
||||
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
|
||||
|
||||
|
||||
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
|
||||
# -----------------------------------------------------------------
|
||||
m4_define([lt_if_dict_fetch],
|
||||
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
|
||||
[$5],
|
||||
[$6])])
|
||||
|
||||
|
||||
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
|
||||
# --------------------------------------------------------------
|
||||
m4_define([lt_dict_filter],
|
||||
[m4_if([$5], [], [],
|
||||
[lt_join(m4_quote(m4_default([$4], [[, ]])),
|
||||
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
|
||||
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
|
||||
])
|
||||
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
# ltversion.m4 -- version numbers -*- Autoconf -*-
|
||||
#
|
||||
# Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
# Written by Scott James Remnant, 2004
|
||||
#
|
||||
# This file is free software; the Free Software Foundation gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
|
||||
# @configure_input@
|
||||
|
||||
# serial 3337 ltversion.m4
|
||||
# This file is part of GNU Libtool
|
||||
|
||||
m4_define([LT_PACKAGE_VERSION], [2.4.2])
|
||||
m4_define([LT_PACKAGE_REVISION], [1.3337])
|
||||
|
||||
AC_DEFUN([LTVERSION_VERSION],
|
||||
[macro_version='2.4.2'
|
||||
macro_revision='1.3337'
|
||||
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
|
||||
_LT_DECL(, macro_revision, 0)
|
||||
])
|
||||
Vendored
+98
@@ -0,0 +1,98 @@
|
||||
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
|
||||
#
|
||||
# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
|
||||
# Written by Scott James Remnant, 2004.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 5 lt~obsolete.m4
|
||||
|
||||
# These exist entirely to fool aclocal when bootstrapping libtool.
|
||||
#
|
||||
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
|
||||
# which have later been changed to m4_define as they aren't part of the
|
||||
# exported API, or moved to Autoconf or Automake where they belong.
|
||||
#
|
||||
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
|
||||
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
|
||||
# using a macro with the same name in our local m4/libtool.m4 it'll
|
||||
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
|
||||
# and doesn't know about Autoconf macros at all.)
|
||||
#
|
||||
# So we provide this file, which has a silly filename so it's always
|
||||
# included after everything else. This provides aclocal with the
|
||||
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
|
||||
# because those macros already exist, or will be overwritten later.
|
||||
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
|
||||
#
|
||||
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
|
||||
# Yes, that means every name once taken will need to remain here until
|
||||
# we give up compatibility with versions before 1.7, at which point
|
||||
# we need to keep only those names which we still refer to.
|
||||
|
||||
# This is to help aclocal find these macros, as it can't see m4_define.
|
||||
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
|
||||
|
||||
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
|
||||
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
|
||||
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
|
||||
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
|
||||
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
|
||||
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
|
||||
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
|
||||
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
|
||||
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
|
||||
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
|
||||
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
|
||||
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
|
||||
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
|
||||
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
|
||||
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
|
||||
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
|
||||
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
|
||||
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
|
||||
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
|
||||
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
|
||||
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
|
||||
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
|
||||
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
|
||||
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
|
||||
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
|
||||
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
|
||||
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
|
||||
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
|
||||
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
|
||||
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
|
||||
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
|
||||
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
|
||||
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
|
||||
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
|
||||
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
|
||||
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
|
||||
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
|
||||
m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
|
||||
m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
|
||||
m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
|
||||
m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
|
||||
m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
|
||||
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
|
||||
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
dnl Shamelessly stolen from Heimdal
|
||||
AC_DEFUN([upcase],[`echo $1 | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`])dnl
|
||||
+148
-264
@@ -1,11 +1,10 @@
|
||||
#! /bin/sh
|
||||
# Common stub for a few missing GNU programs while installing.
|
||||
# Common wrapper for a few potentially missing GNU programs.
|
||||
|
||||
scriptversion=2012-01-06.13; # UTC
|
||||
scriptversion=2013-10-28.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.
|
||||
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
|
||||
# Originally written 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
|
||||
@@ -26,68 +25,40 @@ scriptversion=2012-01-06.13; # UTC
|
||||
# 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"
|
||||
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
|
||||
;;
|
||||
|
||||
--is-lightweight)
|
||||
# Used by our autoconf macros to check whether the available missing
|
||||
# script is modern enough.
|
||||
exit 0
|
||||
;;
|
||||
|
||||
--run)
|
||||
# Back-compat with the calling convention used by older automake.
|
||||
shift
|
||||
;;
|
||||
|
||||
-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.
|
||||
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
|
||||
to PROGRAM being missing or too old.
|
||||
|
||||
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]
|
||||
aclocal autoconf autoheader autom4te automake makeinfo
|
||||
bison yacc flex lex help2man
|
||||
|
||||
Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
|
||||
\`g' are ignored when checking the name.
|
||||
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 $?
|
||||
@@ -99,228 +70,141 @@ Send bug reports to <bug-automake@gnu.org>."
|
||||
;;
|
||||
|
||||
-*)
|
||||
echo 1>&2 "$0: Unknown \`$1' option"
|
||||
echo 1>&2 "Try \`$0 --help' for more information"
|
||||
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'`
|
||||
# Run the given program, remember its exit status.
|
||||
"$@"; st=$?
|
||||
|
||||
# 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 it succeeded, we are done.
|
||||
test $st -eq 0 && exit 0
|
||||
|
||||
# Also exit now if we it failed (or wasn't found), and '--version' was
|
||||
# passed; such an option is passed most likely to detect whether the
|
||||
# program is present and works.
|
||||
case $2 in --version|--help) exit $st;; esac
|
||||
|
||||
# Exit code 63 means version mismatch. This often happens when the user
|
||||
# tries to use an ancient version of a tool on a file that requires a
|
||||
# minimum version.
|
||||
if test $st -eq 63; then
|
||||
msg="probably too old"
|
||||
elif test $st -eq 127; then
|
||||
# Program was missing.
|
||||
msg="missing on your system"
|
||||
else
|
||||
# Program was found and executed, but failed. Give up.
|
||||
exit $st
|
||||
fi
|
||||
|
||||
perl_URL=http://www.perl.org/
|
||||
flex_URL=http://flex.sourceforge.net/
|
||||
gnu_software_URL=http://www.gnu.org/software
|
||||
|
||||
program_details ()
|
||||
{
|
||||
case $1 in
|
||||
aclocal|automake)
|
||||
echo "The '$1' program is part of the GNU Automake package:"
|
||||
echo "<$gnu_software_URL/automake>"
|
||||
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
|
||||
echo "<$gnu_software_URL/autoconf>"
|
||||
echo "<$gnu_software_URL/m4/>"
|
||||
echo "<$perl_URL>"
|
||||
;;
|
||||
autoconf|autom4te|autoheader)
|
||||
echo "The '$1' program is part of the GNU Autoconf package:"
|
||||
echo "<$gnu_software_URL/autoconf/>"
|
||||
echo "It also requires GNU m4 and Perl in order to run:"
|
||||
echo "<$gnu_software_URL/m4/>"
|
||||
echo "<$perl_URL>"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
give_advice ()
|
||||
{
|
||||
# Normalize program name to check for.
|
||||
normalized_program=`echo "$1" | sed '
|
||||
s/^gnu-//; t
|
||||
s/^gnu//; t
|
||||
s/^g//; t'`
|
||||
|
||||
printf '%s\n' "'$1' is $msg."
|
||||
|
||||
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
|
||||
case $normalized_program in
|
||||
autoconf*)
|
||||
echo "You should only need it if you modified 'configure.ac',"
|
||||
echo "or m4 files included by it."
|
||||
program_details 'autoconf'
|
||||
;;
|
||||
autoheader*)
|
||||
echo "You should only need it if you modified 'acconfig.h' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'autoheader'
|
||||
;;
|
||||
automake*)
|
||||
echo "You should only need it if you modified 'Makefile.am' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'automake'
|
||||
;;
|
||||
aclocal*)
|
||||
echo "You should only need it if you modified 'acinclude.m4' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'aclocal'
|
||||
;;
|
||||
autom4te*)
|
||||
echo "You might have modified some maintainer files that require"
|
||||
echo "the 'autom4te' program to be rebuilt."
|
||||
program_details 'autom4te'
|
||||
;;
|
||||
bison*|yacc*)
|
||||
echo "You should only need it if you modified a '.y' file."
|
||||
echo "You may want to install the GNU Bison package:"
|
||||
echo "<$gnu_software_URL/bison/>"
|
||||
;;
|
||||
lex*|flex*)
|
||||
echo "You should only need it if you modified a '.l' file."
|
||||
echo "You may want to install the Fast Lexical Analyzer package:"
|
||||
echo "<$flex_URL>"
|
||||
;;
|
||||
help2man*)
|
||||
echo "You should only need it if you modified a dependency" \
|
||||
"of a man page."
|
||||
echo "You may want to install the GNU Help2man package:"
|
||||
echo "<$gnu_software_URL/help2man/>"
|
||||
;;
|
||||
makeinfo*)
|
||||
echo "You should only need it if you modified a '.texi' file, or"
|
||||
echo "any other file indirectly affecting the aspect of the manual."
|
||||
echo "You might want to install the Texinfo package:"
|
||||
echo "<$gnu_software_URL/texinfo/>"
|
||||
echo "The spurious makeinfo call might also be the consequence of"
|
||||
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
|
||||
echo "want to install GNU make:"
|
||||
echo "<$gnu_software_URL/make/>"
|
||||
;;
|
||||
*)
|
||||
echo "You might have modified some files without having the proper"
|
||||
echo "tools for further handling them. Check the 'README' file, it"
|
||||
echo "often tells you about the needed prerequisites for installing"
|
||||
echo "this package. You may also peek at any GNU archive site, in"
|
||||
echo "case some other package contains this missing '$1' program."
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
*)
|
||||
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
|
||||
give_advice "$1" | sed -e '1s/^/WARNING: /' \
|
||||
-e '2,$s/^/ /' >&2
|
||||
|
||||
# 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
|
||||
# Propagate the correct exit status (expected to be 127 for a program
|
||||
# not found, 63 for a program that failed due to version mismatch).
|
||||
exit $st
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
|
||||
Executable
+139
@@ -0,0 +1,139 @@
|
||||
#! /bin/sh
|
||||
# test-driver - basic testsuite driver script.
|
||||
|
||||
scriptversion=2013-07-13.22; # UTC
|
||||
|
||||
# Copyright (C) 2011-2013 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.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
# Make unconditional expansion of undefined variables an error. This
|
||||
# helps a lot in preventing typo-related bugs.
|
||||
set -u
|
||||
|
||||
usage_error ()
|
||||
{
|
||||
echo "$0: $*" >&2
|
||||
print_usage >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
print_usage ()
|
||||
{
|
||||
cat <<END
|
||||
Usage:
|
||||
test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
|
||||
[--expect-failure={yes|no}] [--color-tests={yes|no}]
|
||||
[--enable-hard-errors={yes|no}] [--]
|
||||
TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
|
||||
The '--test-name', '--log-file' and '--trs-file' options are mandatory.
|
||||
END
|
||||
}
|
||||
|
||||
test_name= # Used for reporting.
|
||||
log_file= # Where to save the output of the test script.
|
||||
trs_file= # Where to save the metadata of the test run.
|
||||
expect_failure=no
|
||||
color_tests=no
|
||||
enable_hard_errors=yes
|
||||
while test $# -gt 0; do
|
||||
case $1 in
|
||||
--help) print_usage; exit $?;;
|
||||
--version) echo "test-driver $scriptversion"; exit $?;;
|
||||
--test-name) test_name=$2; shift;;
|
||||
--log-file) log_file=$2; shift;;
|
||||
--trs-file) trs_file=$2; shift;;
|
||||
--color-tests) color_tests=$2; shift;;
|
||||
--expect-failure) expect_failure=$2; shift;;
|
||||
--enable-hard-errors) enable_hard_errors=$2; shift;;
|
||||
--) shift; break;;
|
||||
-*) usage_error "invalid option: '$1'";;
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
missing_opts=
|
||||
test x"$test_name" = x && missing_opts="$missing_opts --test-name"
|
||||
test x"$log_file" = x && missing_opts="$missing_opts --log-file"
|
||||
test x"$trs_file" = x && missing_opts="$missing_opts --trs-file"
|
||||
if test x"$missing_opts" != x; then
|
||||
usage_error "the following mandatory options are missing:$missing_opts"
|
||||
fi
|
||||
|
||||
if test $# -eq 0; then
|
||||
usage_error "missing argument"
|
||||
fi
|
||||
|
||||
if test $color_tests = yes; then
|
||||
# Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
|
||||
red='[0;31m' # Red.
|
||||
grn='[0;32m' # Green.
|
||||
lgn='[1;32m' # Light green.
|
||||
blu='[1;34m' # Blue.
|
||||
mgn='[0;35m' # Magenta.
|
||||
std='[m' # No color.
|
||||
else
|
||||
red= grn= lgn= blu= mgn= std=
|
||||
fi
|
||||
|
||||
do_exit='rm -f $log_file $trs_file; (exit $st); exit $st'
|
||||
trap "st=129; $do_exit" 1
|
||||
trap "st=130; $do_exit" 2
|
||||
trap "st=141; $do_exit" 13
|
||||
trap "st=143; $do_exit" 15
|
||||
|
||||
# Test script is run here.
|
||||
"$@" >$log_file 2>&1
|
||||
estatus=$?
|
||||
if test $enable_hard_errors = no && test $estatus -eq 99; then
|
||||
estatus=1
|
||||
fi
|
||||
|
||||
case $estatus:$expect_failure in
|
||||
0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
|
||||
0:*) col=$grn res=PASS recheck=no gcopy=no;;
|
||||
77:*) col=$blu res=SKIP recheck=no gcopy=yes;;
|
||||
99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;;
|
||||
*:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;;
|
||||
*:*) col=$red res=FAIL recheck=yes gcopy=yes;;
|
||||
esac
|
||||
|
||||
# Report outcome to console.
|
||||
echo "${col}${res}${std}: $test_name"
|
||||
|
||||
# Register the test result, and other relevant metadata.
|
||||
echo ":test-result: $res" > $trs_file
|
||||
echo ":global-test-result: $res" >> $trs_file
|
||||
echo ":recheck: $recheck" >> $trs_file
|
||||
echo ":copy-in-global-log: $gcopy" >> $trs_file
|
||||
|
||||
# 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:
|
||||
+111
-90
@@ -1,10 +1,9 @@
|
||||
#! /bin/sh
|
||||
# ylwrap - wrapper for lex/yacc invocations.
|
||||
|
||||
scriptversion=2011-08-25.18; # UTC
|
||||
scriptversion=2013-01-12.17; # UTC
|
||||
|
||||
# Copyright (C) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005,
|
||||
# 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
|
||||
#
|
||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||
#
|
||||
@@ -30,9 +29,41 @@ scriptversion=2011-08-25.18; # UTC
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
get_dirname ()
|
||||
{
|
||||
case $1 in
|
||||
*/*|*\\*) printf '%s\n' "$1" | sed -e 's|\([\\/]\)[^\\/]*$|\1|';;
|
||||
# Otherwise, we want the empty string (not ".").
|
||||
esac
|
||||
}
|
||||
|
||||
# guard FILE
|
||||
# ----------
|
||||
# The CPP macro used to guard inclusion of FILE.
|
||||
guard ()
|
||||
{
|
||||
printf '%s\n' "$1" \
|
||||
| sed \
|
||||
-e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \
|
||||
-e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g' \
|
||||
-e 's/__*/_/g'
|
||||
}
|
||||
|
||||
# quote_for_sed [STRING]
|
||||
# ----------------------
|
||||
# Return STRING (or stdin) quoted to be used as a sed pattern.
|
||||
quote_for_sed ()
|
||||
{
|
||||
case $# in
|
||||
0) cat;;
|
||||
1) printf '%s\n' "$1";;
|
||||
esac \
|
||||
| sed -e 's|[][\\.*]|\\&|g'
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
'')
|
||||
echo "$0: No files given. Try \`$0 --help' for more information." 1>&2
|
||||
echo "$0: No files given. Try '$0 --help' for more information." 1>&2
|
||||
exit 1
|
||||
;;
|
||||
--basedir)
|
||||
@@ -65,39 +96,71 @@ esac
|
||||
|
||||
|
||||
# The input.
|
||||
input="$1"
|
||||
input=$1
|
||||
shift
|
||||
case "$input" in
|
||||
# We'll later need for a correct munging of "#line" directives.
|
||||
input_sub_rx=`get_dirname "$input" | quote_for_sed`
|
||||
case $input in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
# Absolute path; do nothing.
|
||||
;;
|
||||
*)
|
||||
# Relative path. Make it absolute.
|
||||
input="`pwd`/$input"
|
||||
input=`pwd`/$input
|
||||
;;
|
||||
esac
|
||||
input_rx=`get_dirname "$input" | quote_for_sed`
|
||||
|
||||
pairlist=
|
||||
while test "$#" -ne 0; do
|
||||
if test "$1" = "--"; then
|
||||
# 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=false
|
||||
if test -f y_tab.c || test -f y_tab.h; then
|
||||
y_tab_nodot=true
|
||||
fi
|
||||
|
||||
# The parser itself, the first file, is the destination of the .y.c
|
||||
# rule in the Makefile.
|
||||
parser=$1
|
||||
|
||||
# A sed program to s/FROM/TO/g for all the FROM/TO so that, for
|
||||
# instance, we rename #include "y.tab.h" into #include "parse.h"
|
||||
# during the conversion from y.tab.c to parse.c.
|
||||
sed_fix_filenames=
|
||||
|
||||
# Also rename header guards, as Bison 2.7 for instance uses its header
|
||||
# guard in its implementation file.
|
||||
sed_fix_header_guards=
|
||||
|
||||
while test $# -ne 0; do
|
||||
if test x"$1" = x"--"; then
|
||||
shift
|
||||
break
|
||||
fi
|
||||
pairlist="$pairlist $1"
|
||||
from=$1
|
||||
# Handle y_tab.c and y_tab.h output by DOS
|
||||
if $y_tab_nodot; then
|
||||
case $from in
|
||||
"y.tab.c") from=y_tab.c;;
|
||||
"y.tab.h") from=y_tab.h;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
to=$1
|
||||
shift
|
||||
sed_fix_filenames="${sed_fix_filenames}s|"`quote_for_sed "$from"`"|$to|g;"
|
||||
sed_fix_header_guards="${sed_fix_header_guards}s|"`guard "$from"`"|"`guard "$to"`"|g;"
|
||||
done
|
||||
|
||||
# The program to run.
|
||||
prog="$1"
|
||||
prog=$1
|
||||
shift
|
||||
# Make any relative path in $prog absolute.
|
||||
case "$prog" in
|
||||
case $prog in
|
||||
[\\/]* | ?:[\\/]*) ;;
|
||||
*[\\/]*) prog="`pwd`/$prog" ;;
|
||||
*[\\/]*) 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
|
||||
@@ -115,98 +178,56 @@ 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
|
||||
for from in *
|
||||
do
|
||||
to=`printf '%s\n' "$from" | sed "$sed_fix_filenames"`
|
||||
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";;
|
||||
# otherwise prepend '../'.
|
||||
case $to in
|
||||
[\\/]* | ?:[\\/]*) target=$to;;
|
||||
*) target=../$to;;
|
||||
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`"
|
||||
# Do not overwrite unchanged header files to avoid useless
|
||||
# recompilations. Always update the parser itself: 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 $from != $parser; then
|
||||
realtarget=$target
|
||||
target=tmp-`printf '%s\n' "$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=$?
|
||||
# Munge "#line" or "#" directives. Don't let the resulting
|
||||
# debug information point at an absolute srcdir. Use the real
|
||||
# output file name, not yy.lex.c for instance. Adjust the
|
||||
# include guards too.
|
||||
sed -e "/^#/!b" \
|
||||
-e "s|$input_rx|$input_sub_rx|" \
|
||||
-e "$sed_fix_filenames" \
|
||||
-e "$sed_fix_header_guards" \
|
||||
"$from" >"$target" || ret=$?
|
||||
|
||||
# Check whether header files must be updated.
|
||||
if test $first = no; then
|
||||
# Check whether files must be updated.
|
||||
if test "$from" != "$parser"; then
|
||||
if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then
|
||||
echo "$2" is unchanged
|
||||
echo "$to is unchanged"
|
||||
rm -f "$target"
|
||||
else
|
||||
echo updating "$2"
|
||||
echo "updating $to"
|
||||
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
|
||||
# A missing file is only an error for the parser. This is a
|
||||
# blatant hack to let us support using "yacc -d". If -d is not
|
||||
# specified, don't fail when the header file is "missing".
|
||||
if test "$from" = "$parser"; then
|
||||
ret=1
|
||||
fi
|
||||
fi
|
||||
shift
|
||||
shift
|
||||
first=no
|
||||
done
|
||||
else
|
||||
ret=$?
|
||||
fi
|
||||
|
||||
# Remove the directory.
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
+175
-20
@@ -1,28 +1,76 @@
|
||||
AC_INIT([jq], [1.3], [mu@netsoc.tcd.ie],
|
||||
[jq], [http://stedolan.github.com/jq/])
|
||||
m4_define([jq_version], m4_esyscmd_s([git describe --tags --dirty --match 'jq-*'|sed 's/^jq-//']))
|
||||
|
||||
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 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_PROG_LEX
|
||||
if test "x$LEX" != xflex; then
|
||||
LEX="$SHELL $missing_dir/missing flex"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
##########################################################################
|
||||
# check for ONIGURUMA library
|
||||
##########################################################################
|
||||
|
||||
AC_ARG_WITH([oniguruma],
|
||||
[AS_HELP_STRING([--with-oniguruma=prefix],
|
||||
[try this for a non-standard install prefix of the oniguruma library])],
|
||||
[ONIGURUMAPATHSET=1],
|
||||
[ONIGURUMAPATHSET=0])
|
||||
|
||||
if test $ONIGURUMAPATHSET = 1; then
|
||||
CFLAGS="$CFLAGS -I${with_oniguruma}/include"
|
||||
LDFLAGS="$LDFLAGS -L${with_oniguruma}/lib"
|
||||
fi
|
||||
|
||||
# check for ONIGURUMA library
|
||||
HAVE_ONIGURUMA=0
|
||||
AC_CHECK_HEADER("oniguruma.h",
|
||||
AC_CHECK_LIB([onig],[onig_version],[LIBS="$LIBS -lonig"; HAVE_ONIGURUMA=1;]))
|
||||
|
||||
# handle check results
|
||||
if test $HAVE_ONIGURUMA != 1; then
|
||||
AC_MSG_NOTICE([Oniguruma was not found.])
|
||||
AC_MSG_NOTICE([ Try setting the location using '--with-oniguruma=PREFIX' ])
|
||||
else
|
||||
AC_DEFINE([HAVE_ONIGURUMA],1,[Define to 1 if Oniguruma is installed])
|
||||
fi
|
||||
|
||||
|
||||
@@ -31,18 +79,41 @@ 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)
|
||||
|
||||
|
||||
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 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 *
|
||||
@@ -50,16 +121,100 @@ AS_IF([test "x$enable_docs" != "xno"],[
|
||||
* 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_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([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(atan, [.5])
|
||||
AC_CHECK_MATH_FUNC(atanh, [.5])
|
||||
AC_CHECK_MATH_FUNC(cbrt, [.5])
|
||||
AC_CHECK_MATH_FUNC(cos, [.5])
|
||||
AC_CHECK_MATH_FUNC(cosh, [.5])
|
||||
AC_CHECK_MATH_FUNC(exp2, [.5])
|
||||
AC_CHECK_MATH_FUNC(exp, [.5])
|
||||
AC_CHECK_MATH_FUNC(floor, [.5])
|
||||
AC_CHECK_MATH_FUNC(j0, [.5])
|
||||
AC_CHECK_MATH_FUNC(j1, [.5])
|
||||
AC_CHECK_MATH_FUNC(log10, [.5])
|
||||
AC_CHECK_MATH_FUNC(log2, [.5])
|
||||
AC_CHECK_MATH_FUNC(log, [.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(y0, [.5])
|
||||
AC_CHECK_MATH_FUNC(y1, [.5])
|
||||
AC_CHECK_MATH_FUNC(pow, [2,2])
|
||||
AC_CHECK_MATH_FUNC(atan2, [.5,.5])
|
||||
AC_CHECK_MATH_FUNC(hypot, [.5,.5])
|
||||
AC_CHECK_MATH_FUNC(remainder, [3,2])
|
||||
|
||||
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)
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -4,3 +4,4 @@ gem "rake"
|
||||
gem "bonsai"
|
||||
gem "maruku"
|
||||
gem "ronn"
|
||||
gem "mustache", "<1.0" # to support ruby <2.0
|
||||
+30
-30
@@ -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
@@ -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:
|
||||
|
||||
+1
-2
@@ -75,7 +75,7 @@ $BINARIES = {
|
||||
|
||||
$BINARIES.each do |name, args|
|
||||
file "../build/#{name}" do |t|
|
||||
sh "MAKEFLAGS=-j4 ../scripts/crosscompile #{name} #{args}"
|
||||
sh "../scripts/crosscompile -j4 #{name} #{args}"
|
||||
end
|
||||
task :binaries => ["../build/#{name}"]
|
||||
end
|
||||
@@ -87,7 +87,6 @@ task :binaries => ["output/download"] do
|
||||
end
|
||||
|
||||
def load_manual
|
||||
YAML::ENGINE.yamler = 'syck'
|
||||
YAML::load(File.open("content/3.manual/manual.yml"))
|
||||
end
|
||||
|
||||
|
||||
+261
-175
@@ -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":"<a href="http:\/\/twitter.com\/">web<\/a>","text":"RT @imagemechanics: iPhone 5 website teardown: How Apple compresses video using JPEG, JSON, and <canvas>.\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 <canvas>.\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 <canvas>.\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 <canvas>.\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 <canvas>.\nhttp://t.co/XRvh1ZVw",
|
||||
"from_user": "_AaronNg"
|
||||
}
|
||||
{
|
||||
"text": "RT @_kud: iPhone 5 website teardown: How Apple compresses video using JPEG, JSON, and <canvas> -- 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 <canvas> 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 <canvas>.\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 <canvas> -- 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 <canvas> 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 <canvas>.\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 <canvas> -- 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 <canvas> 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.
|
||||
@@ -16,7 +16,8 @@ body:
|
||||
|
||||
### Linux
|
||||
|
||||
* Binaries for [64-bit](linux64/jq) or [32-bit](linux32/jq) systems.
|
||||
* jq 1.4 binaries for [64-bit](linux64/jq) or [32-bit](linux32/jq) systems.
|
||||
* jq 1.3 binaries for [64-bit](linux64/jq-1.3/jq) or [32-bit](linux32/jq-1.3/jq) systems.
|
||||
|
||||
* For Arch users, a PKGBUILD for jq-1.1 is in the
|
||||
[AUR](https://aur.archlinux.org/packages.php?ID=63849), as
|
||||
@@ -27,22 +28,42 @@ body:
|
||||
manually by following instructions on [Arch Linux's
|
||||
Wiki](https://wiki.archlinux.org/index.php/Arch_UseRepository).
|
||||
|
||||
* jq 1.2 is [in Debian](http://packages.debian.org/jq)
|
||||
* jq 1.4 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`.
|
||||
|
||||
* jq 1.4 is [in Debian](http://packages.debian.org/jq)
|
||||
|
||||
* jq 1.3.2 is in the official Fedora repository. You can install using
|
||||
`sudo yum install jq`.
|
||||
|
||||
### OS X
|
||||
|
||||
* `brew install jq` using [homebrew](http://mxcl.github.com/homebrew/)
|
||||
|
||||
* Or, grab prebuilt [64-bit binaries](osx64/jq) or [32-bit
|
||||
* Or, grab prebuilt jq 1.4 [64-bit binaries](osx64/jq) or [32-bit
|
||||
binaries](osx32/jq)
|
||||
|
||||
* Or, grab prebuilt jq 1.3 [64-bit binaries](osx64/jq-1.3/jq) or [32-bit
|
||||
binaries](osx32/jq-1.3/jq)
|
||||
|
||||
### Solaris
|
||||
|
||||
* `pkgutil -i jq` in [OpenCSW](http://www.opencsw.org/p/jq) for Solaris 10+, Sparc and x86
|
||||
|
||||
* jq 1.4 executables for Solaris 11 [64-bit](solaris11-64/jq) or [32-bit](solaris11-32/jq)
|
||||
|
||||
### Windows
|
||||
|
||||
* Executables for [64-bit](win64/jq.exe) or [32-bit](win32/jq.exe)
|
||||
* `chocolatey install jq` using [Chocolatey NuGet](https://chocolatey.org/)
|
||||
|
||||
### From source on Linux or OS X
|
||||
* jq 1.4 executables for [64-bit](win64/jq.exe) or [32-bit](win32/jq.exe)
|
||||
|
||||
* [Source tarball for jq $JQ_VERSION](source/jq-$JQ_VERSION.tar.gz)
|
||||
* jq 1.3 executables for [64-bit](win64/jq-1.3/jq-1.3.exe) or [32-bit](win32/jq-1.3/jq-1.3.exe)
|
||||
|
||||
### From source on Linux, OS X, Cygwin, and other POSIX-like operating systems
|
||||
|
||||
* [Source tarball for jq 1.4](source/jq-1.4.tar.gz)
|
||||
|
||||
You can build it using the usual `./configure && make && sudo
|
||||
make install` rigmarole.
|
||||
@@ -51,7 +72,7 @@ body:
|
||||
|
||||
git clone https://github.com/stedolan/jq.git
|
||||
cd jq
|
||||
autoreconf
|
||||
autoreconf -i
|
||||
./configure
|
||||
make
|
||||
sudo make install
|
||||
@@ -59,32 +80,38 @@ body:
|
||||
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/)
|
||||
* [GCC](http://gcc.gnu.org)
|
||||
* [Make](http://www.gnu.org/software/make)
|
||||
* [Autotools](http://www.gnu.org/software/automake)
|
||||
* [Flex](http://flex.sourceforge.net/)
|
||||
* [Bison](https://www.gnu.org/software/bison/)
|
||||
* [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/).
|
||||
|
||||
`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.
|
||||
jq. For jq 1.5, neither is required if you use `./configure
|
||||
--disable-maintainer-mode` instead of `./configure`. This flag says to use
|
||||
the pre-generated lexer and parser that come with the code.
|
||||
|
||||
#### 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. You'll
|
||||
need a few Ruby dependencies, which can be installed by
|
||||
following the instructions in `docs/README.md`.
|
||||
[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.
|
||||
|
||||
|
||||
+1813
-198
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
@@ -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,21 +14,38 @@ 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.
|
||||
|
||||
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: 2015-01-01
|
||||
body: |
|
||||
|
||||
jq 1.5rc1 Get it on the
|
||||
[releases](https://github.com/stedolan/jq/releases) page.
|
||||
|
||||
- date: 2014-06-08
|
||||
body: |
|
||||
|
||||
jq 1.4 (finally) released! Get it on the [download](download/) page.
|
||||
|
||||
- date: 2013-05-19
|
||||
body: |
|
||||
|
||||
jq 1.3 (finally) released! Get it on the [download](download/) page.
|
||||
|
||||
jq 1.3 released.
|
||||
|
||||
@@ -9,8 +9,8 @@ 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
|
||||
|
||||
https://stedolan.github.io/jq
|
||||
|
||||
## BUGS
|
||||
|
||||
Presumably. Report them or discuss them at:
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
# 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.3"
|
||||
jq_version: "1.4-2-g15c4a7f-dirty"
|
||||
|
||||
root: '/jq'
|
||||
footer: |
|
||||
|
||||
Vendored
+10
-1
@@ -10,6 +10,7 @@
|
||||
<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}}
|
||||
@@ -18,10 +19,18 @@
|
||||
<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>
|
||||
<li><a href="{{root}}/download/solaris11-64/jq">Solaris (64-bit)</a></li>
|
||||
<li><a href="{{root}}/download/win64/jq.exe">Windows (64-bit)</a></li>
|
||||
<li><a href="{{root}}/download/">Other platforms, older versions, and source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="btn-group" style="float:right">
|
||||
<a class="btn btn-primary" href="https://jqplay.org">
|
||||
Try online at jqplay.org!
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div style="clear:both;"></div>
|
||||
</div>
|
||||
|
||||
Vendored
+15
-3
@@ -35,6 +35,17 @@
|
||||
}
|
||||
});
|
||||
});
|
||||
// add "Run" button to execute examples on jqplay.org
|
||||
$(function() {
|
||||
$.each($('table.manual-example'), 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><th><a href="' + url + '" class="btn btn-primary btn-small">Run</a></th><th></th></tr><tr><th></th><th></th></tr>');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<input type="text"
|
||||
class="input-medium search-query"
|
||||
@@ -46,6 +57,7 @@
|
||||
</div>
|
||||
<div class="span9">
|
||||
<h1>{{headline}}</h1>
|
||||
{{ history | markdownify }}
|
||||
{{ body | markdownify }}
|
||||
{% for section in sections %}
|
||||
<section id="{{section.title | sanitize}}">
|
||||
@@ -70,8 +82,8 @@
|
||||
|
||||
{% 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>
|
||||
<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>
|
||||
@@ -85,7 +97,7 @@
|
||||
{% else %}
|
||||
<th></th>
|
||||
{% endif %}
|
||||
<td>{{output}}</td>
|
||||
<td>{{output | escape}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
|
||||
Vendored
+2
@@ -17,6 +17,8 @@
|
||||
{% 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>
|
||||
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
#ifndef EXEC_STACK_H
|
||||
#define EXEC_STACK_H
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "jv_alloc.h"
|
||||
|
||||
/*
|
||||
* The stack is a directed forest of variably sized blocks. Each block has a
|
||||
* "next" block which is at a higher memory address, or 0 if the block has no
|
||||
* "next" block. More than one block may have no "next" block. A block may be
|
||||
* the "next" block of more than one other block. Pushed blocks are added at
|
||||
* the low-address end of the stack.
|
||||
*
|
||||
* Stack pointers are negative integers that are offsets relative to "mem_end",
|
||||
* the end of the allocated region. The stack "bound" is the stack pointer of
|
||||
* the last block that would be able to fit in the currently allocated region.
|
||||
* The stack "limit" is the stack pointer of the last block currently in the
|
||||
* stack. The stack pointer of the "next" block is stored directly below each
|
||||
* block.
|
||||
*
|
||||
* <- mem_end = 0x100
|
||||
* 0xF8 +------------+
|
||||
* 0xF0 | |
|
||||
* 0xE8 +------------+ <- stack_ptr1 = -0x18
|
||||
* 0xE0 next = 0
|
||||
* 0xD8 +------------+
|
||||
* 0xD0 | |
|
||||
* 0xC8 | |
|
||||
* 0xC0 +------------+ <- stack_ptr2 = limit = -0x40
|
||||
* 0xB8 next = -0x18
|
||||
* 0xB0
|
||||
* 0xA8 <- bound = -0x58
|
||||
* 0xA0
|
||||
*/
|
||||
|
||||
struct determine_alignment {
|
||||
char x;
|
||||
union { int i; double d; uint64_t u64; size_t sz; void* ptr; } u;
|
||||
};
|
||||
enum {ALIGNMENT = offsetof(struct determine_alignment, u)};
|
||||
|
||||
static size_t align_round_up(size_t sz) {
|
||||
return ((sz + (ALIGNMENT - 1)) / ALIGNMENT) * ALIGNMENT;
|
||||
}
|
||||
|
||||
typedef int stack_ptr;
|
||||
|
||||
struct stack {
|
||||
char* mem_end; // one-past-the-end of allocated region
|
||||
stack_ptr bound;
|
||||
stack_ptr limit; // 0 - stack is empty
|
||||
};
|
||||
|
||||
static void stack_init(struct stack* s) {
|
||||
s->mem_end = 0;
|
||||
s->bound = ALIGNMENT;
|
||||
s->limit = 0;
|
||||
}
|
||||
|
||||
static void stack_reset(struct stack* s) {
|
||||
assert(s->limit == 0 && "stack freed while not empty");
|
||||
char* mem_start = s->mem_end - ( -s->bound + ALIGNMENT);
|
||||
free(mem_start);
|
||||
stack_init(s);
|
||||
}
|
||||
|
||||
static int stack_pop_will_free(struct stack* s, stack_ptr p) {
|
||||
return p == s->limit;
|
||||
}
|
||||
|
||||
static void* stack_block(struct stack* s, stack_ptr p) {
|
||||
return (void*)(s->mem_end + p);
|
||||
}
|
||||
|
||||
static stack_ptr* stack_block_next(struct stack* s, stack_ptr p) {
|
||||
return &((stack_ptr*)stack_block(s, p))[-1];
|
||||
}
|
||||
|
||||
static void stack_reallocate(struct stack* s, size_t sz) {
|
||||
int old_mem_length = -(s->bound) + ALIGNMENT;
|
||||
char* old_mem_start = s->mem_end - old_mem_length;
|
||||
|
||||
int new_mem_length = align_round_up((old_mem_length + sz + 256) * 2);
|
||||
char* new_mem_start = jv_mem_realloc(old_mem_start, new_mem_length);
|
||||
memmove(new_mem_start + (new_mem_length - old_mem_length),
|
||||
new_mem_start, old_mem_length);
|
||||
s->mem_end = new_mem_start + new_mem_length;
|
||||
s->bound = -(new_mem_length - ALIGNMENT);
|
||||
}
|
||||
|
||||
static stack_ptr stack_push_block(struct stack* s, stack_ptr p, size_t sz) {
|
||||
int alloc_sz = align_round_up(sz) + ALIGNMENT;
|
||||
stack_ptr r = s->limit - alloc_sz;
|
||||
if (r < s->bound) {
|
||||
stack_reallocate(s, alloc_sz);
|
||||
}
|
||||
s->limit = r;
|
||||
*stack_block_next(s, r) = p;
|
||||
return r;
|
||||
}
|
||||
|
||||
static stack_ptr stack_pop_block(struct stack* s, stack_ptr p, size_t sz) {
|
||||
stack_ptr r = *stack_block_next(s, p);
|
||||
if (p == s->limit) {
|
||||
int alloc_sz = align_round_up(sz) + ALIGNMENT;
|
||||
s->limit += alloc_sz;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
@@ -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
|
||||
@@ -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
|
||||
-104
@@ -1,104 +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;
|
||||
};
|
||||
|
||||
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;
|
||||
for (int i=0; i<cl.bc->nlocals; i++) {
|
||||
*frame_local_var(fp, i) = jv_invalid();
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
|
||||
static void frame_pop(struct forkable_stack* stk) {
|
||||
frame_ptr fp = frame_current(stk);
|
||||
if (forkable_stack_pop_will_free(stk)) {
|
||||
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
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
|
||||
#define _GNU_SOURCE /* for RTLD_NEXT */
|
||||
#include <assert.h>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static FILE *fail;
|
||||
static FILE *fail_read;
|
||||
static FILE *fail_write;
|
||||
static FILE *fail_close;
|
||||
static int error;
|
||||
|
||||
static FILE * (*real_fopen)(const char *, const char *);
|
||||
static int (*real_fclose)(FILE *);
|
||||
static int (*real_ferror)(FILE *);
|
||||
static void (*real_clearerr)(FILE *);
|
||||
static char * (*real_fgets)(char *, int, FILE *);
|
||||
static size_t (*real_fread)(void *, size_t, size_t, FILE *);
|
||||
static size_t (*real_fwrite)(const void *, size_t, size_t, FILE *);
|
||||
|
||||
#define GET_REAL(sym) \
|
||||
do { \
|
||||
if (real_ ## sym == 0) { \
|
||||
real_ ## sym = dlsym(RTLD_NEXT, #sym); \
|
||||
assert(real_ ## sym != 0); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define dbg_write(msg) (void)write(2, msg, sizeof(msg) - 1)
|
||||
|
||||
#define dbg() \
|
||||
do { \
|
||||
dbg_write("here: "); \
|
||||
dbg_write(__func__); \
|
||||
dbg_write("!\n"); \
|
||||
} while (0)
|
||||
|
||||
FILE *fopen(const char *path, const char *mode) {
|
||||
GET_REAL(fopen);
|
||||
fail = fail_read = fail_write = fail_close = 0;
|
||||
FILE *f = real_fopen(path, mode);
|
||||
error = EIO;
|
||||
if (strcmp(path, "fail_read") == 0) {
|
||||
fail = fail_read = f;
|
||||
} else if (strncmp(path, "fail_write", sizeof("fail_write") - 1) == 0) {
|
||||
// Not that jq opens files for write anyways...
|
||||
fail = fail_write = f;
|
||||
if (strcmp(path, "fail_write_enospc") == 0)
|
||||
error = ENOSPC;
|
||||
} else if (strncmp(path, "fail_close", sizeof("fail_close") - 1) == 0) {
|
||||
fail = fail_close = f;
|
||||
if (strcmp(path, "fail_close_enospc") == 0)
|
||||
error = ENOSPC;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
int fclose(FILE *f) {
|
||||
GET_REAL(fclose);
|
||||
int res = real_fclose(f);
|
||||
if (fail_close == f) {
|
||||
fail = fail_read = fail_write = fail_close = 0;
|
||||
return EOF;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
char * fgets(char *buf, int len, FILE *f) {
|
||||
GET_REAL(fgets);
|
||||
char *res = real_fgets(buf, len, f);
|
||||
if (fail_read == f)
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
size_t fread(void *buf, size_t sz, size_t nemb, FILE *f) {
|
||||
GET_REAL(fread);
|
||||
size_t res = real_fread(buf, sz, nemb, f);
|
||||
if (fail_read == f)
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
size_t fwrite(const void *buf, size_t sz, size_t nemb, FILE *f) {
|
||||
GET_REAL(fwrite);
|
||||
size_t res = real_fwrite(buf, sz, nemb, f);
|
||||
if (fail_write == f)
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
int ferror(FILE *f) {
|
||||
GET_REAL(ferror);
|
||||
int res = real_ferror(f);
|
||||
if (fail == f) {
|
||||
errno = error;
|
||||
return 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void clearerr(FILE *f) {
|
||||
GET_REAL(clearerr);
|
||||
real_clearerr(f);
|
||||
if (fail == f) {
|
||||
fail = fail_read = fail_write = fail_close = 0;
|
||||
error = 0;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "JQ" "1" "May 2013" "" ""
|
||||
.TH "JQ" "1" "August 2015" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBjq\fR \- Command\-line JSON processor
|
||||
@@ -16,7 +16,7 @@ This version of \fBjq\fR was built without a manual, so this manpage is a stub\.
|
||||
.
|
||||
.nf
|
||||
|
||||
http://stedolan\.github\.com/jq
|
||||
https://stedolan\.github\.io/jq
|
||||
.
|
||||
.fi
|
||||
.
|
||||
|
||||
+3075
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,60 @@
|
||||
#ifndef JQ_H
|
||||
#define JQ_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <jv.h>
|
||||
|
||||
enum {JQ_DEBUG_TRACE = 1};
|
||||
|
||||
typedef struct jq_state jq_state;
|
||||
typedef void (*jq_msg_cb)(void *, jv);
|
||||
|
||||
jq_state *jq_init(void);
|
||||
void jq_set_error_cb(jq_state *, jq_msg_cb, void *);
|
||||
void jq_get_error_cb(jq_state *, jq_msg_cb *, void **);
|
||||
void jq_set_nomem_handler(jq_state *, void (*)(void *), void *);
|
||||
jv jq_format_error(jv msg);
|
||||
void jq_report_error(jq_state *, jv);
|
||||
int jq_compile(jq_state *, const char*);
|
||||
int jq_compile_args(jq_state *, const char*, jv);
|
||||
void jq_dump_disassembly(jq_state *, int);
|
||||
void jq_start(jq_state *, jv value, int);
|
||||
jv jq_next(jq_state *);
|
||||
void jq_teardown(jq_state **);
|
||||
|
||||
typedef jv (*jq_input_cb)(jq_state *, void *);
|
||||
void jq_set_input_cb(jq_state *, jq_input_cb, void *);
|
||||
void jq_get_input_cb(jq_state *, jq_input_cb *, void **);
|
||||
|
||||
void jq_set_debug_cb(jq_state *, jq_msg_cb, void *);
|
||||
void jq_get_debug_cb(jq_state *, jq_msg_cb *, void **);
|
||||
|
||||
void jq_set_attrs(jq_state *, jv);
|
||||
jv jq_get_attrs(jq_state *);
|
||||
jv jq_get_jq_origin(jq_state *);
|
||||
jv jq_get_prog_origin(jq_state *);
|
||||
jv jq_get_lib_dirs(jq_state *);
|
||||
void jq_set_attr(jq_state *, jv, jv);
|
||||
jv jq_get_attr(jq_state *, jv);
|
||||
|
||||
/*
|
||||
* We use char * instead of jf for filenames here because filenames
|
||||
* should be in the process' locale's codeset, which may not be UTF-8,
|
||||
* whereas jv string values must be in UTF-8. This way the caller
|
||||
* doesn't have to perform any codeset conversions.
|
||||
*/
|
||||
typedef struct jq_util_input_state jq_util_input_state;
|
||||
typedef void (*jq_util_msg_cb)(void *, const char *);
|
||||
|
||||
jq_util_input_state *jq_util_input_init(jq_util_msg_cb, void *);
|
||||
void jq_util_input_set_parser(jq_util_input_state *, jv_parser *, int);
|
||||
void jq_util_input_free(jq_util_input_state **);
|
||||
void jq_util_input_add_input(jq_util_input_state *, const char *);
|
||||
int jq_util_input_errors(jq_util_input_state *);
|
||||
jv jq_util_input_next_input(jq_util_input_state *);
|
||||
jv jq_util_input_next_input_cb(jq_state *, void *);
|
||||
jv jq_util_input_get_position(jq_state*);
|
||||
jv jq_util_input_get_current_filename(jq_state*);
|
||||
jv jq_util_input_get_current_line(jq_state*);
|
||||
|
||||
#endif /* !JQ_H */
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#ifndef JQ_PARSER_H
|
||||
#define JQ_PARSER_H
|
||||
#include "locfile.h"
|
||||
#include "compile.h"
|
||||
|
||||
int jq_parse(struct locfile* source, block* answer);
|
||||
int jq_parse_library(struct locfile* locations, block* answer);
|
||||
|
||||
@@ -3,15 +3,23 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "jv.h"
|
||||
#include "execute.h"
|
||||
#include "jq.h"
|
||||
|
||||
static void jv_test();
|
||||
static void run_jq_tests();
|
||||
static void run_jq_tests(jv, int, FILE *);
|
||||
|
||||
|
||||
int jq_testsuite(int argc, char* argv[]) {
|
||||
int jq_testsuite(jv libdirs, int verbose, int argc, char* argv[]) {
|
||||
FILE *testdata = stdin;
|
||||
jv_test();
|
||||
run_jq_tests(stdin);
|
||||
if (argc > 0) {
|
||||
testdata = fopen(argv[0], "r");
|
||||
if (!testdata) {
|
||||
perror("fopen");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
run_jq_tests(libdirs, verbose, testdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -22,36 +30,123 @@ static int skipline(const char* buf) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void run_jq_tests(FILE *testdata) {
|
||||
static int checkerrormsg(const char* buf) {
|
||||
return strcmp(buf, "%%FAIL\n") == 0;
|
||||
}
|
||||
|
||||
static int checkfail(const char* buf) {
|
||||
return strcmp(buf, "%%FAIL\n") == 0 || strcmp(buf, "%%FAIL IGNORE MSG\n") == 0;
|
||||
}
|
||||
|
||||
struct err_data {
|
||||
char buf[4096];
|
||||
};
|
||||
|
||||
static void test_err_cb(void *data, jv e) {
|
||||
struct err_data *err_data = data;
|
||||
if (jv_get_kind(e) != JV_KIND_STRING)
|
||||
e = jv_dump_string(e, JV_PRINT_INVALID);
|
||||
if (!strncmp(jv_string_value(e), "jq: error", sizeof("jq: error") - 1))
|
||||
snprintf(err_data->buf, sizeof(err_data->buf), "%s", jv_string_value(e));
|
||||
if (strchr(err_data->buf, '\n'))
|
||||
*(strchr(err_data->buf, '\n')) = '\0';
|
||||
jv_free(e);
|
||||
}
|
||||
|
||||
static void run_jq_tests(jv lib_dirs, int verbose, FILE *testdata) {
|
||||
char prog[4096];
|
||||
char buf[4096];
|
||||
struct err_data err_msg;
|
||||
int tests = 0, passed = 0, invalid = 0;
|
||||
unsigned int lineno = 0;
|
||||
int must_fail = 0;
|
||||
int check_msg = 0;
|
||||
jq_state *jq = NULL;
|
||||
|
||||
jq = jq_init();
|
||||
assert(jq);
|
||||
if (jv_get_kind(lib_dirs) == JV_KIND_NULL)
|
||||
lib_dirs = jv_array();
|
||||
jq_set_attr(jq, jv_string("JQ_LIBRARY_PATH"), lib_dirs);
|
||||
|
||||
while (1) {
|
||||
if (!fgets(buf, sizeof(buf), testdata)) break;
|
||||
if (skipline(buf)) continue;
|
||||
if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = 0;
|
||||
printf("Testing %s\n", buf);
|
||||
if (!fgets(prog, sizeof(prog), testdata)) break;
|
||||
lineno++;
|
||||
if (skipline(prog)) continue;
|
||||
if (checkfail(prog)) {
|
||||
must_fail = 1;
|
||||
check_msg = checkerrormsg(prog);
|
||||
jq_set_error_cb(jq, test_err_cb, &err_msg);
|
||||
continue;
|
||||
}
|
||||
if (prog[strlen(prog)-1] == '\n') prog[strlen(prog)-1] = 0;
|
||||
printf("Testing '%s' at line number %u\n", prog, lineno);
|
||||
int pass = 1;
|
||||
tests++;
|
||||
struct bytecode* bc = jq_compile(buf);
|
||||
if (!bc) {invalid++; continue;}
|
||||
printf("Disassembly:\n");
|
||||
dump_disassembly(2, bc);
|
||||
printf("\n");
|
||||
fgets(buf, sizeof(buf), testdata);
|
||||
int compiled = jq_compile(jq, prog);
|
||||
|
||||
if (must_fail) {
|
||||
jq_set_error_cb(jq, NULL, NULL);
|
||||
if (!fgets(buf, sizeof(buf), testdata)) { invalid++; break; }
|
||||
lineno++;
|
||||
if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = 0;
|
||||
if (compiled) {
|
||||
printf("*** Test program compiled that should not have at line %u: %s\n", lineno, prog);
|
||||
must_fail = 0;
|
||||
check_msg = 0;
|
||||
invalid++;
|
||||
continue;
|
||||
}
|
||||
if (check_msg && strcmp(buf, err_msg.buf) != 0) {
|
||||
printf("*** Erroneous test program failed with wrong message (%s) at line %u: %s\n", err_msg.buf, lineno, prog);
|
||||
invalid++;
|
||||
} else {
|
||||
passed++;
|
||||
}
|
||||
must_fail = 0;
|
||||
check_msg = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!compiled) {
|
||||
printf("*** Test program failed to compile at line %u: %s\n", lineno, prog);
|
||||
invalid++;
|
||||
// skip past test data
|
||||
while (fgets(buf, sizeof(buf), testdata)) {
|
||||
lineno++;
|
||||
if (buf[0] == '\n' || (buf[0] == '\r' && buf[1] == '\n'))
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (verbose) {
|
||||
printf("Disassembly:\n");
|
||||
jq_dump_disassembly(jq, 2);
|
||||
printf("\n");
|
||||
}
|
||||
if (!fgets(buf, sizeof(buf), testdata)) { invalid++; break; }
|
||||
lineno++;
|
||||
jv input = jv_parse(buf);
|
||||
if (!jv_is_valid(input)){ invalid++; continue; }
|
||||
jq_init(bc, input, &jq, JQ_DEBUG_TRACE);
|
||||
if (!jv_is_valid(input)) {
|
||||
printf("*** Input is invalid on line %u: %s\n", lineno, buf);
|
||||
invalid++;
|
||||
continue;
|
||||
}
|
||||
jq_start(jq, input, verbose ? JQ_DEBUG_TRACE : 0);
|
||||
|
||||
while (fgets(buf, sizeof(buf), testdata)) {
|
||||
lineno++;
|
||||
if (skipline(buf)) break;
|
||||
jv expected = jv_parse(buf);
|
||||
if (!jv_is_valid(expected)){ invalid++; continue; }
|
||||
if (!jv_is_valid(expected)) {
|
||||
printf("*** Expected result is invalid on line %u: %s\n", lineno, buf);
|
||||
invalid++;
|
||||
continue;
|
||||
}
|
||||
jv actual = jq_next(jq);
|
||||
if (!jv_is_valid(actual)) {
|
||||
jv_free(actual);
|
||||
printf("*** Insufficient results\n");
|
||||
printf("*** Insufficient results for test at line number %u: %s\n", lineno, prog);
|
||||
pass = 0;
|
||||
break;
|
||||
} else if (!jv_equal(jv_copy(expected), jv_copy(actual))) {
|
||||
@@ -59,10 +154,10 @@ static void run_jq_tests(FILE *testdata) {
|
||||
jv_dump(jv_copy(expected), 0);
|
||||
printf(", but got ");
|
||||
jv_dump(jv_copy(actual), 0);
|
||||
printf("\n");
|
||||
printf(" for test at line number %u: %s\n", lineno, prog);
|
||||
pass = 0;
|
||||
}
|
||||
jv as_string = jv_dump_string(jv_copy(expected), rand() & ~JV_PRINT_COLOUR);
|
||||
jv as_string = jv_dump_string(jv_copy(expected), rand() & ~(JV_PRINT_COLOUR|JV_PRINT_REFCOUNT));
|
||||
jv reparsed = jv_parse_sized(jv_string_value(as_string), jv_string_length_bytes(jv_copy(as_string)));
|
||||
assert(jv_equal(jv_copy(expected), jv_copy(reparsed)));
|
||||
jv_free(as_string);
|
||||
@@ -75,29 +170,36 @@ static void run_jq_tests(FILE *testdata) {
|
||||
if (jv_is_valid(extra)) {
|
||||
printf("*** Superfluous result: ");
|
||||
jv_dump(extra, 0);
|
||||
printf("\n");
|
||||
printf(" for test at line number %u, %s\n", lineno, prog);
|
||||
pass = 0;
|
||||
} else {
|
||||
jv_free(extra);
|
||||
}
|
||||
}
|
||||
jq_teardown(&jq);
|
||||
bytecode_free(bc);
|
||||
passed+=pass;
|
||||
}
|
||||
jq_teardown(&jq);
|
||||
printf("%d of %d tests passed (%d malformed)\n", passed,tests,invalid);
|
||||
if (passed != tests) exit(1);
|
||||
}
|
||||
|
||||
|
||||
static void jv_test() {
|
||||
/// JSON parser regression tests
|
||||
{
|
||||
jv v = jv_parse("{\"a':\"12\"}");
|
||||
assert(jv_get_kind(v) == JV_KIND_INVALID);
|
||||
v = jv_invalid_get_msg(v);
|
||||
assert(strcmp(jv_string_value(v), "Expected separator between values at line 1, column 9 (while parsing '{\"a':\"12\"}')") == 0);
|
||||
jv_free(v);
|
||||
}
|
||||
/// Arrays and numbers
|
||||
{
|
||||
jv a = jv_array();
|
||||
assert(jv_get_kind(a) == JV_KIND_ARRAY);
|
||||
assert(jv_array_length(jv_copy(a)) == 0);
|
||||
assert(jv_array_length(jv_copy(a)) == 0);
|
||||
|
||||
|
||||
a = jv_array_append(a, jv_number(42));
|
||||
assert(jv_array_length(jv_copy(a)) == 1);
|
||||
assert(jv_number_value(jv_array_get(jv_copy(a), 0)) == 42);
|
||||
@@ -115,9 +217,9 @@ static void jv_test() {
|
||||
jv_free(a2);
|
||||
|
||||
|
||||
assert(a.val.nontrivial.ptr->count == 1);
|
||||
assert(jv_get_refcnt(a) == 1);
|
||||
a = jv_array_append(a, jv_copy(a));
|
||||
assert(a.val.nontrivial.ptr->count == 1);
|
||||
assert(jv_get_refcnt(a) == 1);
|
||||
|
||||
assert(jv_array_length(jv_copy(a)) == 2);
|
||||
assert(jv_number_value(jv_array_get(jv_copy(a), 0)) == 42);
|
||||
@@ -150,9 +252,9 @@ static void jv_test() {
|
||||
|
||||
jv_free(subarray);
|
||||
|
||||
void* before = sub2.val.nontrivial.ptr;
|
||||
void* before = sub2.u.ptr;
|
||||
sub2 = jv_array_append(sub2, jv_number(200));
|
||||
void* after = sub2.val.nontrivial.ptr;
|
||||
void* after = sub2.u.ptr;
|
||||
assert(before == after);
|
||||
jv_free(sub2);
|
||||
|
||||
@@ -172,8 +274,10 @@ static void jv_test() {
|
||||
a4 = jv_array_slice(a4, 0, 1);
|
||||
assert(jv_array_length(jv_copy(a4)) == 1);
|
||||
a4 = jv_array_append(a4, jv_number(4));
|
||||
assert(jv_array_length(a4) == 2);
|
||||
assert(jv_array_length(a5) == 2);
|
||||
assert(jv_array_length(jv_copy(a4)) == 2);
|
||||
assert(jv_array_length(jv_copy(a5)) == 2);
|
||||
jv_free(a4);
|
||||
jv_free(a5);
|
||||
|
||||
|
||||
assert(jv_array_length(jv_copy(a)) == 2);
|
||||
@@ -181,7 +285,7 @@ static void jv_test() {
|
||||
assert(jv_array_length(jv_array_get(jv_copy(a), 1)) == 1);
|
||||
|
||||
|
||||
jv_dump(jv_copy(a), 0); printf("\n");
|
||||
//jv_dump(jv_copy(a), 0); printf("\n");
|
||||
jv_free(a);
|
||||
}
|
||||
|
||||
@@ -191,16 +295,18 @@ static void jv_test() {
|
||||
assert(jv_equal(jv_string("foo"), jv_string_sized("foo", 3)));
|
||||
char nasty[] = "foo\0";
|
||||
jv shortstr = jv_string(nasty), longstr = jv_string_sized(nasty, sizeof(nasty));
|
||||
assert(jv_string_length_bytes(shortstr) == (int)strlen(nasty));
|
||||
assert(jv_string_length_bytes(longstr) == (int)sizeof(nasty));
|
||||
assert(jv_string_length_bytes(jv_copy(shortstr)) == (int)strlen(nasty));
|
||||
assert(jv_string_length_bytes(jv_copy(longstr)) == (int)sizeof(nasty));
|
||||
jv_free(shortstr);
|
||||
jv_free(longstr);
|
||||
|
||||
|
||||
|
||||
char a1s[] = "hello", a2s[] = "hello", bs[] = "goodbye";
|
||||
jv a1 = jv_string(a1s), a2 = jv_string(a2s), b = jv_string(bs);
|
||||
assert(jv_equal(jv_copy(a1), jv_copy(a2)));
|
||||
assert(jv_equal(jv_copy(a2), jv_copy(a1)));
|
||||
assert(!jv_equal(jv_copy(a1), jv_copy(b)));
|
||||
|
||||
|
||||
assert(jv_string_hash(jv_copy(a1)) == jv_string_hash(jv_copy(a1)));
|
||||
assert(jv_string_hash(jv_copy(a1)) == jv_string_hash(jv_copy(a2)));
|
||||
assert(jv_string_hash(jv_copy(b)) != jv_string_hash(jv_copy(a1)));
|
||||
@@ -234,8 +340,7 @@ static void jv_test() {
|
||||
jv_free(o1);
|
||||
assert(jv_number_value(jv_object_get(jv_copy(o2), jv_string("bar"))) == 240);
|
||||
|
||||
jv_dump(jv_copy(o2), 0); printf("\n");
|
||||
|
||||
//jv_dump(jv_copy(o2), 0); printf("\n");
|
||||
jv_free(o2);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,9 @@
|
||||
#ifndef JV_H
|
||||
#define JV_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef enum {
|
||||
JV_KIND_INVALID,
|
||||
@@ -18,21 +16,19 @@ typedef enum {
|
||||
JV_KIND_OBJECT
|
||||
} jv_kind;
|
||||
|
||||
typedef struct {
|
||||
size_t count;
|
||||
} jv_refcnt;
|
||||
|
||||
typedef struct{
|
||||
jv_refcnt* ptr;
|
||||
int i[2];
|
||||
} jv_nontrivial;
|
||||
struct jv_refcnt;
|
||||
|
||||
/* All of the fields of this struct are private.
|
||||
Really. Do not play with them. */
|
||||
typedef struct {
|
||||
jv_kind kind;
|
||||
unsigned char kind_flags;
|
||||
unsigned char pad_;
|
||||
unsigned short offset; /* array offsets */
|
||||
int size;
|
||||
union {
|
||||
struct jv_refcnt* ptr;
|
||||
double number;
|
||||
jv_nontrivial nontrivial;
|
||||
} val;
|
||||
} u;
|
||||
} jv;
|
||||
|
||||
/*
|
||||
@@ -47,24 +43,28 @@ 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_get_refcnt(jv);
|
||||
|
||||
int jv_equal(jv, jv);
|
||||
int jv_identical(jv, jv);
|
||||
int jv_contains(jv, jv);
|
||||
|
||||
jv jv_invalid();
|
||||
jv jv_invalid(void);
|
||||
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_null(void);
|
||||
jv jv_true(void);
|
||||
jv jv_false(void);
|
||||
jv jv_bool(int);
|
||||
|
||||
jv jv_number(double);
|
||||
double jv_number_value(jv);
|
||||
int jv_is_integer(jv);
|
||||
|
||||
jv jv_array();
|
||||
jv jv_array(void);
|
||||
jv jv_array_sized(int);
|
||||
int jv_array_length(jv);
|
||||
jv jv_array_get(jv, int);
|
||||
@@ -72,6 +72,7 @@ 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);
|
||||
jv jv_array_indexes(jv, jv);
|
||||
#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) \
|
||||
@@ -80,23 +81,53 @@ jv jv_array_slice(jv, int, int);
|
||||
(x = jv_array_get(jv_copy(a), i), 1) : 0; \
|
||||
i++)
|
||||
|
||||
#define JV_ARRAY_1(e) (jv_array_append(jv_array(),e))
|
||||
#define JV_ARRAY_2(e1,e2) (jv_array_append(JV_ARRAY_1(e1),e2))
|
||||
#define JV_ARRAY_3(e1,e2,e3) (jv_array_append(JV_ARRAY_2(e1,e2),e3))
|
||||
#define JV_ARRAY_4(e1,e2,e3,e4) (jv_array_append(JV_ARRAY_3(e1,e2,e3),e4))
|
||||
#define JV_ARRAY_5(e1,e2,e3,e4,e5) (jv_array_append(JV_ARRAY_4(e1,e2,e3,e4),e5))
|
||||
#define JV_ARRAY_6(e1,e2,e3,e4,e5,e6) (jv_array_append(JV_ARRAY_5(e1,e2,e3,e4,e5),e6))
|
||||
#define JV_ARRAY_7(e1,e2,e3,e4,e5,e6,e7) (jv_array_append(JV_ARRAY_6(e1,e2,e3,e4,e5,e6),e7))
|
||||
#define JV_ARRAY_8(e1,e2,e3,e4,e5,e6,e7,e8) (jv_array_append(JV_ARRAY_7(e1,e2,e3,e4,e5,e6,e7),e8))
|
||||
#define JV_ARRAY_9(e1,e2,e3,e4,e5,e6,e7,e8,e9) (jv_array_append(JV_ARRAY_8(e1,e2,e3,e4,e5,e6,e7,e8),e9))
|
||||
#define JV_ARRAY_IDX(_1,_2,_3,_4,_5,_6,_7,_8,_9,NAME,...) NAME
|
||||
#define JV_ARRAY(...) \
|
||||
JV_ARRAY_IDX(__VA_ARGS__, JV_ARRAY_9, JV_ARRAY_8, JV_ARRAY_7, JV_ARRAY_6, JV_ARRAY_5, JV_ARRAY_4, JV_ARRAY_3, JV_ARRAY_2, JV_ARRAY_1)(__VA_ARGS__)
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define JV_PRINTF_LIKE(fmt_arg_num, args_num) \
|
||||
__attribute__ ((__format__( __printf__, fmt_arg_num, args_num)))
|
||||
#define JV_VPRINTF_LIKE(fmt_arg_num) \
|
||||
__attribute__ ((__format__( __printf__, fmt_arg_num, 0)))
|
||||
#endif
|
||||
|
||||
|
||||
jv jv_string(const char*);
|
||||
jv jv_string_sized(const char*, int);
|
||||
jv jv_string_empty(int len);
|
||||
int jv_string_length_bytes(jv);
|
||||
int jv_string_length_codepoints(jv);
|
||||
uint32_t jv_string_hash(jv);
|
||||
unsigned long jv_string_hash(jv);
|
||||
const char* jv_string_value(jv);
|
||||
jv jv_string_indexes(jv j, jv k);
|
||||
jv jv_string_slice(jv j, int start, int end);
|
||||
jv jv_string_concat(jv, jv);
|
||||
jv jv_string_fmt(const char*, ...);
|
||||
jv jv_string_vfmt(const char*, va_list) JV_VPRINTF_LIKE(1);
|
||||
jv jv_string_fmt(const char*, ...) JV_PRINTF_LIKE(1, 2);
|
||||
jv jv_string_append_codepoint(jv a, uint32_t c);
|
||||
jv jv_string_append_buf(jv a, const char* buf, int len);
|
||||
jv jv_string_append_str(jv a, const char* str);
|
||||
jv jv_string_split(jv j, jv sep);
|
||||
jv jv_string_explode(jv j);
|
||||
jv jv_string_implode(jv j);
|
||||
|
||||
jv jv_object();
|
||||
jv jv_object(void);
|
||||
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);
|
||||
jv jv_object_merge_recursive(jv, jv);
|
||||
|
||||
int jv_object_iter(jv);
|
||||
int jv_object_iter_next(jv, int);
|
||||
@@ -112,25 +143,76 @@ jv jv_object_iter_value(jv, int);
|
||||
1) \
|
||||
: 0; \
|
||||
jv_i__ = jv_object_iter_next(t, jv_i__)) \
|
||||
|
||||
|
||||
#define JV_OBJECT_1(k) (jv_object_set(jv_object(),(k),jv_null()))
|
||||
#define JV_OBJECT_2(k1,v1) (jv_object_set(jv_object(),(k1),(v1)))
|
||||
#define JV_OBJECT_3(k1,v1,k2) (jv_object_set(JV_OBJECT_2(k1,v1),k2,jv_null()))
|
||||
#define JV_OBJECT_4(k1,v1,k2,v2) (jv_object_set(JV_OBJECT_2(k1,v1),k2,v2))
|
||||
#define JV_OBJECT_5(k1,v1,k2,v2,k3) (jv_object_set(JV_OBJECT_4(k1,v1,k2,v2),k3,jv_null))
|
||||
#define JV_OBJECT_6(k1,v1,k2,v2,k3,v3) (jv_object_set(JV_OBJECT_4(k1,v1,k2,v2),k3,v3))
|
||||
#define JV_OBJECT_7(k1,v1,k2,v2,k3,v3,k4) (jv_object_set(JV_OBJECT_6(k1,v1,k2,v2,k3,v3),k4,jv_null()))
|
||||
#define JV_OBJECT_8(k1,v1,k2,v2,k3,v3,k4,v4) (jv_object_set(JV_OBJECT_6(k1,v1,k2,v2,k3,v3),k4,v4))
|
||||
#define JV_OBJECT_IDX(_1,_2,_3,_4,_5,_6,_7,_8,NAME,...) NAME
|
||||
#define JV_OBJECT(...) \
|
||||
JV_OBJECT_IDX(__VA_ARGS__, JV_OBJECT_8, JV_OBJECT_7, JV_OBJECT_6, JV_OBJECT_5, JV_OBJECT_4, JV_OBJECT_3, JV_OBJECT_2, JV_OBJECT_1)(__VA_ARGS__)
|
||||
|
||||
|
||||
|
||||
int jv_get_refcnt(jv);
|
||||
|
||||
enum { JV_PRINT_PRETTY = 1, JV_PRINT_ASCII = 2, JV_PRINT_COLOUR = 4 };
|
||||
enum jv_print_flags {
|
||||
JV_PRINT_PRETTY = 1,
|
||||
JV_PRINT_ASCII = 2,
|
||||
JV_PRINT_COLOUR = 4,
|
||||
JV_PRINT_SORTED = 8,
|
||||
JV_PRINT_INVALID = 16,
|
||||
JV_PRINT_REFCOUNT = 32,
|
||||
JV_PRINT_TAB = 64,
|
||||
JV_PRINT_ISATTY = 128,
|
||||
JV_PRINT_SPACE0 = 256,
|
||||
JV_PRINT_SPACE1 = 512,
|
||||
JV_PRINT_SPACE2 = 1024,
|
||||
};
|
||||
#define JV_PRINT_INDENT_FLAGS(n) \
|
||||
((n) < 0 || (n) > 7 ? JV_PRINT_TAB | JV_PRINT_PRETTY : (n) == 0 ? 0 : (n) << 8 | JV_PRINT_PRETTY)
|
||||
void jv_dumpf(jv, FILE *f, int flags);
|
||||
void jv_dump(jv, int flags);
|
||||
void jv_show(jv, int flags);
|
||||
jv jv_dump_string(jv, int flags);
|
||||
char *jv_dump_string_trunc(jv x, char *outbuf, size_t bufsize);
|
||||
|
||||
enum {
|
||||
JV_PARSE_SEQ = 1,
|
||||
JV_PARSE_STREAMING = 2,
|
||||
JV_PARSE_STREAM_ERRORS = 4,
|
||||
};
|
||||
|
||||
jv jv_parse(const char* string);
|
||||
jv jv_parse_sized(const char* string, int length);
|
||||
|
||||
typedef void (*jv_nomem_handler_f)(void *);
|
||||
void jv_nomem_handler(jv_nomem_handler_f, void *);
|
||||
|
||||
jv jv_load_file(const char *, int);
|
||||
|
||||
typedef struct jv_parser jv_parser;
|
||||
jv_parser* jv_parser_new(int);
|
||||
void jv_parser_set_buf(jv_parser*, const char*, int, int);
|
||||
int jv_parser_remaining(jv_parser*);
|
||||
jv jv_parser_next(jv_parser*);
|
||||
void jv_parser_free(jv_parser*);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
jv jv_get(jv, jv);
|
||||
jv jv_set(jv, jv, jv);
|
||||
jv jv_has(jv, jv);
|
||||
jv jv_setpath(jv, jv, jv);
|
||||
jv jv_getpath(jv, jv);
|
||||
jv jv_delpaths(jv, jv);
|
||||
jv jv_keys(jv /*object or array*/);
|
||||
jv jv_keys_unsorted(jv /*object or array*/);
|
||||
int jv_cmp(jv, jv);
|
||||
jv jv_group(jv, jv);
|
||||
jv jv_sort(jv, jv);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
+142
@@ -1,12 +1,123 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "jv_alloc.h"
|
||||
|
||||
struct nomem_handler {
|
||||
jv_nomem_handler_f handler;
|
||||
void *data;
|
||||
};
|
||||
|
||||
#if !defined(HAVE_PTHREAD_KEY_CREATE) || \
|
||||
!defined(HAVE_PTHREAD_ONCE) || \
|
||||
!defined(HAVE_ATEXIT)
|
||||
|
||||
/* Try thread-local storage? */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* Visual C++: yes */
|
||||
static __declspec(thread) struct nomem_handler nomem_handler;
|
||||
#define USE_TLS
|
||||
#else
|
||||
#ifdef HAVE___THREAD
|
||||
/* GCC and friends: yes */
|
||||
static __thread struct nomem_handler nomem_handler;
|
||||
#define USE_TLS
|
||||
#endif /* HAVE___THREAD */
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#endif /* !HAVE_PTHREAD_KEY_CREATE */
|
||||
|
||||
#ifdef USE_TLS
|
||||
void jv_nomem_handler(jv_nomem_handler_f handler, void *data) {
|
||||
nomem_handler.handler = handler;
|
||||
}
|
||||
|
||||
static void memory_exhausted() {
|
||||
if (nomem_handler.handler)
|
||||
nomem_handler.handler(nomem_handler.data); // Maybe handler() will longjmp() to safety
|
||||
// Or not
|
||||
fprintf(stderr, "error: cannot allocate memory\n");
|
||||
abort();
|
||||
}
|
||||
#else /* USE_TLS */
|
||||
|
||||
#ifdef HAVE_PTHREAD_KEY_CREATE
|
||||
#include <pthread.h>
|
||||
|
||||
pthread_key_t nomem_handler_key;
|
||||
pthread_once_t mem_once = PTHREAD_ONCE_INIT;
|
||||
|
||||
static void tsd_fini(void) {
|
||||
struct nomem_handler *nomem_handler;
|
||||
nomem_handler = pthread_getspecific(nomem_handler_key);
|
||||
if (nomem_handler) {
|
||||
(void) pthread_setspecific(nomem_handler_key, NULL);
|
||||
free(nomem_handler);
|
||||
}
|
||||
}
|
||||
|
||||
static void tsd_init(void) {
|
||||
if (pthread_key_create(&nomem_handler_key, NULL) != 0) {
|
||||
fprintf(stderr, "error: cannot create thread specific key");
|
||||
abort();
|
||||
}
|
||||
if (atexit(tsd_fini) != 0) {
|
||||
fprintf(stderr, "error: cannot set an exit handler");
|
||||
abort();
|
||||
}
|
||||
struct nomem_handler *nomem_handler = calloc(1, sizeof(struct nomem_handler));
|
||||
if (pthread_setspecific(nomem_handler_key, nomem_handler) != 0) {
|
||||
fprintf(stderr, "error: cannot set thread specific data");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void jv_nomem_handler(jv_nomem_handler_f handler, void *data) {
|
||||
pthread_once(&mem_once, tsd_init); // cannot fail
|
||||
struct nomem_handler *nomem_handler;
|
||||
|
||||
nomem_handler = pthread_getspecific(nomem_handler_key);
|
||||
if (nomem_handler == NULL) {
|
||||
handler(data);
|
||||
fprintf(stderr, "error: cannot allocate memory\n");
|
||||
abort();
|
||||
}
|
||||
nomem_handler->handler = handler;
|
||||
nomem_handler->data = data;
|
||||
}
|
||||
|
||||
static void memory_exhausted() {
|
||||
struct nomem_handler *nomem_handler;
|
||||
|
||||
pthread_once(&mem_once, tsd_init);
|
||||
nomem_handler = pthread_getspecific(nomem_handler_key);
|
||||
if (nomem_handler)
|
||||
nomem_handler->handler(nomem_handler->data); // Maybe handler() will longjmp() to safety
|
||||
// Or not
|
||||
fprintf(stderr, "error: cannot allocate memory\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* No thread-local storage of any kind that we know how to handle */
|
||||
|
||||
static struct nomem_handler nomem_handler;
|
||||
void jv_nomem_handler(jv_nomem_handler_f handler, void *data) {
|
||||
nomem_handler.handler = handler;
|
||||
nomem_handler.data = data;
|
||||
}
|
||||
|
||||
static void memory_exhausted() {
|
||||
fprintf(stderr, "error: cannot allocate memory\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
#endif /* HAVE_PTHREAD_KEY_CREATE */
|
||||
#endif /* USE_TLS */
|
||||
|
||||
|
||||
void* jv_mem_alloc(size_t sz) {
|
||||
void* p = malloc(sz);
|
||||
if (!p) {
|
||||
@@ -15,6 +126,34 @@ void* jv_mem_alloc(size_t sz) {
|
||||
return p;
|
||||
}
|
||||
|
||||
void* jv_mem_alloc_unguarded(size_t sz) {
|
||||
return malloc(sz);
|
||||
}
|
||||
|
||||
void* jv_mem_calloc(size_t nemb, size_t sz) {
|
||||
void* p = calloc(nemb, sz);
|
||||
if (!p) {
|
||||
memory_exhausted();
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void* jv_mem_calloc_unguarded(size_t nemb, size_t sz) {
|
||||
return calloc(nemb, sz);
|
||||
}
|
||||
|
||||
char* jv_mem_strdup(const char *s) {
|
||||
char *p = strdup(s);
|
||||
if (!p) {
|
||||
memory_exhausted();
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
char* jv_mem_strdup_unguarded(const char *s) {
|
||||
return strdup(s);
|
||||
}
|
||||
|
||||
void jv_mem_free(void* p) {
|
||||
free(p);
|
||||
}
|
||||
@@ -30,8 +169,11 @@ void* jv_mem_realloc(void* p, size_t sz) {
|
||||
#ifndef NDEBUG
|
||||
volatile char jv_mem_uninitialised;
|
||||
__attribute__((constructor)) void jv_mem_uninit_setup(){
|
||||
// ignore warning that this reads uninitialized memory - that's the point!
|
||||
#ifndef __clang_analyzer__
|
||||
char* p = malloc(1);
|
||||
jv_mem_uninitialised = *p;
|
||||
free(p);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@@ -2,6 +2,7 @@
|
||||
#define JV_ALLOC_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include "jv.h"
|
||||
|
||||
#ifndef NDEBUG
|
||||
extern volatile char jv_mem_uninitialised;
|
||||
@@ -15,6 +16,11 @@ static void jv_mem_invalidate(void* mem, size_t n) {
|
||||
}
|
||||
|
||||
void* jv_mem_alloc(size_t);
|
||||
void* jv_mem_alloc_unguarded(size_t);
|
||||
void* jv_mem_calloc(size_t, size_t);
|
||||
void* jv_mem_calloc_unguarded(size_t, size_t);
|
||||
char* jv_mem_strdup(const char *);
|
||||
char* jv_mem_strdup_unguarded(const char *);
|
||||
void jv_mem_free(void*);
|
||||
__attribute__((warn_unused_result)) void* jv_mem_realloc(void*, size_t);
|
||||
|
||||
|
||||
@@ -1,17 +1,25 @@
|
||||
#include "jv_aux.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "jv_alloc.h"
|
||||
|
||||
static int parse_slice(jv array, jv slice, int* pstart, int* pend) {
|
||||
static int parse_slice(jv j, jv slice, int* pstart, int* pend) {
|
||||
// Array slices
|
||||
int len = jv_array_length(jv_copy(array));
|
||||
jv start_jv = jv_object_get(jv_copy(slice), jv_string("start"));
|
||||
jv end_jv = jv_object_get(slice, jv_string("end"));
|
||||
if (jv_get_kind(start_jv) == JV_KIND_NULL) {
|
||||
jv_free(start_jv);
|
||||
start_jv = jv_number(0);
|
||||
}
|
||||
int len;
|
||||
if (jv_get_kind(j) == JV_KIND_ARRAY) {
|
||||
len = jv_array_length(j);
|
||||
} else if (jv_get_kind(j) == JV_KIND_STRING) {
|
||||
len = jv_string_length_codepoints(j);
|
||||
} else {
|
||||
jv_free(j);
|
||||
return 0;
|
||||
}
|
||||
if (jv_get_kind(end_jv) == JV_KIND_NULL) {
|
||||
jv_free(end_jv);
|
||||
end_jv = jv_number(len);
|
||||
@@ -22,13 +30,18 @@ static int parse_slice(jv array, jv slice, int* pstart, int* pend) {
|
||||
jv_free(end_jv);
|
||||
return 0;
|
||||
} else {
|
||||
int start = (int)jv_number_value(start_jv);
|
||||
int end = (int)jv_number_value(end_jv);
|
||||
if (start < 0) start = len + start;
|
||||
if (end < 0) end = len + end;
|
||||
double dstart = jv_number_value(start_jv);
|
||||
double dend = jv_number_value(end_jv);
|
||||
if (dstart < 0) dstart += len;
|
||||
if (dend < 0) dend += len;
|
||||
if (dstart < 0) dstart = 0;
|
||||
if (dstart > len) dstart = len;
|
||||
|
||||
int start = (int)dstart;
|
||||
int end = (dend > len) ? len : (int)dend;
|
||||
// Ends are exclusive but e.g. 1 < 1.5 so :1.5 should be :2 not :1
|
||||
if(end < dend) end += 1;
|
||||
|
||||
if (start < 0) start = 0;
|
||||
if (start > len) start = len;
|
||||
if (end > len) end = len;
|
||||
if (end < start) end = start;
|
||||
assert(0 <= start && start <= end && end <= len);
|
||||
@@ -47,31 +60,60 @@ jv jv_get(jv t, jv k) {
|
||||
v = jv_null();
|
||||
}
|
||||
} else if (jv_get_kind(t) == JV_KIND_ARRAY && jv_get_kind(k) == JV_KIND_NUMBER) {
|
||||
// FIXME: don't do lookup for noninteger index
|
||||
v = jv_array_get(t, (int)jv_number_value(k));
|
||||
if (!jv_is_valid(v)) {
|
||||
jv_free(v);
|
||||
if(jv_is_integer(k)){
|
||||
int idx = (int)jv_number_value(k);
|
||||
if (idx < 0)
|
||||
idx += jv_array_length(jv_copy(t));
|
||||
v = jv_array_get(t, idx);
|
||||
if (!jv_is_valid(v)) {
|
||||
jv_free(v);
|
||||
v = jv_null();
|
||||
}
|
||||
} else {
|
||||
jv_free(t);
|
||||
jv_free(k);
|
||||
v = jv_null();
|
||||
}
|
||||
} else if (jv_get_kind(t) == JV_KIND_ARRAY && jv_get_kind(k) == JV_KIND_OBJECT) {
|
||||
int start, end;
|
||||
if (parse_slice(t, k, &start, &end)) {
|
||||
if (parse_slice(jv_copy(t), k, &start, &end)) {
|
||||
v = jv_array_slice(t, start, end);
|
||||
} else {
|
||||
jv_free(t);
|
||||
v = jv_invalid_with_msg(jv_string_fmt("Start and end indices of an array slice must be numbers"));
|
||||
}
|
||||
} else if (jv_get_kind(t) == JV_KIND_STRING && jv_get_kind(k) == JV_KIND_OBJECT) {
|
||||
int start, end;
|
||||
if (parse_slice(jv_copy(t), k, &start, &end)) {
|
||||
v = jv_string_slice(t, start, end);
|
||||
} else {
|
||||
v = jv_invalid_with_msg(jv_string_fmt("Start and end indices of an string slice must be numbers"));
|
||||
jv_free(t);
|
||||
}
|
||||
} else if (jv_get_kind(t) == JV_KIND_NULL &&
|
||||
(jv_get_kind(k) == JV_KIND_STRING ||
|
||||
jv_get_kind(k) == JV_KIND_NUMBER ||
|
||||
} else if (jv_get_kind(t) == JV_KIND_ARRAY && jv_get_kind(k) == JV_KIND_ARRAY) {
|
||||
v = jv_array_indexes(t, k);
|
||||
} else if (jv_get_kind(t) == JV_KIND_NULL &&
|
||||
(jv_get_kind(k) == JV_KIND_STRING ||
|
||||
jv_get_kind(k) == JV_KIND_NUMBER ||
|
||||
jv_get_kind(k) == JV_KIND_OBJECT)) {
|
||||
jv_free(t);
|
||||
jv_free(k);
|
||||
v = jv_null();
|
||||
} else {
|
||||
v = jv_invalid_with_msg(jv_string_fmt("Cannot index %s with %s",
|
||||
jv_kind_name(jv_get_kind(t)),
|
||||
jv_kind_name(jv_get_kind(k))));
|
||||
/*
|
||||
* If k is a short string it's probably from a jq .foo expression or
|
||||
* similar, in which case putting it in the invalid msg may help the
|
||||
* user. The length 30 is arbitrary.
|
||||
*/
|
||||
if (jv_get_kind(k) == JV_KIND_STRING && jv_string_length_bytes(jv_copy(k)) < 30) {
|
||||
v = jv_invalid_with_msg(jv_string_fmt("Cannot index %s with string \"%s\"",
|
||||
jv_kind_name(jv_get_kind(t)),
|
||||
jv_string_value(k)));
|
||||
} else {
|
||||
v = jv_invalid_with_msg(jv_string_fmt("Cannot index %s with %s",
|
||||
jv_kind_name(jv_get_kind(t)),
|
||||
jv_kind_name(jv_get_kind(k))));
|
||||
}
|
||||
jv_free(t);
|
||||
jv_free(k);
|
||||
}
|
||||
@@ -85,7 +127,7 @@ jv jv_set(jv t, jv k, jv v) {
|
||||
return v;
|
||||
}
|
||||
int isnull = jv_get_kind(t) == JV_KIND_NULL;
|
||||
if (jv_get_kind(k) == JV_KIND_STRING &&
|
||||
if (jv_get_kind(k) == JV_KIND_STRING &&
|
||||
(jv_get_kind(t) == JV_KIND_OBJECT || isnull)) {
|
||||
if (isnull) t = jv_object();
|
||||
t = jv_object_set(t, k, v);
|
||||
@@ -97,7 +139,7 @@ jv jv_set(jv t, jv k, jv v) {
|
||||
(jv_get_kind(t) == JV_KIND_ARRAY || isnull)) {
|
||||
if (isnull) t = jv_array();
|
||||
int start, end;
|
||||
if (parse_slice(t, k, &start, &end)) {
|
||||
if (parse_slice(jv_copy(t), k, &start, &end)) {
|
||||
if (jv_get_kind(v) == JV_KIND_ARRAY) {
|
||||
int array_len = jv_array_length(jv_copy(t));
|
||||
assert(0 <= start && start <= end && end <= array_len);
|
||||
@@ -128,7 +170,6 @@ jv jv_set(jv t, jv k, jv v) {
|
||||
}
|
||||
} else {
|
||||
jv_free(t);
|
||||
jv_free(k);
|
||||
jv_free(v);
|
||||
t = jv_invalid_with_msg(jv_string_fmt("Start and end indices of an array slice must be numbers"));
|
||||
}
|
||||
@@ -176,7 +217,7 @@ jv jv_has(jv t, jv k) {
|
||||
jv jv_dels(jv t, jv keys) {
|
||||
assert(jv_get_kind(keys) == JV_KIND_ARRAY);
|
||||
assert(jv_is_valid(t));
|
||||
|
||||
|
||||
if (jv_get_kind(t) == JV_KIND_NULL || jv_array_length(jv_copy(keys)) == 0) {
|
||||
// no change
|
||||
} else if (jv_get_kind(t) == JV_KIND_ARRAY) {
|
||||
@@ -190,12 +231,11 @@ jv jv_dels(jv t, jv keys) {
|
||||
keys = jv_array_append(keys, key);
|
||||
} else if (jv_get_kind(key) == JV_KIND_OBJECT) {
|
||||
int start, end;
|
||||
if (parse_slice(t, key, &start, &end)) {
|
||||
if (parse_slice(jv_copy(t), key, &start, &end)) {
|
||||
starts = jv_array_append(starts, jv_number(start));
|
||||
ends = jv_array_append(ends, jv_number(end));
|
||||
} else {
|
||||
jv_free(new_array);
|
||||
jv_free(key);
|
||||
new_array = jv_invalid_with_msg(jv_string_fmt("Start and end indices of an array slice must be numbers"));
|
||||
goto arr_out;
|
||||
}
|
||||
@@ -247,7 +287,7 @@ jv jv_dels(jv t, jv keys) {
|
||||
jv_free(k);
|
||||
break;
|
||||
}
|
||||
t = jv_object_delete(t, k);
|
||||
t = jv_object_delete(t, k);
|
||||
}
|
||||
} else {
|
||||
jv err = jv_invalid_with_msg(jv_string_fmt("Cannot delete fields from %s",
|
||||
@@ -278,7 +318,7 @@ jv jv_setpath(jv root, jv path, jv value) {
|
||||
}
|
||||
jv pathcurr = jv_array_get(jv_copy(path), 0);
|
||||
jv pathrest = jv_array_slice(path, 1, jv_array_length(jv_copy(path)));
|
||||
return jv_set(root, pathcurr,
|
||||
return jv_set(root, pathcurr,
|
||||
jv_setpath(jv_get(jv_copy(root), jv_copy(pathcurr)), pathrest, value));
|
||||
}
|
||||
|
||||
@@ -344,7 +384,7 @@ static jv delpaths_sorted(jv object, jv paths, int start) {
|
||||
jv_free(paths);
|
||||
if (jv_is_valid(object))
|
||||
object = jv_dels(object, delkeys);
|
||||
else
|
||||
else
|
||||
jv_free(delkeys);
|
||||
return object;
|
||||
}
|
||||
@@ -388,6 +428,18 @@ static int string_cmp(const void* pa, const void* pb){
|
||||
return r;
|
||||
}
|
||||
|
||||
jv jv_keys_unsorted(jv x) {
|
||||
if (jv_get_kind(x) != JV_KIND_OBJECT)
|
||||
return jv_keys(x);
|
||||
jv answer = jv_array_sized(jv_object_length(jv_copy(x)));
|
||||
jv_object_foreach(x, key, value) {
|
||||
answer = jv_array_append(answer, key);
|
||||
jv_free(value);
|
||||
}
|
||||
jv_free(x);
|
||||
return answer;
|
||||
}
|
||||
|
||||
jv jv_keys(jv x) {
|
||||
if (jv_get_kind(x) == JV_KIND_OBJECT) {
|
||||
int nkeys = jv_object_length(jv_copy(x));
|
||||
@@ -438,7 +490,7 @@ int jv_cmp(jv a, jv b) {
|
||||
|
||||
case JV_KIND_NUMBER: {
|
||||
double da = jv_number_value(a), db = jv_number_value(b);
|
||||
|
||||
|
||||
// handle NaN as though it were null
|
||||
if (da != da) r = jv_cmp(jv_null(), jv_number(db));
|
||||
else if (db != db) r = jv_cmp(jv_number(da), jv_null());
|
||||
@@ -545,21 +597,23 @@ jv jv_group(jv objects, jv keys) {
|
||||
int n = jv_array_length(jv_copy(objects));
|
||||
struct sort_entry* entries = sort_items(objects, keys);
|
||||
jv ret = jv_array();
|
||||
jv curr_key = entries[0].key;
|
||||
jv group = jv_array_append(jv_array(), entries[0].object);
|
||||
for (int i = 1; i < n; i++) {
|
||||
if (jv_equal(jv_copy(curr_key), jv_copy(entries[i].key))) {
|
||||
jv_free(entries[i].key);
|
||||
} else {
|
||||
jv_free(curr_key);
|
||||
curr_key = entries[i].key;
|
||||
ret = jv_array_append(ret, group);
|
||||
group = jv_array();
|
||||
if (n > 0) {
|
||||
jv curr_key = entries[0].key;
|
||||
jv group = jv_array_append(jv_array(), entries[0].object);
|
||||
for (int i = 1; i < n; i++) {
|
||||
if (jv_equal(jv_copy(curr_key), jv_copy(entries[i].key))) {
|
||||
jv_free(entries[i].key);
|
||||
} else {
|
||||
jv_free(curr_key);
|
||||
curr_key = entries[i].key;
|
||||
ret = jv_array_append(ret, group);
|
||||
group = jv_array();
|
||||
}
|
||||
group = jv_array_append(group, entries[i].object);
|
||||
}
|
||||
group = jv_array_append(group, entries[i].object);
|
||||
jv_free(curr_key);
|
||||
ret = jv_array_append(ret, group);
|
||||
}
|
||||
jv_free(curr_key);
|
||||
ret = jv_array_append(ret, group);
|
||||
jv_mem_free(entries);
|
||||
return ret;
|
||||
}
|
||||
@@ -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
|
||||
@@ -187,7 +187,6 @@
|
||||
* used for input more than STRTOD_DIGLIM digits long (default 40).
|
||||
*/
|
||||
|
||||
#define IEEE_8087
|
||||
#define NO_ERRNO
|
||||
#define NO_HEX_FP
|
||||
#define No_Hex_NaN
|
||||
@@ -526,7 +525,7 @@ void jvp_dtoa_context_init(struct dtoa_context* C) {
|
||||
}
|
||||
C->p5s = 0;
|
||||
}
|
||||
|
||||
|
||||
static Bigint *
|
||||
Balloc(struct dtoa_context* C, int k)
|
||||
{
|
||||
@@ -4225,7 +4224,7 @@ jvp_dtoa
|
||||
while((*b++ = *s++));
|
||||
goto done0;
|
||||
}
|
||||
if (decpt <= -4 || decpt > se - s + 5) {
|
||||
if (decpt <= -4 || decpt > se - s + 15) {
|
||||
*b++ = *s++;
|
||||
if (*s) {
|
||||
*b++ = '.';
|
||||
|
||||
@@ -17,6 +17,6 @@ double jvp_strtod(struct dtoa_context* C, const char* s, char** se);
|
||||
char* jvp_dtoa(struct dtoa_context* C, double dd, int mode, int ndigits, int *decpt, int *sign, char **rve);
|
||||
void jvp_freedtoa(struct dtoa_context* C, char *s);
|
||||
|
||||
#define JVP_DTOA_FMT_MAX_LEN 32
|
||||
#define JVP_DTOA_FMT_MAX_LEN 64
|
||||
char* jvp_dtoa_fmt(struct dtoa_context* C, register char *b, double x);
|
||||
#endif
|
||||
@@ -0,0 +1,49 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "jv.h"
|
||||
|
||||
jv jv_load_file(const char* filename, int raw) {
|
||||
FILE* file = fopen(filename, "r");
|
||||
struct jv_parser* parser;
|
||||
jv data;
|
||||
if (!file) {
|
||||
return jv_invalid_with_msg(jv_string_fmt("Could not open %s: %s",
|
||||
filename,
|
||||
strerror(errno)));
|
||||
}
|
||||
if (raw) {
|
||||
data = jv_string("");
|
||||
} else {
|
||||
data = jv_array();
|
||||
parser = jv_parser_new(0);
|
||||
}
|
||||
while (!feof(file) && !ferror(file)) {
|
||||
char buf[4096];
|
||||
size_t n = fread(buf, 1, sizeof(buf), file);
|
||||
if (raw) {
|
||||
data = jv_string_concat(data, jv_string_sized(buf, (int)n));
|
||||
} else {
|
||||
jv_parser_set_buf(parser, buf, n, !feof(file));
|
||||
jv value;
|
||||
while (jv_is_valid((value = jv_parser_next(parser))))
|
||||
data = jv_array_append(data, value);
|
||||
if (jv_invalid_has_msg(jv_copy(value))) {
|
||||
jv_free(data);
|
||||
data = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!raw)
|
||||
jv_parser_free(parser);
|
||||
int badread = ferror(file);
|
||||
if (fclose(file) != 0 || badread) {
|
||||
jv_free(data);
|
||||
return jv_invalid_with_msg(jv_string_fmt("Error reading from %s",
|
||||
filename));
|
||||
}
|
||||
return data;
|
||||
}
|
||||
+437
-31
@@ -1,11 +1,12 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "jv.h"
|
||||
#include "jv_dtoa.h"
|
||||
#include "jv_parse.h"
|
||||
#include "jv_unicode.h"
|
||||
#include "jv_alloc.h"
|
||||
#include "jv_dtoa.h"
|
||||
|
||||
typedef const char* presult;
|
||||
|
||||
@@ -16,32 +17,118 @@ typedef const char* presult;
|
||||
#define pfunc presult
|
||||
#endif
|
||||
|
||||
void jv_parser_init(struct jv_parser* p) {
|
||||
enum last_seen {
|
||||
JV_LAST_NONE = 0,
|
||||
JV_LAST_OPEN_ARRAY = '[',
|
||||
JV_LAST_OPEN_OBJECT = '{',
|
||||
JV_LAST_COLON = ':',
|
||||
JV_LAST_COMMA = ',',
|
||||
JV_LAST_VALUE = 'V',
|
||||
};
|
||||
|
||||
struct jv_parser {
|
||||
const char* curr_buf;
|
||||
int curr_buf_length;
|
||||
int curr_buf_pos;
|
||||
int curr_buf_is_partial;
|
||||
int eof;
|
||||
unsigned bom_strip_position;
|
||||
|
||||
int flags;
|
||||
|
||||
jv* stack; // parser
|
||||
int stackpos; // parser
|
||||
int stacklen; // both (optimization; it's really pathlen for streaming)
|
||||
jv path; // streamer
|
||||
enum last_seen last_seen; // streamer
|
||||
jv output; // streamer
|
||||
jv next; // both
|
||||
|
||||
char* tokenbuf;
|
||||
int tokenpos;
|
||||
int tokenlen;
|
||||
|
||||
int line, column;
|
||||
|
||||
struct dtoa_context dtoa;
|
||||
|
||||
enum {
|
||||
JV_PARSER_NORMAL,
|
||||
JV_PARSER_STRING,
|
||||
JV_PARSER_STRING_ESCAPE,
|
||||
JV_PARSER_WAITING_FOR_RS // parse error, waiting for RS
|
||||
} st;
|
||||
unsigned int last_ch_was_ws:1;
|
||||
};
|
||||
|
||||
|
||||
static void parser_init(struct jv_parser* p, int flags) {
|
||||
p->flags = flags;
|
||||
if ((p->flags & JV_PARSE_STREAMING)) {
|
||||
p->path = jv_array();
|
||||
} else {
|
||||
p->path = jv_invalid();
|
||||
p->flags &= ~(JV_PARSE_STREAM_ERRORS);
|
||||
}
|
||||
p->stack = 0;
|
||||
p->stacklen = p->stackpos = 0;
|
||||
p->last_seen = JV_LAST_NONE;
|
||||
p->output = jv_invalid();
|
||||
p->next = jv_invalid();
|
||||
p->tokenbuf = 0;
|
||||
p->tokenlen = p->tokenpos = 0;
|
||||
p->st = JV_PARSER_NORMAL;
|
||||
if ((p->flags & JV_PARSE_SEQ))
|
||||
p->st = JV_PARSER_WAITING_FOR_RS;
|
||||
else
|
||||
p->st = JV_PARSER_NORMAL;
|
||||
p->eof = 0;
|
||||
p->curr_buf = 0;
|
||||
p->curr_buf_length = p->curr_buf_pos = p->curr_buf_is_partial = 0;
|
||||
p->bom_strip_position = 0;
|
||||
p->last_ch_was_ws = 0;
|
||||
p->line = 1;
|
||||
p->column = 0;
|
||||
jvp_dtoa_context_init(&p->dtoa);
|
||||
}
|
||||
|
||||
void jv_parser_free(struct jv_parser* p) {
|
||||
static void parser_reset(struct jv_parser* p) {
|
||||
if ((p->flags & JV_PARSE_STREAMING)) {
|
||||
jv_free(p->path);
|
||||
p->path = jv_array();
|
||||
p->stacklen = 0;
|
||||
}
|
||||
p->last_seen = JV_LAST_NONE;
|
||||
jv_free(p->output);
|
||||
p->output = jv_invalid();
|
||||
jv_free(p->next);
|
||||
for (int i=0; i<p->stackpos; i++)
|
||||
p->next = jv_invalid();
|
||||
for (int i=0; i<p->stackpos; i++)
|
||||
jv_free(p->stack[i]);
|
||||
p->stackpos = 0;
|
||||
p->tokenpos = 0;
|
||||
p->st = JV_PARSER_NORMAL;
|
||||
}
|
||||
|
||||
static void parser_free(struct jv_parser* p) {
|
||||
parser_reset(p);
|
||||
jv_free(p->path);
|
||||
jv_free(p->output);
|
||||
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";
|
||||
if ((p->flags & JV_PARSE_STREAMING)) {
|
||||
if (jv_is_valid(p->next) || p->last_seen == JV_LAST_VALUE)
|
||||
return "Expected separator between values";
|
||||
if (p->stacklen > 0)
|
||||
p->last_seen = JV_LAST_VALUE;
|
||||
else
|
||||
p->last_seen = JV_LAST_NONE;
|
||||
} else {
|
||||
if (jv_is_valid(p->next)) return "Expected separator between values";
|
||||
}
|
||||
jv_free(p->next);
|
||||
p->next = val;
|
||||
return 0;
|
||||
@@ -57,7 +144,7 @@ static void push(struct jv_parser* p, jv v) {
|
||||
p->stack[p->stackpos++] = v;
|
||||
}
|
||||
|
||||
static pfunc token(struct jv_parser* p, char ch) {
|
||||
static pfunc parse_token(struct jv_parser* p, char ch) {
|
||||
switch (ch) {
|
||||
case '[':
|
||||
if (jv_is_valid(p->next)) return "Expected separator between values";
|
||||
@@ -70,7 +157,7 @@ static pfunc token(struct jv_parser* p, char ch) {
|
||||
break;
|
||||
|
||||
case ':':
|
||||
if (!jv_is_valid(p->next))
|
||||
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";
|
||||
@@ -90,7 +177,7 @@ static pfunc token(struct jv_parser* p, char ch) {
|
||||
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-2] = jv_object_set(p->stack[p->stackpos-2],
|
||||
p->stack[p->stackpos-1], p->next);
|
||||
p->stackpos--;
|
||||
p->next = jv_invalid();
|
||||
@@ -123,7 +210,7 @@ static pfunc token(struct jv_parser* p, char ch) {
|
||||
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-2] = jv_object_set(p->stack[p->stackpos-2],
|
||||
p->stack[p->stackpos-1], p->next);
|
||||
p->stackpos--;
|
||||
p->next = jv_invalid();
|
||||
@@ -140,6 +227,159 @@ static pfunc token(struct jv_parser* p, char ch) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static pfunc stream_token(struct jv_parser* p, char ch) {
|
||||
jv_kind k;
|
||||
jv last;
|
||||
|
||||
switch (ch) {
|
||||
case '[':
|
||||
if (jv_is_valid(p->next))
|
||||
return "Expected a separator between values";
|
||||
p->path = jv_array_append(p->path, jv_number(0)); // push
|
||||
p->last_seen = JV_LAST_OPEN_ARRAY;
|
||||
p->stacklen++;
|
||||
break;
|
||||
|
||||
case '{':
|
||||
if (p->last_seen == JV_LAST_VALUE)
|
||||
return "Expected a separator between values";
|
||||
// Push object key: null, since we don't know it yet
|
||||
p->path = jv_array_append(p->path, jv_null()); // push
|
||||
p->last_seen = JV_LAST_OPEN_OBJECT;
|
||||
p->stacklen++;
|
||||
break;
|
||||
|
||||
case ':':
|
||||
if (p->stacklen == 0 || jv_get_kind(jv_array_get(jv_copy(p->path), p->stacklen - 1)) == JV_KIND_NUMBER)
|
||||
return "':' not as part of an object";
|
||||
if (!jv_is_valid(p->next) || p->last_seen == JV_LAST_NONE)
|
||||
return "Expected string key before ':'";
|
||||
if (jv_get_kind(p->next) != JV_KIND_STRING)
|
||||
return "Object keys must be strings";
|
||||
if (p->last_seen != JV_LAST_VALUE)
|
||||
return "':' should follow a key";
|
||||
p->last_seen = JV_LAST_COLON;
|
||||
p->path = jv_array_set(p->path, p->stacklen - 1, p->next);
|
||||
p->next = jv_invalid();
|
||||
break;
|
||||
|
||||
case ',':
|
||||
if (p->last_seen != JV_LAST_VALUE)
|
||||
return "Expected value before ','";
|
||||
if (p->stacklen == 0)
|
||||
return "',' not as part of an object or array";
|
||||
last = jv_array_get(jv_copy(p->path), p->stacklen - 1);
|
||||
k = jv_get_kind(last);
|
||||
if (k == JV_KIND_NUMBER) {
|
||||
int idx = jv_number_value(last);
|
||||
|
||||
if (jv_is_valid(p->next)) {
|
||||
p->output = JV_ARRAY(jv_copy(p->path), p->next);
|
||||
p->next = jv_invalid();
|
||||
}
|
||||
p->path = jv_array_set(p->path, p->stacklen - 1, jv_number(idx + 1));
|
||||
p->last_seen = JV_LAST_COMMA;
|
||||
} else if (k == JV_KIND_STRING) {
|
||||
if (jv_is_valid(p->next)) {
|
||||
p->output = JV_ARRAY(jv_copy(p->path), p->next);
|
||||
p->next = jv_invalid();
|
||||
}
|
||||
p->path = jv_array_set(p->path, p->stacklen - 1, jv_true()); // ready for another name:value pair
|
||||
p->last_seen = JV_LAST_COMMA;
|
||||
} else {
|
||||
assert(k == JV_KIND_NULL);
|
||||
// this case hits on input like {,}
|
||||
// make sure to handle input like {"a", "b"} and {"a":, ...}
|
||||
jv_free(last);
|
||||
return "Objects must consist of key:value pairs";
|
||||
}
|
||||
jv_free(last);
|
||||
break;
|
||||
|
||||
case ']':
|
||||
if (p->stacklen == 0)
|
||||
return "Unmatched ']' at the top-level";
|
||||
if (p->last_seen == JV_LAST_COMMA)
|
||||
return "Expected another array element";
|
||||
if (p->last_seen == JV_LAST_OPEN_ARRAY)
|
||||
assert(!jv_is_valid(p->next));
|
||||
|
||||
last = jv_array_get(jv_copy(p->path), p->stacklen - 1);
|
||||
k = jv_get_kind(last);
|
||||
jv_free(last);
|
||||
|
||||
if (k != JV_KIND_NUMBER)
|
||||
return "Unmatched ']' in the middle of an object";
|
||||
if (jv_is_valid(p->next)) {
|
||||
p->output = JV_ARRAY(jv_copy(p->path), p->next, jv_true());
|
||||
p->next = jv_invalid();
|
||||
} else if (p->last_seen != JV_LAST_OPEN_ARRAY) {
|
||||
p->output = JV_ARRAY(jv_copy(p->path));
|
||||
}
|
||||
|
||||
p->path = jv_array_slice(p->path, 0, --(p->stacklen)); // pop
|
||||
//assert(!jv_is_valid(p->next));
|
||||
jv_free(p->next);
|
||||
p->next = jv_invalid();
|
||||
|
||||
if (p->last_seen == JV_LAST_OPEN_ARRAY)
|
||||
p->output = JV_ARRAY(jv_copy(p->path), jv_array()); // Empty arrays are leaves
|
||||
|
||||
if (p->stacklen == 0)
|
||||
p->last_seen = JV_LAST_NONE;
|
||||
else
|
||||
p->last_seen = JV_LAST_VALUE;
|
||||
break;
|
||||
|
||||
case '}':
|
||||
if (p->stacklen == 0)
|
||||
return "Unmatched '}' at the top-level";
|
||||
if (p->last_seen == JV_LAST_COMMA)
|
||||
return "Expected another key:value pair";
|
||||
if (p->last_seen == JV_LAST_OPEN_OBJECT)
|
||||
assert(!jv_is_valid(p->next));
|
||||
|
||||
last = jv_array_get(jv_copy(p->path), p->stacklen - 1);
|
||||
k = jv_get_kind(last);
|
||||
jv_free(last);
|
||||
if (k == JV_KIND_NUMBER)
|
||||
return "Unmatched '}' in the middle of an array";
|
||||
|
||||
if (jv_is_valid(p->next)) {
|
||||
if (k != JV_KIND_STRING)
|
||||
return "Objects must consist of key:value pairs";
|
||||
p->output = JV_ARRAY(jv_copy(p->path), p->next, jv_true());
|
||||
p->next = jv_invalid();
|
||||
} else {
|
||||
// Perhaps {"a":[]}
|
||||
if (p->last_seen == JV_LAST_COLON)
|
||||
// Looks like {"a":}
|
||||
return "Missing value in key:value pair";
|
||||
if (p->last_seen == JV_LAST_COMMA)
|
||||
// Looks like {"a":0,}
|
||||
return "Expected another key-value pair";
|
||||
if (p->last_seen == JV_LAST_OPEN_ARRAY)
|
||||
return "Unmatched '}' in the middle of an array";
|
||||
if (p->last_seen != JV_LAST_VALUE && p->last_seen != JV_LAST_OPEN_OBJECT)
|
||||
return "Unmatched '}'";
|
||||
if (p->last_seen != JV_LAST_OPEN_OBJECT)
|
||||
p->output = JV_ARRAY(jv_copy(p->path));
|
||||
}
|
||||
p->path = jv_array_slice(p->path, 0, --(p->stacklen)); // pop
|
||||
jv_free(p->next);
|
||||
p->next = jv_invalid();
|
||||
|
||||
if (p->last_seen == JV_LAST_OPEN_OBJECT)
|
||||
p->output = JV_ARRAY(jv_copy(p->path), jv_object()); // Empty arrays are leaves
|
||||
|
||||
if (p->stacklen == 0)
|
||||
p->last_seen = JV_LAST_NONE;
|
||||
else
|
||||
p->last_seen = JV_LAST_VALUE;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tokenadd(struct jv_parser* p, char c) {
|
||||
assert(p->tokenpos <= p->tokenlen);
|
||||
@@ -170,7 +410,7 @@ 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 == '\\') {
|
||||
@@ -207,7 +447,8 @@ static pfunc found_string(struct jv_parser* p) {
|
||||
codepoint = 0x10000 + (((codepoint - 0xD800) << 10)
|
||||
|(surrogate - 0xDC00));
|
||||
}
|
||||
// FIXME assert valid codepoint
|
||||
if (codepoint > 0x10FFFF)
|
||||
codepoint = 0xFFFD; // U+FFFD REPLACEMENT CHARACTER
|
||||
out += jvp_utf8_encode(codepoint, out);
|
||||
break;
|
||||
|
||||
@@ -215,6 +456,8 @@ static pfunc found_string(struct jv_parser* p) {
|
||||
return "Invalid escape";
|
||||
}
|
||||
} else {
|
||||
if (c > 0 && c < 0x001f)
|
||||
return "Invalid string: control characters from U+0000 through U+001F must be escaped";
|
||||
*out++ = c;
|
||||
}
|
||||
}
|
||||
@@ -236,7 +479,7 @@ static pfunc check_literal(struct jv_parser* p) {
|
||||
}
|
||||
if (pattern) {
|
||||
if (p->tokenpos != plen) return "Invalid literal";
|
||||
for (int i=0; i<plen; i++)
|
||||
for (int i=0; i<plen; i++)
|
||||
if (p->tokenbuf[i] != pattern[i])
|
||||
return "Invalid literal";
|
||||
TRY(value(p, v));
|
||||
@@ -285,7 +528,7 @@ static chclass classify(char c) {
|
||||
|
||||
static const presult OK = "output produced";
|
||||
|
||||
static int check_done(struct jv_parser* p, jv* out) {
|
||||
static int parse_check_done(struct jv_parser* p, jv* out) {
|
||||
if (p->stackpos == 0 && jv_is_valid(p->next)) {
|
||||
*out = p->next;
|
||||
p->next = jv_invalid();
|
||||
@@ -295,15 +538,85 @@ static int check_done(struct jv_parser* p, jv* out) {
|
||||
}
|
||||
}
|
||||
|
||||
static int stream_check_done(struct jv_parser* p, jv* out) {
|
||||
if (p->stacklen == 0 && jv_is_valid(p->next)) {
|
||||
*out = JV_ARRAY(jv_copy(p->path),p->next);
|
||||
p->next = jv_invalid();
|
||||
return 1;
|
||||
} else if (jv_is_valid(p->output)) {
|
||||
if (jv_array_length(jv_copy(p->output)) > 2) {
|
||||
// At end of an array or object, necessitating one more output by
|
||||
// which to indicate this
|
||||
*out = jv_array_slice(jv_copy(p->output), 0, 2);
|
||||
p->output = jv_array_slice(p->output, 0, 1); // arrange one more output
|
||||
} else {
|
||||
// No further processing needed
|
||||
*out = p->output;
|
||||
p->output = jv_invalid();
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int parse_check_truncation(struct jv_parser* p) {
|
||||
return ((p->flags & JV_PARSE_SEQ) && !p->last_ch_was_ws && (p->stackpos > 0 || p->tokenpos > 0 || jv_get_kind(p->next) == JV_KIND_NUMBER));
|
||||
}
|
||||
|
||||
static int stream_check_truncation(struct jv_parser* p) {
|
||||
jv_kind k = jv_get_kind(p->next);
|
||||
return (p->stacklen > 0 || k == JV_KIND_NUMBER || k == JV_KIND_TRUE || k == JV_KIND_FALSE || k == JV_KIND_NULL);
|
||||
}
|
||||
|
||||
static int parse_is_top_num(struct jv_parser* p) {
|
||||
return (p->stackpos == 0 && jv_get_kind(p->next) == JV_KIND_NUMBER);
|
||||
}
|
||||
|
||||
static int stream_is_top_num(struct jv_parser* p) {
|
||||
return (p->stacklen == 0 && jv_get_kind(p->next) == JV_KIND_NUMBER);
|
||||
}
|
||||
|
||||
#define check_done(p, o) \
|
||||
(((p)->flags & JV_PARSE_STREAMING) ? stream_check_done((p), (o)) : parse_check_done((p), (o)))
|
||||
|
||||
#define token(p, ch) \
|
||||
(((p)->flags & JV_PARSE_STREAMING) ? stream_token((p), (ch)) : parse_token((p), (ch)))
|
||||
|
||||
#define check_truncation(p) \
|
||||
(((p)->flags & JV_PARSE_STREAMING) ? stream_check_truncation((p)) : parse_check_truncation((p)))
|
||||
|
||||
#define is_top_num(p) \
|
||||
(((p)->flags & JV_PARSE_STREAMING) ? stream_is_top_num((p)) : parse_is_top_num((p)))
|
||||
|
||||
static pfunc scan(struct jv_parser* p, char ch, jv* out) {
|
||||
p->column++;
|
||||
if (ch == '\n') {
|
||||
p->line++;
|
||||
p->column = 0;
|
||||
}
|
||||
if (ch == '\036' /* ASCII RS; see draft-ietf-json-sequence-07 */) {
|
||||
if (check_truncation(p)) {
|
||||
if (check_literal(p) == 0 && is_top_num(p))
|
||||
return "Potentially truncated top-level numeric value";
|
||||
return "Truncated value";
|
||||
}
|
||||
TRY(check_literal(p));
|
||||
if (p->st == JV_PARSER_NORMAL && check_done(p, out))
|
||||
return OK;
|
||||
// shouldn't happen?
|
||||
assert(!jv_is_valid(*out));
|
||||
parser_reset(p);
|
||||
jv_free(*out);
|
||||
*out = jv_invalid();
|
||||
return OK;
|
||||
}
|
||||
presult answer = 0;
|
||||
p->last_ch_was_ws = 0;
|
||||
if (p->st == JV_PARSER_NORMAL) {
|
||||
chclass cls = classify(ch);
|
||||
if (cls == WHITESPACE)
|
||||
p->last_ch_was_ws = 1;
|
||||
if (cls != LITERAL) {
|
||||
TRY(check_literal(p));
|
||||
if (check_done(p, out)) answer = OK;
|
||||
@@ -341,12 +654,30 @@ static pfunc scan(struct jv_parser* p, char ch, jv* out) {
|
||||
return answer;
|
||||
}
|
||||
|
||||
struct jv_parser* jv_parser_new(int flags) {
|
||||
struct jv_parser* p = jv_mem_alloc(sizeof(struct jv_parser));
|
||||
parser_init(p, flags);
|
||||
p->flags = flags;
|
||||
return p;
|
||||
}
|
||||
|
||||
void jv_parser_free(struct jv_parser* p) {
|
||||
parser_free(p);
|
||||
jv_mem_free(p);
|
||||
}
|
||||
|
||||
static const unsigned char UTF8_BOM[] = {0xEF,0xBB,0xBF};
|
||||
|
||||
int jv_parser_remaining(struct jv_parser* p) {
|
||||
if (p->curr_buf == 0)
|
||||
return 0;
|
||||
return (p->curr_buf_length - p->curr_buf_pos);
|
||||
}
|
||||
|
||||
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)) {
|
||||
while (length > 0 && p->bom_strip_position < sizeof(UTF8_BOM)) {
|
||||
if ((unsigned char)*buf == UTF8_BOM[p->bom_strip_position]) {
|
||||
// matched a BOM character
|
||||
buf++;
|
||||
@@ -368,43 +699,118 @@ void jv_parser_set_buf(struct jv_parser* p, const char* buf, int length, int is_
|
||||
p->curr_buf_is_partial = is_partial;
|
||||
}
|
||||
|
||||
static jv make_error(struct jv_parser*, const char *, ...) JV_PRINTF_LIKE(2, 3);
|
||||
|
||||
static jv make_error(struct jv_parser* p, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
jv e = jv_string_vfmt(fmt, ap);
|
||||
va_end(ap);
|
||||
if ((p->flags & JV_PARSE_STREAM_ERRORS))
|
||||
return JV_ARRAY(e, jv_copy(p->path));
|
||||
return jv_invalid_with_msg(e);
|
||||
}
|
||||
|
||||
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;
|
||||
if (p->eof)
|
||||
return jv_invalid();
|
||||
if (!p->curr_buf)
|
||||
return jv_invalid(); // Need a buffer
|
||||
if (p->bom_strip_position == 0xff) {
|
||||
if (!(p->flags & JV_PARSE_SEQ))
|
||||
return jv_invalid_with_msg(jv_string("Malformed BOM"));
|
||||
p->st =JV_PARSER_WAITING_FOR_RS;
|
||||
parser_reset(p);
|
||||
}
|
||||
jv value = jv_invalid();
|
||||
if ((p->flags & JV_PARSE_STREAMING) && stream_check_done(p, &value))
|
||||
return value;
|
||||
char ch;
|
||||
presult msg = 0;
|
||||
while (!msg && p->curr_buf_pos < p->curr_buf_length) {
|
||||
char ch = p->curr_buf[p->curr_buf_pos++];
|
||||
ch = p->curr_buf[p->curr_buf_pos++];
|
||||
if (p->st == JV_PARSER_WAITING_FOR_RS) {
|
||||
if (ch == '\n') {
|
||||
p->line++;
|
||||
p->column = 0;
|
||||
} else {
|
||||
p->column++;
|
||||
}
|
||||
if (ch == '\036')
|
||||
p->st = JV_PARSER_NORMAL;
|
||||
continue; // need to resync, wait for RS
|
||||
}
|
||||
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));
|
||||
jv_free(value);
|
||||
if (ch != '\036' && (p->flags & JV_PARSE_SEQ)) {
|
||||
// Skip to the next RS
|
||||
p->st = JV_PARSER_WAITING_FOR_RS;
|
||||
value = make_error(p, "%s at line %d, column %d (need RS to resync)", msg, p->line, p->column);
|
||||
parser_reset(p);
|
||||
return value;
|
||||
}
|
||||
value = make_error(p, "%s at line %d, column %d", msg, p->line, p->column);
|
||||
parser_reset(p);
|
||||
if (!(p->flags & JV_PARSE_SEQ)) {
|
||||
// We're not parsing a JSON text sequence; throw this buffer away.
|
||||
// XXX We should fail permanently here.
|
||||
p->curr_buf = 0;
|
||||
p->curr_buf_pos = 0;
|
||||
} // Else ch must be RS; don't clear buf so we can start parsing again after this ch
|
||||
return value;
|
||||
} 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)
|
||||
p->eof = 1;
|
||||
assert(p->curr_buf_pos == p->curr_buf_length);
|
||||
jv_free(value);
|
||||
if (p->st == JV_PARSER_WAITING_FOR_RS)
|
||||
return make_error(p, "Unfinished abandoned text at EOF at line %d, column %d", p->line, p->column);
|
||||
if (p->st != JV_PARSER_NORMAL) {
|
||||
value = make_error(p, "Unfinished string at EOF at line %d, column %d", p->line, p->column);
|
||||
parser_reset(p);
|
||||
p->st = JV_PARSER_WAITING_FOR_RS;
|
||||
return value;
|
||||
}
|
||||
if ((msg = check_literal(p))) {
|
||||
value = make_error(p, "%s at EOF at line %d, column %d", msg, p->line, p->column);
|
||||
parser_reset(p);
|
||||
p->st = JV_PARSER_WAITING_FOR_RS;
|
||||
return value;
|
||||
}
|
||||
if (((p->flags & JV_PARSE_STREAMING) && p->stacklen != 0) ||
|
||||
(!(p->flags & JV_PARSE_STREAMING) && p->stackpos != 0)) {
|
||||
value = make_error(p, "Unfinished JSON term at EOF at line %d, column %d", p->line, p->column);
|
||||
parser_reset(p);
|
||||
p->st = JV_PARSER_WAITING_FOR_RS;
|
||||
return value;
|
||||
}
|
||||
// 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;
|
||||
if ((p->flags & JV_PARSE_STREAMING) && jv_is_valid(p->next)) {
|
||||
value = JV_ARRAY(jv_copy(p->path), p->next); // except in streaming mode we've got to make it [path,value]
|
||||
} else {
|
||||
value = p->next;
|
||||
}
|
||||
p->next = jv_invalid();
|
||||
if ((p->flags & JV_PARSE_SEQ) && !p->last_ch_was_ws && jv_get_kind(value) == JV_KIND_NUMBER) {
|
||||
jv_free(value);
|
||||
return make_error(p, "Potentially truncated top-level numeric value at EOF at line %d, column %d", p->line, p->column);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
jv jv_parse_sized(const char* string, int length) {
|
||||
struct jv_parser parser;
|
||||
jv_parser_init(&parser);
|
||||
parser_init(&parser, 0);
|
||||
jv_parser_set_buf(&parser, string, length, 0);
|
||||
jv value = jv_parser_next(&parser);
|
||||
if (jv_is_valid(value)) {
|
||||
@@ -429,7 +835,7 @@ jv jv_parse_sized(const char* string, int length) {
|
||||
jv_free(value);
|
||||
value = jv_invalid_with_msg(jv_string("Expected JSON value"));
|
||||
}
|
||||
jv_parser_free(&parser);
|
||||
parser_free(&parser);
|
||||
|
||||
if (!jv_is_valid(value) && jv_invalid_has_msg(jv_copy(value))) {
|
||||
jv msg = jv_invalid_get_msg(value);
|
||||
|
||||
-37
@@ -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
|
||||
+177
-78
@@ -1,8 +1,15 @@
|
||||
#include "jv.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <float.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
#include <fileapi.h>
|
||||
#endif
|
||||
|
||||
#include "jv.h"
|
||||
#include "jv_dtoa.h"
|
||||
#include "jv_unicode.h"
|
||||
|
||||
@@ -10,77 +17,90 @@
|
||||
#define COL(c) (ESC "[" c "m")
|
||||
#define COLRESET (ESC "[0m")
|
||||
|
||||
// Colour table. See http://en.wikipedia.org/wiki/ANSI_escape_code#Colors
|
||||
// Colour table. See https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
|
||||
// for how to choose these.
|
||||
static const jv_kind colour_kinds[] =
|
||||
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")};
|
||||
{COL("1;30"), COL("0;39"), COL("0;39"), COL("0;39"),
|
||||
COL("0;32"), COL("1;39"), COL("1;39")};
|
||||
#define FIELD_COLOUR COL("34;1")
|
||||
|
||||
static void put_buf(const char* s, int len, FILE* fout, jv* strout) {
|
||||
static void put_buf(const char *s, int len, FILE *fout, jv *strout, int is_tty) {
|
||||
if (strout) {
|
||||
*strout = jv_string_append_buf(*strout, s, len);
|
||||
} else {
|
||||
#ifdef WIN32
|
||||
/* See util.h */
|
||||
if (is_tty)
|
||||
WriteFile((HANDLE)_get_osfhandle(fileno(fout)), s, len, NULL, NULL);
|
||||
else
|
||||
fwrite(s, 1, len, fout);
|
||||
#else
|
||||
fwrite(s, 1, len, fout);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void put_char(char c, FILE* fout, jv* strout) {
|
||||
put_buf(&c, 1, fout, strout);
|
||||
static void put_char(char c, FILE* fout, jv* strout, int T) {
|
||||
put_buf(&c, 1, fout, strout, T);
|
||||
}
|
||||
|
||||
static void put_str(const char* s, FILE* fout, jv* strout) {
|
||||
put_buf(s, strlen(s), fout, strout);
|
||||
static void put_str(const char* s, FILE* fout, jv* strout, int T) {
|
||||
put_buf(s, strlen(s), fout, strout, T);
|
||||
}
|
||||
|
||||
static void put_space(int n, FILE* fout, jv* strout) {
|
||||
while (n--) {
|
||||
put_char(' ', fout, strout);
|
||||
static void put_indent(int n, int flags, FILE* fout, jv* strout, int T) {
|
||||
if (flags & JV_PRINT_TAB) {
|
||||
while (n--)
|
||||
put_char('\t', fout, strout, T);
|
||||
} else {
|
||||
n *= ((flags & (JV_PRINT_SPACE0 | JV_PRINT_SPACE1 | JV_PRINT_SPACE2)) >> 8);
|
||||
while (n--)
|
||||
put_char(' ', fout, strout, T);
|
||||
}
|
||||
}
|
||||
|
||||
static void jvp_dump_string(jv str, int ascii_only, FILE* F, jv* S) {
|
||||
static void jvp_dump_string(jv str, int ascii_only, FILE* F, jv* S, int T) {
|
||||
assert(jv_get_kind(str) == JV_KIND_STRING);
|
||||
const char* i = jv_string_value(str);
|
||||
const char* end = i + jv_string_length_bytes(jv_copy(str));
|
||||
const char* cstart;
|
||||
int c = 0;
|
||||
char buf[32];
|
||||
put_char('"', F, S);
|
||||
put_char('"', F, S, T);
|
||||
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('\\', F, S, T);
|
||||
}
|
||||
put_char(c, F, S);
|
||||
put_char(c, F, S, T);
|
||||
} else if (c < 0x20 || c == 0x7F) {
|
||||
// ASCII control character
|
||||
switch (c) {
|
||||
case '\b':
|
||||
put_char('\\', F, S);
|
||||
put_char('b', F, S);
|
||||
put_char('\\', F, S, T);
|
||||
put_char('b', F, S, T);
|
||||
break;
|
||||
case '\t':
|
||||
put_char('\\', F, S);
|
||||
put_char('t', F, S);
|
||||
put_char('\\', F, S, T);
|
||||
put_char('t', F, S, T);
|
||||
break;
|
||||
case '\r':
|
||||
put_char('\\', F, S);
|
||||
put_char('r', F, S);
|
||||
put_char('\\', F, S, T);
|
||||
put_char('r', F, S, T);
|
||||
break;
|
||||
case '\n':
|
||||
put_char('\\', F, S);
|
||||
put_char('n', F, S);
|
||||
put_char('\\', F, S, T);
|
||||
put_char('n', F, S, T);
|
||||
break;
|
||||
case '\f':
|
||||
put_char('\\', F, S);
|
||||
put_char('f', F, S);
|
||||
put_char('\\', F, S, T);
|
||||
put_char('f', F, S, T);
|
||||
break;
|
||||
default:
|
||||
unicode_escape = 1;
|
||||
@@ -90,7 +110,7 @@ static void jvp_dump_string(jv str, int ascii_only, FILE* F, jv* S) {
|
||||
if (ascii_only) {
|
||||
unicode_escape = 1;
|
||||
} else {
|
||||
put_buf(cstart, i - cstart, F, S);
|
||||
put_buf(cstart, i - cstart, F, S, T);
|
||||
}
|
||||
}
|
||||
if (unicode_escape) {
|
||||
@@ -98,27 +118,34 @@ static void jvp_dump_string(jv str, int ascii_only, FILE* F, jv* S) {
|
||||
sprintf(buf, "\\u%04x", c);
|
||||
} else {
|
||||
c -= 0x10000;
|
||||
sprintf(buf, "\\u%04x\\u%04x",
|
||||
sprintf(buf, "\\u%04x\\u%04x",
|
||||
0xD800 | ((c & 0xffc00) >> 10),
|
||||
0xDC00 | (c & 0x003ff));
|
||||
}
|
||||
put_str(buf, F, S);
|
||||
put_str(buf, F, S, T);
|
||||
}
|
||||
}
|
||||
assert(c != -1);
|
||||
put_char('"', F, S);
|
||||
put_char('"', F, S, T);
|
||||
}
|
||||
|
||||
enum { INDENT = 2 };
|
||||
static void put_refcnt(struct dtoa_context* C, int refcnt, FILE *F, jv* S, int T){
|
||||
char buf[JVP_DTOA_FMT_MAX_LEN];
|
||||
put_char(' ', F, S, T);
|
||||
put_char('(', F, S, T);
|
||||
put_str(jvp_dtoa_fmt(C, buf, refcnt), F, S, T);
|
||||
put_char(')', F, S, T);
|
||||
}
|
||||
|
||||
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;
|
||||
double refcnt = (flags & JV_PRINT_REFCOUNT) ? jv_get_refcnt(x) - 1 : -1;
|
||||
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);
|
||||
put_str(colour, F, S, flags & JV_PRINT_ISATTY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -126,119 +153,175 @@ static void jv_dump_term(struct dtoa_context* C, jv x, int flags, int indent, FI
|
||||
switch (jv_get_kind(x)) {
|
||||
default:
|
||||
case JV_KIND_INVALID:
|
||||
assert(0 && "Invalid value");
|
||||
if (flags & JV_PRINT_INVALID) {
|
||||
jv msg = jv_invalid_get_msg(jv_copy(x));
|
||||
if (jv_get_kind(msg) == JV_KIND_STRING) {
|
||||
put_str("<invalid:", F, S, flags & JV_PRINT_ISATTY);
|
||||
jvp_dump_string(msg, flags | JV_PRINT_ASCII, F, S, flags & JV_PRINT_ISATTY);
|
||||
put_str(">", F, S, flags & JV_PRINT_ISATTY);
|
||||
} else {
|
||||
put_str("<invalid>", F, S, flags & JV_PRINT_ISATTY);
|
||||
}
|
||||
} else {
|
||||
assert(0 && "Invalid value");
|
||||
}
|
||||
break;
|
||||
case JV_KIND_NULL:
|
||||
put_str("null", F, S);
|
||||
put_str("null", F, S, flags & JV_PRINT_ISATTY);
|
||||
break;
|
||||
case JV_KIND_FALSE:
|
||||
put_str("false", F, S);
|
||||
put_str("false", F, S, flags & JV_PRINT_ISATTY);
|
||||
break;
|
||||
case JV_KIND_TRUE:
|
||||
put_str("true", F, S);
|
||||
put_str("true", F, S, flags & JV_PRINT_ISATTY);
|
||||
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);
|
||||
put_str("null", F, S, flags & JV_PRINT_ISATTY);
|
||||
} 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);
|
||||
put_str(jvp_dtoa_fmt(C, buf, d), F, S, flags & JV_PRINT_ISATTY);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case JV_KIND_STRING:
|
||||
jvp_dump_string(x, flags & JV_PRINT_ASCII, F, S);
|
||||
jvp_dump_string(x, flags & JV_PRINT_ASCII, F, S, flags & JV_PRINT_ISATTY);
|
||||
if (flags & JV_PRINT_REFCOUNT)
|
||||
put_refcnt(C, refcnt, F, S, flags & JV_PRINT_ISATTY);
|
||||
break;
|
||||
case JV_KIND_ARRAY: {
|
||||
if (jv_array_length(jv_copy(x)) == 0) {
|
||||
put_str("[]", F, S);
|
||||
put_str("[]", F, S, flags & JV_PRINT_ISATTY);
|
||||
break;
|
||||
}
|
||||
put_str("[", F, S);
|
||||
put_str("[", F, S, flags & JV_PRINT_ISATTY);
|
||||
if (flags & JV_PRINT_PRETTY) {
|
||||
put_char('\n', F, S);
|
||||
put_space(indent+INDENT, F, S);
|
||||
put_char('\n', F, S, flags & JV_PRINT_ISATTY);
|
||||
put_indent(indent + 1, flags, F, S, flags & JV_PRINT_ISATTY);
|
||||
}
|
||||
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);
|
||||
put_str(",\n", F, S, flags & JV_PRINT_ISATTY);
|
||||
put_indent(indent + 1, flags, F, S, flags & JV_PRINT_ISATTY);
|
||||
} else {
|
||||
put_str(",", F, S);
|
||||
put_str(",", F, S, flags & JV_PRINT_ISATTY);
|
||||
}
|
||||
}
|
||||
jv_dump_term(C, elem, flags, indent + INDENT, F, S);
|
||||
if (colour) put_str(colour, F, S);
|
||||
jv_dump_term(C, elem, flags, indent + 1, F, S);
|
||||
if (colour) put_str(colour, F, S, flags & JV_PRINT_ISATTY);
|
||||
}
|
||||
if (flags & JV_PRINT_PRETTY) {
|
||||
put_char('\n', F, S);
|
||||
put_space(indent, F, S);
|
||||
put_char('\n', F, S, flags & JV_PRINT_ISATTY);
|
||||
put_indent(indent, flags, F, S, flags & JV_PRINT_ISATTY);
|
||||
}
|
||||
if (colour) put_str(colour, F, S);
|
||||
put_char(']', F, S);
|
||||
if (colour) put_str(colour, F, S, flags & JV_PRINT_ISATTY);
|
||||
put_char(']', F, S, flags & JV_PRINT_ISATTY);
|
||||
if (flags & JV_PRINT_REFCOUNT)
|
||||
put_refcnt(C, refcnt, F, S, flags & JV_PRINT_ISATTY);
|
||||
break;
|
||||
}
|
||||
case JV_KIND_OBJECT: {
|
||||
if (jv_object_length(jv_copy(x)) == 0) {
|
||||
put_str("{}", F, S);
|
||||
put_str("{}", F, S, flags & JV_PRINT_ISATTY);
|
||||
break;
|
||||
}
|
||||
put_char('{', F, S);
|
||||
put_char('{', F, S, flags & JV_PRINT_ISATTY);
|
||||
if (flags & JV_PRINT_PRETTY) {
|
||||
put_char('\n', F, S);
|
||||
put_space(indent+INDENT, F, S);
|
||||
put_char('\n', F, S, flags & JV_PRINT_ISATTY);
|
||||
put_indent(indent + 1, flags, F, S, flags & JV_PRINT_ISATTY);
|
||||
}
|
||||
int first = 1;
|
||||
jv_object_foreach(x, key, value) {
|
||||
int i = 0;
|
||||
jv keyset = jv_null();
|
||||
while (1) {
|
||||
jv key, value;
|
||||
if (flags & JV_PRINT_SORTED) {
|
||||
if (first) {
|
||||
keyset = jv_keys(jv_copy(x));
|
||||
i = 0;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
if (i >= jv_array_length(jv_copy(keyset))) {
|
||||
jv_free(keyset);
|
||||
break;
|
||||
}
|
||||
key = jv_array_get(jv_copy(keyset), i);
|
||||
value = jv_object_get(jv_copy(x), jv_copy(key));
|
||||
} else {
|
||||
if (first) {
|
||||
i = jv_object_iter(x);
|
||||
} else {
|
||||
i = jv_object_iter_next(x, i);
|
||||
}
|
||||
if (!jv_object_iter_valid(x, i)) break;
|
||||
key = jv_object_iter_key(x, i);
|
||||
value = jv_object_iter_value(x, i);
|
||||
}
|
||||
|
||||
if (!first) {
|
||||
if (flags & JV_PRINT_PRETTY){
|
||||
put_str(",\n", F, S);
|
||||
put_space(indent+INDENT, F, S);
|
||||
put_str(",\n", F, S, flags & JV_PRINT_ISATTY);
|
||||
put_indent(indent + 1, flags, F, S, flags & JV_PRINT_ISATTY);
|
||||
} else {
|
||||
put_str(",", F, S);
|
||||
put_str(",", F, S, flags & JV_PRINT_ISATTY);
|
||||
}
|
||||
}
|
||||
if (colour) put_str(COLRESET, F, S);
|
||||
if (colour) put_str(COLRESET, F, S, flags & JV_PRINT_ISATTY);
|
||||
|
||||
first = 0;
|
||||
if (colour) put_str(FIELD_COLOUR, F, S);
|
||||
jvp_dump_string(key, flags & JV_PRINT_ASCII, F, S);
|
||||
if (colour) put_str(FIELD_COLOUR, F, S, flags & JV_PRINT_ISATTY);
|
||||
jvp_dump_string(key, flags & JV_PRINT_ASCII, F, S, flags & JV_PRINT_ISATTY);
|
||||
jv_free(key);
|
||||
if (colour) put_str(COLRESET, F, S);
|
||||
if (colour) put_str(COLRESET, F, S, flags & JV_PRINT_ISATTY);
|
||||
|
||||
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 (colour) put_str(colour, F, S, flags & JV_PRINT_ISATTY);
|
||||
put_str((flags & JV_PRINT_PRETTY) ? ": " : ":", F, S, flags & JV_PRINT_ISATTY);
|
||||
if (colour) put_str(COLRESET, F, S, flags & JV_PRINT_ISATTY);
|
||||
|
||||
jv_dump_term(C, value, flags, indent + 1, F, S);
|
||||
if (colour) put_str(colour, F, S, flags & JV_PRINT_ISATTY);
|
||||
}
|
||||
if (flags & JV_PRINT_PRETTY) {
|
||||
put_char('\n', F, S);
|
||||
put_space(indent, F, S);
|
||||
put_char('\n', F, S, flags & JV_PRINT_ISATTY);
|
||||
put_indent(indent, flags, F, S, flags & JV_PRINT_ISATTY);
|
||||
}
|
||||
if (colour) put_str(colour, F, S);
|
||||
put_char('}', F, S);
|
||||
if (colour) put_str(colour, F, S, flags & JV_PRINT_ISATTY);
|
||||
put_char('}', F, S, flags & JV_PRINT_ISATTY);
|
||||
if (flags & JV_PRINT_REFCOUNT)
|
||||
put_refcnt(C, refcnt, F, S, flags & JV_PRINT_ISATTY);
|
||||
}
|
||||
}
|
||||
jv_free(x);
|
||||
if (colour) {
|
||||
put_str(COLRESET, F, S);
|
||||
put_str(COLRESET, F, S, flags & JV_PRINT_ISATTY);
|
||||
}
|
||||
}
|
||||
|
||||
void jv_dump(jv x, int flags) {
|
||||
void jv_dumpf(jv x, FILE *f, int flags) {
|
||||
struct dtoa_context C;
|
||||
jvp_dtoa_context_init(&C);
|
||||
jv_dump_term(&C, x, flags, 0, stdout, 0);
|
||||
jv_dump_term(&C, x, flags, 0, f, 0);
|
||||
jvp_dtoa_context_free(&C);
|
||||
}
|
||||
|
||||
void jv_dump(jv x, int flags) {
|
||||
jv_dumpf(x, stdout, flags);
|
||||
}
|
||||
|
||||
/* This one is nice for use in debuggers */
|
||||
void jv_show(jv x, int flags) {
|
||||
if (flags == -1)
|
||||
flags = JV_PRINT_PRETTY | JV_PRINT_COLOUR | JV_PRINT_INDENT_FLAGS(2);
|
||||
jv_dumpf(jv_copy(x), stderr, flags | JV_PRINT_INVALID);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
jv jv_dump_string(jv x, int flags) {
|
||||
struct dtoa_context C;
|
||||
jvp_dtoa_context_init(&C);
|
||||
@@ -247,3 +330,19 @@ jv jv_dump_string(jv x, int flags) {
|
||||
jvp_dtoa_context_free(&C);
|
||||
return s;
|
||||
}
|
||||
|
||||
char *jv_dump_string_trunc(jv x, char *outbuf, size_t bufsize) {
|
||||
x = jv_dump_string(x,0);
|
||||
const char* p = jv_string_value(x);
|
||||
const size_t len = strlen(p);
|
||||
strncpy(outbuf, p, bufsize);
|
||||
outbuf[bufsize - 1] = 0;
|
||||
if (len > bufsize - 1 && bufsize >= 4) {
|
||||
// Indicate truncation with '...'
|
||||
outbuf[bufsize - 2]='.';
|
||||
outbuf[bufsize - 3]='.';
|
||||
outbuf[bufsize - 4]='.';
|
||||
}
|
||||
jv_free(x);
|
||||
return outbuf;
|
||||
}
|
||||
+48
-16
@@ -3,35 +3,67 @@
|
||||
#include "jv_unicode.h"
|
||||
#include "jv_utf8_tables.h"
|
||||
|
||||
const char* jvp_utf8_next(const char* in, const char* end, int* codepoint) {
|
||||
const char* jvp_utf8_next(const char* in, const char* end, int* codepoint_ret) {
|
||||
assert(in <= end);
|
||||
if (in == end) {
|
||||
codepoint = 0;
|
||||
return 0;
|
||||
}
|
||||
int codepoint = -1;
|
||||
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;
|
||||
if ((first & 0x80) == 0) {
|
||||
/* Fast-path for ASCII */
|
||||
codepoint = first;
|
||||
length = 1;
|
||||
} else if (length == 0 || length == UTF8_CONTINUATION_BYTE) {
|
||||
/* Bad single byte - either an invalid byte or an out-of-place continuation byte */
|
||||
length = 1;
|
||||
} else if (in + length > end) {
|
||||
/* String ends before UTF8 sequence ends */
|
||||
length = end - in;
|
||||
} else {
|
||||
codepoint = ((unsigned)in[0]) & utf8_coding_bits[first];
|
||||
for (int i=1; i<length; i++) {
|
||||
unsigned ch = (unsigned char)in[i];
|
||||
if (utf8_coding_length[ch] != UTF8_CONTINUATION_BYTE){
|
||||
/* Invalid UTF8 sequence - not followed by the right number of continuation bytes */
|
||||
codepoint = -1;
|
||||
length = i;
|
||||
break;
|
||||
}
|
||||
codepoint = (codepoint << 6) | (ch & 0x3f);
|
||||
}
|
||||
if (codepoint < utf8_first_codepoint[length]) {
|
||||
/* Overlong UTF8 sequence */
|
||||
codepoint = -1;
|
||||
}
|
||||
if (0xD800 <= codepoint && codepoint <= 0xDFFF) {
|
||||
/* Surrogate codepoints can't be encoded in UTF8 */
|
||||
codepoint = -1;
|
||||
}
|
||||
if (codepoint > 0x10FFFF) {
|
||||
/* Outside Unicode range */
|
||||
codepoint = -1;
|
||||
}
|
||||
*codepoint = (*codepoint << 6) | (ch & 0x3f);
|
||||
}
|
||||
assert(length > 0);
|
||||
*codepoint_ret = codepoint;
|
||||
return in + length;
|
||||
}
|
||||
|
||||
int jvp_utf8_verify(const char* in, const char* end) {
|
||||
int codepoint = 0;
|
||||
int jvp_utf8_is_valid(const char* in, const char* end) {
|
||||
int codepoint;
|
||||
while ((in = jvp_utf8_next(in, end, &codepoint))) {
|
||||
if (codepoint == -1) return 0;
|
||||
}
|
||||
return codepoint != -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int jvp_utf8_decode_length(char startchar) {
|
||||
if ((startchar & 0x80) == 0) return 1;
|
||||
else if ((startchar & 0xC0) == 0xC0) return 2;
|
||||
else if ((startchar & 0xE0) == 0xE0) return 3;
|
||||
else return 4;
|
||||
}
|
||||
|
||||
int jvp_utf8_encode_length(int codepoint) {
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
#define JV_UNICODE_H
|
||||
|
||||
const char* jvp_utf8_next(const char* in, const char* end, int* codepoint);
|
||||
|
||||
int jvp_utf8_is_valid(const char* in, const char* end);
|
||||
|
||||
int jvp_utf8_decode_length(char startchar);
|
||||
|
||||
|
||||
@@ -33,3 +33,5 @@ static const unsigned char utf8_coding_bits[] =
|
||||
0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
|
||||
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
static const int utf8_first_codepoint[] =
|
||||
{0x00, 0x00, 0x80, 0x800, 0x10000};
|
||||
@@ -0,0 +1,362 @@
|
||||
#ifndef jq_yyHEADER_H
|
||||
#define jq_yyHEADER_H 1
|
||||
#define jq_yyIN_HEADER 1
|
||||
|
||||
#line 6 "lexer.h"
|
||||
|
||||
#line 8 "lexer.h"
|
||||
|
||||
#define YY_INT_ALIGNED short int
|
||||
|
||||
/* A lexical scanner generated by flex */
|
||||
|
||||
#define FLEX_SCANNER
|
||||
#define YY_FLEX_MAJOR_VERSION 2
|
||||
#define YY_FLEX_MINOR_VERSION 5
|
||||
#define YY_FLEX_SUBMINOR_VERSION 35
|
||||
#if YY_FLEX_SUBMINOR_VERSION > 0
|
||||
#define FLEX_BETA
|
||||
#endif
|
||||
|
||||
/* First, we deal with platform-specific or compiler-specific issues. */
|
||||
|
||||
/* begin standard C headers. */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* end standard C headers. */
|
||||
|
||||
/* flex integer type definitions */
|
||||
|
||||
#ifndef FLEXINT_H
|
||||
#define FLEXINT_H
|
||||
|
||||
/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
|
||||
|
||||
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
|
||||
/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
|
||||
* if you want the limit (max/min) macros for int types.
|
||||
*/
|
||||
#ifndef __STDC_LIMIT_MACROS
|
||||
#define __STDC_LIMIT_MACROS 1
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
typedef int8_t flex_int8_t;
|
||||
typedef uint8_t flex_uint8_t;
|
||||
typedef int16_t flex_int16_t;
|
||||
typedef uint16_t flex_uint16_t;
|
||||
typedef int32_t flex_int32_t;
|
||||
typedef uint32_t flex_uint32_t;
|
||||
#else
|
||||
typedef signed char flex_int8_t;
|
||||
typedef short int flex_int16_t;
|
||||
typedef int flex_int32_t;
|
||||
typedef unsigned char flex_uint8_t;
|
||||
typedef unsigned short int flex_uint16_t;
|
||||
typedef unsigned int flex_uint32_t;
|
||||
|
||||
/* Limits of integral types. */
|
||||
#ifndef INT8_MIN
|
||||
#define INT8_MIN (-128)
|
||||
#endif
|
||||
#ifndef INT16_MIN
|
||||
#define INT16_MIN (-32767-1)
|
||||
#endif
|
||||
#ifndef INT32_MIN
|
||||
#define INT32_MIN (-2147483647-1)
|
||||
#endif
|
||||
#ifndef INT8_MAX
|
||||
#define INT8_MAX (127)
|
||||
#endif
|
||||
#ifndef INT16_MAX
|
||||
#define INT16_MAX (32767)
|
||||
#endif
|
||||
#ifndef INT32_MAX
|
||||
#define INT32_MAX (2147483647)
|
||||
#endif
|
||||
#ifndef UINT8_MAX
|
||||
#define UINT8_MAX (255U)
|
||||
#endif
|
||||
#ifndef UINT16_MAX
|
||||
#define UINT16_MAX (65535U)
|
||||
#endif
|
||||
#ifndef UINT32_MAX
|
||||
#define UINT32_MAX (4294967295U)
|
||||
#endif
|
||||
|
||||
#endif /* ! C99 */
|
||||
|
||||
#endif /* ! FLEXINT_H */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/* The "const" storage-class-modifier is valid. */
|
||||
#define YY_USE_CONST
|
||||
|
||||
#else /* ! __cplusplus */
|
||||
|
||||
/* C99 requires __STDC__ to be defined as 1. */
|
||||
#if defined (__STDC__)
|
||||
|
||||
#define YY_USE_CONST
|
||||
|
||||
#endif /* defined (__STDC__) */
|
||||
#endif /* ! __cplusplus */
|
||||
|
||||
#ifdef YY_USE_CONST
|
||||
#define yyconst const
|
||||
#else
|
||||
#define yyconst
|
||||
#endif
|
||||
|
||||
/* An opaque pointer. */
|
||||
#ifndef YY_TYPEDEF_YY_SCANNER_T
|
||||
#define YY_TYPEDEF_YY_SCANNER_T
|
||||
typedef void* yyscan_t;
|
||||
#endif
|
||||
|
||||
/* For convenience, these vars (plus the bison vars far below)
|
||||
are macros in the reentrant scanner. */
|
||||
#define yyin yyg->yyin_r
|
||||
#define yyout yyg->yyout_r
|
||||
#define yyextra yyg->yyextra_r
|
||||
#define yyleng yyg->yyleng_r
|
||||
#define yytext yyg->yytext_r
|
||||
#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
|
||||
#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
|
||||
#define yy_flex_debug yyg->yy_flex_debug_r
|
||||
|
||||
/* Size of default input buffer. */
|
||||
#ifndef YY_BUF_SIZE
|
||||
#ifdef __ia64__
|
||||
/* On IA-64, the buffer size is 16k, not 8k.
|
||||
* Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
|
||||
* Ditto for the __ia64__ case accordingly.
|
||||
*/
|
||||
#define YY_BUF_SIZE 32768
|
||||
#else
|
||||
#define YY_BUF_SIZE 16384
|
||||
#endif /* __ia64__ */
|
||||
#endif
|
||||
|
||||
#ifndef YY_TYPEDEF_YY_BUFFER_STATE
|
||||
#define YY_TYPEDEF_YY_BUFFER_STATE
|
||||
typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
||||
#endif
|
||||
|
||||
#ifndef YY_TYPEDEF_YY_SIZE_T
|
||||
#define YY_TYPEDEF_YY_SIZE_T
|
||||
typedef size_t yy_size_t;
|
||||
#endif
|
||||
|
||||
#ifndef YY_STRUCT_YY_BUFFER_STATE
|
||||
#define YY_STRUCT_YY_BUFFER_STATE
|
||||
struct yy_buffer_state
|
||||
{
|
||||
FILE *yy_input_file;
|
||||
|
||||
char *yy_ch_buf; /* input buffer */
|
||||
char *yy_buf_pos; /* current position in input buffer */
|
||||
|
||||
/* Size of input buffer in bytes, not including room for EOB
|
||||
* characters.
|
||||
*/
|
||||
yy_size_t yy_buf_size;
|
||||
|
||||
/* Number of characters read into yy_ch_buf, not including EOB
|
||||
* characters.
|
||||
*/
|
||||
int yy_n_chars;
|
||||
|
||||
/* Whether we "own" the buffer - i.e., we know we created it,
|
||||
* and can realloc() it to grow it, and should free() it to
|
||||
* delete it.
|
||||
*/
|
||||
int yy_is_our_buffer;
|
||||
|
||||
/* Whether this is an "interactive" input source; if so, and
|
||||
* if we're using stdio for input, then we want to use getc()
|
||||
* instead of fread(), to make sure we stop fetching input after
|
||||
* each newline.
|
||||
*/
|
||||
int yy_is_interactive;
|
||||
|
||||
/* Whether we're considered to be at the beginning of a line.
|
||||
* If so, '^' rules will be active on the next match, otherwise
|
||||
* not.
|
||||
*/
|
||||
int yy_at_bol;
|
||||
|
||||
int yy_bs_lineno; /**< The line count. */
|
||||
int yy_bs_column; /**< The column count. */
|
||||
|
||||
/* Whether to try to fill the input buffer when we reach the
|
||||
* end of it.
|
||||
*/
|
||||
int yy_fill_buffer;
|
||||
|
||||
int yy_buffer_status;
|
||||
|
||||
};
|
||||
#endif /* !YY_STRUCT_YY_BUFFER_STATE */
|
||||
|
||||
void jq_yyrestart (FILE *input_file ,yyscan_t yyscanner );
|
||||
void jq_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
|
||||
YY_BUFFER_STATE jq_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
|
||||
void jq_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
|
||||
void jq_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
|
||||
void jq_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
|
||||
void jq_yypop_buffer_state (yyscan_t yyscanner );
|
||||
|
||||
YY_BUFFER_STATE jq_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
|
||||
YY_BUFFER_STATE jq_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
|
||||
YY_BUFFER_STATE jq_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
|
||||
|
||||
void *jq_yyalloc (yy_size_t ,yyscan_t yyscanner );
|
||||
void *jq_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
|
||||
void jq_yyfree (void * ,yyscan_t yyscanner );
|
||||
|
||||
/* Begin user sect3 */
|
||||
|
||||
#define jq_yywrap(n) 1
|
||||
#define YY_SKIP_YYWRAP
|
||||
|
||||
#define yytext_ptr yytext_r
|
||||
|
||||
#ifdef YY_HEADER_EXPORT_START_CONDITIONS
|
||||
#define INITIAL 0
|
||||
#define IN_PAREN 1
|
||||
#define IN_BRACKET 2
|
||||
#define IN_BRACE 3
|
||||
#define IN_QQINTERP 4
|
||||
#define IN_QQSTRING 5
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef YY_NO_UNISTD_H
|
||||
/* Special case for "unistd.h", since it is non-ANSI. We include it way
|
||||
* down here because we want the user's section 1 to have been scanned first.
|
||||
* The user has a chance to override it with an option.
|
||||
*/
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define YY_EXTRA_TYPE int
|
||||
|
||||
int jq_yylex_init (yyscan_t* scanner);
|
||||
|
||||
int jq_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
|
||||
|
||||
/* Accessor methods to globals.
|
||||
These are made visible to non-reentrant scanners for convenience. */
|
||||
|
||||
int jq_yylex_destroy (yyscan_t yyscanner );
|
||||
|
||||
int jq_yyget_debug (yyscan_t yyscanner );
|
||||
|
||||
void jq_yyset_debug (int debug_flag ,yyscan_t yyscanner );
|
||||
|
||||
YY_EXTRA_TYPE jq_yyget_extra (yyscan_t yyscanner );
|
||||
|
||||
void jq_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
|
||||
|
||||
FILE *jq_yyget_in (yyscan_t yyscanner );
|
||||
|
||||
void jq_yyset_in (FILE * in_str ,yyscan_t yyscanner );
|
||||
|
||||
FILE *jq_yyget_out (yyscan_t yyscanner );
|
||||
|
||||
void jq_yyset_out (FILE * out_str ,yyscan_t yyscanner );
|
||||
|
||||
int jq_yyget_leng (yyscan_t yyscanner );
|
||||
|
||||
char *jq_yyget_text (yyscan_t yyscanner );
|
||||
|
||||
int jq_yyget_lineno (yyscan_t yyscanner );
|
||||
|
||||
void jq_yyset_lineno (int line_number ,yyscan_t yyscanner );
|
||||
|
||||
YYSTYPE * jq_yyget_lval (yyscan_t yyscanner );
|
||||
|
||||
void jq_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
|
||||
|
||||
YYLTYPE *jq_yyget_lloc (yyscan_t yyscanner );
|
||||
|
||||
void jq_yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner );
|
||||
|
||||
/* Macros after this point can all be overridden by user definitions in
|
||||
* section 1.
|
||||
*/
|
||||
|
||||
#ifndef YY_SKIP_YYWRAP
|
||||
#ifdef __cplusplus
|
||||
extern "C" int jq_yywrap (yyscan_t yyscanner );
|
||||
#else
|
||||
extern int jq_yywrap (yyscan_t yyscanner );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef yytext_ptr
|
||||
static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
|
||||
#endif
|
||||
|
||||
#ifdef YY_NEED_STRLEN
|
||||
static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
|
||||
#endif
|
||||
|
||||
#ifndef YY_NO_INPUT
|
||||
|
||||
#endif
|
||||
|
||||
/* Amount of stuff to slurp up with each read. */
|
||||
#ifndef YY_READ_BUF_SIZE
|
||||
#ifdef __ia64__
|
||||
/* On IA-64, the buffer size is 16k, not 8k */
|
||||
#define YY_READ_BUF_SIZE 16384
|
||||
#else
|
||||
#define YY_READ_BUF_SIZE 8192
|
||||
#endif /* __ia64__ */
|
||||
#endif
|
||||
|
||||
/* Number of entries by which start-condition stack grows. */
|
||||
#ifndef YY_START_STACK_INCR
|
||||
#define YY_START_STACK_INCR 25
|
||||
#endif
|
||||
|
||||
/* Default declaration of generated scanner - a define so the user can
|
||||
* easily add parameters.
|
||||
*/
|
||||
#ifndef YY_DECL
|
||||
#define YY_DECL_IS_OURS 1
|
||||
|
||||
extern int jq_yylex \
|
||||
(YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
|
||||
|
||||
#define YY_DECL int jq_yylex \
|
||||
(YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
|
||||
#endif /* !YY_DECL */
|
||||
|
||||
/* yy_get_previous_state - get the state just before the EOB char was reached */
|
||||
|
||||
#undef YY_NEW_FILE
|
||||
#undef YY_FLUSH_BUFFER
|
||||
#undef yy_set_bol
|
||||
#undef yy_new_buffer
|
||||
#undef yy_set_interactive
|
||||
#undef YY_DO_BEFORE_ACTION
|
||||
|
||||
#ifdef YY_DECL_IS_OURS
|
||||
#undef YY_DECL_IS_OURS
|
||||
#undef YY_DECL
|
||||
#endif
|
||||
|
||||
#line 129 "lexer.l"
|
||||
|
||||
|
||||
#line 361 "lexer.h"
|
||||
#undef jq_yyIN_HEADER
|
||||
#endif /* jq_yyHEADER_H */
|
||||
@@ -1,4 +1,5 @@
|
||||
%{
|
||||
#include <assert.h>
|
||||
#include "jv_alloc.h"
|
||||
#include "compile.h"
|
||||
|
||||
@@ -41,6 +42,9 @@ struct lexer_param;
|
||||
"!=" { return NEQ; }
|
||||
"==" { return EQ; }
|
||||
"as" { return AS; }
|
||||
"import" { return IMPORT; }
|
||||
"include" { return INCLUDE; }
|
||||
"module" { return MODULE; }
|
||||
"def" { return DEF; }
|
||||
"if" { return IF; }
|
||||
"then" { return THEN; }
|
||||
@@ -50,16 +54,24 @@ struct lexer_param;
|
||||
"or" { return OR; }
|
||||
"end" { return END; }
|
||||
"reduce" { return REDUCE; }
|
||||
"foreach" { return FOREACH; }
|
||||
"//" { return DEFINEDOR; }
|
||||
"try" { return TRY; }
|
||||
"catch" { return CATCH; }
|
||||
"label" { return LABEL; }
|
||||
"break" { return BREAK; }
|
||||
"__loc__" { return LOC; }
|
||||
"|=" { return SETPIPE; }
|
||||
"+=" { return SETPLUS; }
|
||||
"-=" { return SETMINUS; }
|
||||
"*=" { return SETMULT; }
|
||||
"/=" { return SETDIV; }
|
||||
"%=" { return SETMOD; }
|
||||
"//=" { return SETDEFINEDOR; }
|
||||
"<=" { return LESSEQ; }
|
||||
">=" { return GREATEREQ; }
|
||||
"."|"="|";"|","|":"|"|"|"+"|"-"|"*"|"/"|"\$"|"<"|">" { return yytext[0];}
|
||||
".." { return REC; }
|
||||
"."|"?"|"="|";"|","|":"|"|"|"+"|"-"|"*"|"/"|"%"|"\$"|"<"|">" { return yytext[0];}
|
||||
|
||||
"["|"{"|"(" {
|
||||
return enter(yytext[0], YY_START, yyscanner);
|
||||
@@ -92,7 +104,7 @@ struct lexer_param;
|
||||
}
|
||||
(\\[^u(]|\\u[a-zA-Z0-9]{0,4})+ {
|
||||
/* pass escapes to the json parser */
|
||||
jv escapes = jv_string_fmt("\"%.*s\"", yyleng, yytext);
|
||||
jv escapes = jv_string_fmt("\"%.*s\"", (int)yyleng, yytext);
|
||||
yylval->literal = jv_parse_sized(jv_string_value(escapes), jv_string_length_bytes(jv_copy(escapes)));
|
||||
jv_free(escapes);
|
||||
return QQSTRING_TEXT;
|
||||
@@ -107,7 +119,8 @@ struct lexer_param;
|
||||
}
|
||||
|
||||
|
||||
[a-zA-Z_][a-zA-Z_0-9]* { yylval->literal = jv_string(yytext); return IDENT;}
|
||||
([a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]* { yylval->literal = jv_string(yytext); return IDENT;}
|
||||
\.[a-zA-Z_][a-zA-Z_0-9]* { yylval->literal = jv_string(yytext+1); return FIELD;}
|
||||
|
||||
[ \n\t]+ {}
|
||||
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
#ifdef HAVE_ACOS
|
||||
LIBM_DD(acos)
|
||||
#else
|
||||
LIBM_DD_NO(acos)
|
||||
#endif
|
||||
#ifdef HAVE_ACOSH
|
||||
LIBM_DD(acosh)
|
||||
#else
|
||||
LIBM_DD_NO(acosh)
|
||||
#endif
|
||||
#ifdef HAVE_ASIN
|
||||
LIBM_DD(asin)
|
||||
#else
|
||||
LIBM_DD_NO(asin)
|
||||
#endif
|
||||
#ifdef HAVE_ASINH
|
||||
LIBM_DD(asinh)
|
||||
#else
|
||||
LIBM_DD_NO(asinh)
|
||||
#endif
|
||||
#ifdef HAVE_ATAN
|
||||
LIBM_DD(atan)
|
||||
#else
|
||||
LIBM_DD_NO(atan)
|
||||
#endif
|
||||
#ifdef HAVE_ATANH
|
||||
LIBM_DD(atanh)
|
||||
#else
|
||||
LIBM_DD_NO(atanh)
|
||||
#endif
|
||||
#ifdef HAVE_CBRT
|
||||
LIBM_DD(cbrt)
|
||||
#else
|
||||
LIBM_DD_NO(cbrt)
|
||||
#endif
|
||||
#ifdef HAVE_COS
|
||||
LIBM_DD(cos)
|
||||
#else
|
||||
LIBM_DD_NO(cos)
|
||||
#endif
|
||||
#ifdef HAVE_COSH
|
||||
LIBM_DD(cosh)
|
||||
#else
|
||||
LIBM_DD_NO(cosh)
|
||||
#endif
|
||||
#ifdef HAVE_EXP2
|
||||
LIBM_DD(exp2)
|
||||
#else
|
||||
LIBM_DD_NO(exp2)
|
||||
#endif
|
||||
#ifdef HAVE_EXP
|
||||
LIBM_DD(exp)
|
||||
#else
|
||||
LIBM_DD_NO(exp)
|
||||
#endif
|
||||
#ifdef HAVE_FLOOR
|
||||
LIBM_DD(floor)
|
||||
#else
|
||||
LIBM_DD_NO(floor)
|
||||
#endif
|
||||
#ifdef HAVE_J0
|
||||
LIBM_DD(j0)
|
||||
#else
|
||||
LIBM_DD_NO(j0)
|
||||
#endif
|
||||
#ifdef HAVE_J1
|
||||
LIBM_DD(j1)
|
||||
#else
|
||||
LIBM_DD_NO(j1)
|
||||
#endif
|
||||
#ifdef HAVE_LOG10
|
||||
LIBM_DD(log10)
|
||||
#else
|
||||
LIBM_DD_NO(log10)
|
||||
#endif
|
||||
#ifdef HAVE_LOG2
|
||||
LIBM_DD(log2)
|
||||
#else
|
||||
LIBM_DD_NO(log2)
|
||||
#endif
|
||||
#ifdef HAVE_LOG
|
||||
LIBM_DD(log)
|
||||
#else
|
||||
LIBM_DD_NO(log)
|
||||
#endif
|
||||
#ifdef HAVE_SIN
|
||||
LIBM_DD(sin)
|
||||
#else
|
||||
LIBM_DD_NO(sin)
|
||||
#endif
|
||||
#ifdef HAVE_SINH
|
||||
LIBM_DD(sinh)
|
||||
#else
|
||||
LIBM_DD_NO(sinh)
|
||||
#endif
|
||||
#ifdef HAVE_SQRT
|
||||
LIBM_DD(sqrt)
|
||||
#else
|
||||
LIBM_DD_NO(sqrt)
|
||||
#endif
|
||||
#ifdef HAVE_TAN
|
||||
LIBM_DD(tan)
|
||||
#else
|
||||
LIBM_DD_NO(tan)
|
||||
#endif
|
||||
#ifdef HAVE_TANH
|
||||
LIBM_DD(tanh)
|
||||
#else
|
||||
LIBM_DD_NO(tanh)
|
||||
#endif
|
||||
#ifdef HAVE_TGAMMA
|
||||
LIBM_DD(tgamma)
|
||||
#else
|
||||
LIBM_DD_NO(tgamma)
|
||||
#endif
|
||||
#ifdef HAVE_Y0
|
||||
LIBM_DD(y0)
|
||||
#else
|
||||
LIBM_DD_NO(y0)
|
||||
#endif
|
||||
#ifdef HAVE_Y1
|
||||
LIBM_DD(y1)
|
||||
#else
|
||||
LIBM_DD_NO(y1)
|
||||
#endif
|
||||
#ifdef HAVE_POW
|
||||
LIBM_DDD(pow)
|
||||
#else
|
||||
LIBM_DDD_NO(pow)
|
||||
#endif
|
||||
#ifdef HAVE_JN
|
||||
LIBM_DID(jn)
|
||||
#endif
|
||||
#ifdef HAVE_YN
|
||||
LIBM_DID(yn)
|
||||
#endif
|
||||
#ifdef HAVE_ATAN2
|
||||
LIBM_DDD(atan2)
|
||||
#else
|
||||
LIBM_DDD_NO(atan2)
|
||||
#endif
|
||||
#ifdef HAVE_HYPOT
|
||||
LIBM_DDD(hypot)
|
||||
#else
|
||||
LIBM_DDD_NO(hypot)
|
||||
#endif
|
||||
#ifdef HAVE_REMAINDER
|
||||
LIBM_DDD(remainder)
|
||||
#else
|
||||
LIBM_DDD_NO(remainder)
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#ifdef HAVE_SCALBN
|
||||
LIBM_DDI(scalbn)
|
||||
#endif
|
||||
#ifdef HAVE_LGAMMA_R
|
||||
LIBM_DDIP(lgamma_r)
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,393 @@
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/stat.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <shlwapi.h>
|
||||
#endif
|
||||
|
||||
#include "jq_parser.h"
|
||||
#include "locfile.h"
|
||||
#include "jv.h"
|
||||
#include "jq.h"
|
||||
#include "parser.h"
|
||||
#include "util.h"
|
||||
#include "compile.h"
|
||||
|
||||
struct lib_loading_state {
|
||||
char **names;
|
||||
block *defs;
|
||||
uint64_t ct;
|
||||
};
|
||||
static int load_library(jq_state *jq, jv lib_path, int is_data, int raw,
|
||||
const char *as, block *out_block,
|
||||
struct lib_loading_state *lib_state);
|
||||
|
||||
static int path_is_relative(jv p) {
|
||||
const char *s = jv_string_value(p);
|
||||
|
||||
#ifdef WIN32
|
||||
int res = PathIsRelativeA(s);
|
||||
#else
|
||||
int res = *s != '/';
|
||||
#endif
|
||||
jv_free(p);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// Given a lib_path to search first, creates a chain of search paths
|
||||
// in the following order:
|
||||
// 1. lib_path
|
||||
// 2. -L paths passed in on the command line (from jq_state*) or builtin list
|
||||
static jv build_lib_search_chain(jq_state *jq, jv search_path, jv jq_origin, jv lib_origin) {
|
||||
assert(jv_get_kind(search_path) == JV_KIND_ARRAY);
|
||||
jv expanded = jv_array();
|
||||
jv expanded_elt;
|
||||
jv err = jv_null();
|
||||
jv_array_foreach(search_path, i, path) {
|
||||
if (jv_get_kind(path) != JV_KIND_STRING) {
|
||||
jv_free(path);
|
||||
continue;
|
||||
}
|
||||
path = expand_path(path);
|
||||
if (!jv_is_valid(path)) {
|
||||
err = path;
|
||||
path = jv_null();
|
||||
continue;
|
||||
}
|
||||
if (strcmp(".",jv_string_value(path)) == 0) {
|
||||
expanded_elt = jv_copy(path);
|
||||
} else if (strncmp("$ORIGIN/",jv_string_value(path),sizeof("$ORIGIN/") - 1) == 0) {
|
||||
expanded_elt = jv_string_fmt("%s/%s",
|
||||
jv_string_value(jq_origin),
|
||||
jv_string_value(path) + sizeof ("$ORIGIN/") - 1);
|
||||
} else if (jv_get_kind(lib_origin) == JV_KIND_STRING &&
|
||||
path_is_relative(jv_copy(path))) {
|
||||
expanded_elt = jv_string_fmt("%s/%s",
|
||||
jv_string_value(lib_origin),
|
||||
jv_string_value(path));
|
||||
} else {
|
||||
expanded_elt = path;
|
||||
path = jv_invalid();
|
||||
}
|
||||
expanded = jv_array_append(expanded, expanded_elt);
|
||||
jv_free(path);
|
||||
}
|
||||
jv_free(jq_origin);
|
||||
jv_free(lib_origin);
|
||||
jv_free(search_path);
|
||||
return JV_ARRAY(expanded, err);
|
||||
}
|
||||
|
||||
// Doesn't actually check that name not be an absolute path, and we
|
||||
// don't have to: we always append relative paths to others (with a '/'
|
||||
// in between).
|
||||
static jv validate_relpath(jv name) {
|
||||
const char *s = jv_string_value(name);
|
||||
if (strchr(s, '\\')) {
|
||||
jv res = jv_invalid_with_msg(jv_string_fmt("Modules must be named by relative paths using '/', not '\\' (%s)", s));
|
||||
jv_free(name);
|
||||
return res;
|
||||
}
|
||||
jv components = jv_string_split(jv_copy(name), jv_string("/"));
|
||||
jv rp = jv_array_get(jv_copy(components), 0);
|
||||
components = jv_array_slice(components, 1, jv_array_length(jv_copy(components)));
|
||||
jv_array_foreach(components, i, x) {
|
||||
if (!strcmp(jv_string_value(x), "..")) {
|
||||
jv_free(x);
|
||||
jv_free(rp);
|
||||
jv_free(components);
|
||||
jv res = jv_invalid_with_msg(jv_string_fmt("Relative paths to modules may not traverse to parent directories (%s)", s));
|
||||
jv_free(name);
|
||||
return res;
|
||||
}
|
||||
if (i > 0 && jv_equal(jv_copy(x), jv_array_get(jv_copy(components), i - 1))) {
|
||||
jv_free(x);
|
||||
jv_free(rp);
|
||||
jv_free(components);
|
||||
jv res = jv_invalid_with_msg(jv_string_fmt("module names must not have equal consecutive components: %s",
|
||||
jv_string_value(name)));
|
||||
jv_free(name);
|
||||
return res;
|
||||
}
|
||||
rp = jv_string_concat(rp, jv_string_concat(jv_string("/"), x));
|
||||
}
|
||||
jv_free(components);
|
||||
jv_free(name);
|
||||
return rp;
|
||||
}
|
||||
|
||||
// Assumes name has been validated
|
||||
static jv jv_basename(jv name) {
|
||||
const char *s = jv_string_value(name);
|
||||
const char *p = strrchr(s, '/');
|
||||
if (!p)
|
||||
return name;
|
||||
jv res = jv_string_fmt("%s", p);
|
||||
jv_free(name);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Asummes validated relative path to module
|
||||
static jv find_lib(jq_state *jq, jv rel_path, jv search, const char *suffix, jv jq_origin, jv lib_origin) {
|
||||
if (jv_get_kind(search) != JV_KIND_ARRAY)
|
||||
return jv_invalid_with_msg(jv_string_fmt("Module search path must be an array"));
|
||||
if (jv_get_kind(rel_path) != JV_KIND_STRING)
|
||||
return jv_invalid_with_msg(jv_string_fmt("Module path must be a string"));
|
||||
|
||||
struct stat st;
|
||||
int ret;
|
||||
|
||||
// Ideally we should cache this somewhere
|
||||
search = build_lib_search_chain(jq, search, jq_origin, lib_origin);
|
||||
jv err = jv_array_get(jv_copy(search), 1);
|
||||
search = jv_array_get(search, 0);
|
||||
|
||||
jv bname = jv_basename(jv_copy(rel_path));
|
||||
|
||||
jv_array_foreach(search, i, spath) {
|
||||
if (jv_get_kind(spath) == JV_KIND_NULL) {
|
||||
jv_free(spath);
|
||||
break;
|
||||
}
|
||||
if (jv_get_kind(spath) != JV_KIND_STRING ||
|
||||
strcmp(jv_string_value(spath), "") == 0) {
|
||||
jv_free(spath);
|
||||
continue; /* XXX report non-strings in search path?? */
|
||||
}
|
||||
// Try ${search_dir}/${rel_path}.jq
|
||||
jv testpath = jq_realpath(jv_string_fmt("%s/%s%s",
|
||||
jv_string_value(spath),
|
||||
jv_string_value(rel_path),
|
||||
suffix));
|
||||
ret = stat(jv_string_value(testpath),&st);
|
||||
if (ret == -1 && errno == ENOENT) {
|
||||
jv_free(testpath);
|
||||
// Try ${search_dir}/$(dirname ${rel_path})/jq/main.jq
|
||||
testpath = jq_realpath(jv_string_fmt("%s/%s/%s%s",
|
||||
jv_string_value(spath),
|
||||
jv_string_value(rel_path),
|
||||
"jq/main",
|
||||
suffix));
|
||||
ret = stat(jv_string_value(testpath),&st);
|
||||
}
|
||||
if (ret == -1 && errno == ENOENT) {
|
||||
jv_free(testpath);
|
||||
// Try ${search_dir}/${rel_path}/$(basename ${rel_path}).jq
|
||||
testpath = jq_realpath(jv_string_fmt("%s/%s/%s%s",
|
||||
jv_string_value(spath),
|
||||
jv_string_value(rel_path),
|
||||
jv_string_value(bname),
|
||||
suffix));
|
||||
ret = stat(jv_string_value(testpath),&st);
|
||||
}
|
||||
if (ret == 0) {
|
||||
jv_free(err);
|
||||
jv_free(rel_path);
|
||||
jv_free(search);
|
||||
jv_free(bname);
|
||||
jv_free(spath);
|
||||
return testpath;
|
||||
}
|
||||
jv_free(testpath);
|
||||
jv_free(spath);
|
||||
}
|
||||
jv output;
|
||||
if (!jv_is_valid(err)) {
|
||||
err = jv_invalid_get_msg(err);
|
||||
output = jv_invalid_with_msg(jv_string_fmt("module not found: %s (%s)",
|
||||
jv_string_value(rel_path),
|
||||
jv_string_value(err)));
|
||||
} else {
|
||||
output = jv_invalid_with_msg(jv_string_fmt("module not found: %s",
|
||||
jv_string_value(rel_path)));
|
||||
}
|
||||
jv_free(err);
|
||||
jv_free(rel_path);
|
||||
jv_free(search);
|
||||
jv_free(bname);
|
||||
return output;
|
||||
}
|
||||
|
||||
static jv default_search(jq_state *jq, jv value) {
|
||||
if (!jv_is_valid(value)) {
|
||||
// dependent didn't say; prepend . to system search path listj
|
||||
jv_free(value);
|
||||
return jv_array_concat(JV_ARRAY(jv_string(".")), jq_get_lib_dirs(jq));
|
||||
}
|
||||
if (jv_get_kind(value) != JV_KIND_ARRAY)
|
||||
return JV_ARRAY(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
// XXX Split this into a util that takes a callback, and then...
|
||||
static int process_dependencies(jq_state *jq, jv jq_origin, jv lib_origin, block *src_block, struct lib_loading_state *lib_state) {
|
||||
jv deps = block_take_imports(src_block);
|
||||
block bk = *src_block;
|
||||
int nerrors = 0;
|
||||
const char *as_str = NULL;
|
||||
|
||||
jv_array_foreach(deps, i, dep) {
|
||||
int is_data = jv_get_kind(jv_object_get(jv_copy(dep), jv_string("is_data"))) == JV_KIND_TRUE;
|
||||
int raw = 0;
|
||||
jv v = jv_object_get(jv_copy(dep), jv_string("raw"));
|
||||
if (jv_get_kind(v) == JV_KIND_TRUE)
|
||||
raw = 1;
|
||||
jv_free(v);
|
||||
jv relpath = validate_relpath(jv_object_get(jv_copy(dep), jv_string("relpath")));
|
||||
jv as = jv_object_get(jv_copy(dep), jv_string("as"));
|
||||
assert(!jv_is_valid(as) || jv_get_kind(as) == JV_KIND_STRING);
|
||||
if (jv_get_kind(as) == JV_KIND_STRING)
|
||||
as_str = jv_string_value(as);
|
||||
jv search = default_search(jq, jv_object_get(dep, jv_string("search")));
|
||||
// dep is now freed; do not reuse
|
||||
|
||||
// find_lib does a lot of work that could be cached...
|
||||
jv resolved = find_lib(jq, relpath, search, is_data ? ".json" : ".jq", jv_copy(jq_origin), jv_copy(lib_origin));
|
||||
// XXX ...move the rest of this into a callback.
|
||||
if (!jv_is_valid(resolved)) {
|
||||
jv emsg = jv_invalid_get_msg(resolved);
|
||||
jq_report_error(jq, jv_string_fmt("jq: error: %s\n",jv_string_value(emsg)));
|
||||
jv_free(emsg);
|
||||
jv_free(as);
|
||||
jv_free(deps);
|
||||
jv_free(jq_origin);
|
||||
jv_free(lib_origin);
|
||||
return 1;
|
||||
}
|
||||
uint64_t state_idx = 0;
|
||||
for (; state_idx < lib_state->ct; ++state_idx) {
|
||||
if (strcmp(lib_state->names[state_idx],jv_string_value(resolved)) == 0)
|
||||
break;
|
||||
}
|
||||
if (state_idx < lib_state->ct) { // Found
|
||||
jv_free(resolved);
|
||||
// Bind the library to the program
|
||||
bk = block_bind_library(lib_state->defs[state_idx], bk, OP_IS_CALL_PSEUDO, as_str);
|
||||
} else { // Not found. Add it to the table before binding.
|
||||
block dep_def_block = gen_noop();
|
||||
nerrors += load_library(jq, resolved, is_data, raw, as_str, &dep_def_block, lib_state);
|
||||
// resolved has been freed
|
||||
if (nerrors == 0) {
|
||||
// Bind the library to the program
|
||||
bk = block_bind_library(dep_def_block, bk, OP_IS_CALL_PSEUDO, as_str);
|
||||
}
|
||||
}
|
||||
jv_free(as);
|
||||
}
|
||||
jv_free(lib_origin);
|
||||
jv_free(jq_origin);
|
||||
jv_free(deps);
|
||||
return nerrors;
|
||||
}
|
||||
|
||||
// Loads the library at lib_path into lib_state, putting the library's defs
|
||||
// into *out_block
|
||||
static int load_library(jq_state *jq, jv lib_path, int is_data, int raw, const char *as, block *out_block, struct lib_loading_state *lib_state) {
|
||||
int nerrors = 0;
|
||||
struct locfile* src = NULL;
|
||||
block program;
|
||||
jv data;
|
||||
if (is_data && !raw)
|
||||
data = jv_load_file(jv_string_value(lib_path), 0);
|
||||
else
|
||||
data = jv_load_file(jv_string_value(lib_path), 1);
|
||||
int state_idx;
|
||||
if (!jv_is_valid(data)) {
|
||||
if (jv_invalid_has_msg(jv_copy(data)))
|
||||
data = jv_invalid_get_msg(data);
|
||||
else
|
||||
data = jv_string("unknown error");
|
||||
jq_report_error(jq, jv_string_fmt("jq: error loading data file %s: %s\n", jv_string_value(lib_path), jv_string_value(data)));
|
||||
nerrors++;
|
||||
goto out;
|
||||
} else if (is_data) {
|
||||
// import "foo" as $bar;
|
||||
program = gen_const_global(jv_copy(data), as);
|
||||
} else {
|
||||
// import "foo" as bar;
|
||||
src = locfile_init(jq, jv_string_value(lib_path), jv_string_value(data), jv_string_length_bytes(jv_copy(data)));
|
||||
nerrors += jq_parse_library(src, &program);
|
||||
if (nerrors == 0) {
|
||||
char *lib_origin = strdup(jv_string_value(lib_path));
|
||||
nerrors += process_dependencies(jq, jq_get_jq_origin(jq),
|
||||
jv_string(dirname(lib_origin)),
|
||||
&program, lib_state);
|
||||
free(lib_origin);
|
||||
}
|
||||
}
|
||||
state_idx = lib_state->ct++;
|
||||
lib_state->names = realloc(lib_state->names, lib_state->ct * sizeof(const char *));
|
||||
lib_state->defs = realloc(lib_state->defs, lib_state->ct * sizeof(block));
|
||||
lib_state->names[state_idx] = strdup(jv_string_value(lib_path));
|
||||
lib_state->defs[state_idx] = program;
|
||||
*out_block = program;
|
||||
if (src)
|
||||
locfile_free(src);
|
||||
out:
|
||||
jv_free(lib_path);
|
||||
jv_free(data);
|
||||
return nerrors;
|
||||
}
|
||||
|
||||
// FIXME It'd be nice to have an option to search the same search path
|
||||
// as we do in process_dependencies.
|
||||
jv load_module_meta(jq_state *jq, jv mod_relpath) {
|
||||
// We can't know the caller's origin; we could though, if it was passed in
|
||||
jv lib_path = find_lib(jq, validate_relpath(mod_relpath), jq_get_lib_dirs(jq), ".jq", jq_get_jq_origin(jq), jv_null());
|
||||
if (!jv_is_valid(lib_path))
|
||||
return lib_path;
|
||||
jv meta = jv_null();
|
||||
jv data = jv_load_file(jv_string_value(lib_path), 1);
|
||||
if (jv_is_valid(data)) {
|
||||
block program;
|
||||
struct locfile* src = locfile_init(jq, jv_string_value(lib_path), jv_string_value(data), jv_string_length_bytes(jv_copy(data)));
|
||||
int nerrors = jq_parse_library(src, &program);
|
||||
if (nerrors == 0) {
|
||||
meta = block_module_meta(program);
|
||||
if (jv_get_kind(meta) == JV_KIND_NULL)
|
||||
meta = jv_object();
|
||||
meta = jv_object_set(meta, jv_string("deps"), block_take_imports(&program));
|
||||
}
|
||||
locfile_free(src);
|
||||
block_free(program);
|
||||
}
|
||||
jv_free(lib_path);
|
||||
jv_free(data);
|
||||
return meta;
|
||||
}
|
||||
|
||||
int load_program(jq_state *jq, struct locfile* src, block *out_block) {
|
||||
int nerrors = 0;
|
||||
block program;
|
||||
struct lib_loading_state lib_state = {0,0,0};
|
||||
nerrors = jq_parse(src, &program);
|
||||
if (nerrors)
|
||||
return nerrors;
|
||||
|
||||
nerrors = process_dependencies(jq, jq_get_jq_origin(jq), jq_get_prog_origin(jq), &program, &lib_state);
|
||||
block libs = gen_noop();
|
||||
for (uint64_t i = 0; i < lib_state.ct; ++i) {
|
||||
free(lib_state.names[i]);
|
||||
if (nerrors == 0 && !block_is_const(lib_state.defs[i]))
|
||||
libs = block_join(libs, lib_state.defs[i]);
|
||||
else
|
||||
block_free(lib_state.defs[i]);
|
||||
}
|
||||
free(lib_state.names);
|
||||
free(lib_state.defs);
|
||||
if (nerrors)
|
||||
block_free(program);
|
||||
else
|
||||
*out_block = block_drop_unreferenced(block_join(libs, program));
|
||||
|
||||
return nerrors;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#ifndef LINKER_H
|
||||
#define LINKER_H
|
||||
|
||||
int load_program(jq_state *jq, struct locfile* src, block *out_block);
|
||||
jv load_module_meta(jq_state *jq, jv modname);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,91 @@
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "jq.h"
|
||||
#include "jv_alloc.h"
|
||||
#include "locfile.h"
|
||||
|
||||
|
||||
struct locfile* locfile_init(jq_state *jq, const char *fname, const char* data, int length) {
|
||||
struct locfile* l = jv_mem_alloc(sizeof(struct locfile));
|
||||
l->jq = jq;
|
||||
l->fname = jv_string(fname);
|
||||
l->data = jv_mem_alloc(length);
|
||||
memcpy((char*)l->data,data,length);
|
||||
l->length = length;
|
||||
l->nlines = 1;
|
||||
l->refct = 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+1; // at start of line, not of \n
|
||||
line++;
|
||||
}
|
||||
}
|
||||
l->linemap[l->nlines] = length+1; // virtual last \n
|
||||
return l;
|
||||
}
|
||||
|
||||
struct locfile* locfile_retain(struct locfile* l) {
|
||||
l->refct++;
|
||||
return l;
|
||||
}
|
||||
void locfile_free(struct locfile* l) {
|
||||
if (--(l->refct) == 0) {
|
||||
jv_free(l->fname);
|
||||
jv_mem_free(l->linemap);
|
||||
jv_mem_free((char*)l->data);
|
||||
jv_mem_free(l);
|
||||
}
|
||||
}
|
||||
|
||||
int locfile_get_line(struct locfile* l, int pos) {
|
||||
assert(pos < l->length);
|
||||
int line = 1;
|
||||
while (l->linemap[line] <= pos) line++; // == if pos at start (before, never ==, because pos never on \n)
|
||||
assert(line-1 < l->nlines);
|
||||
return line-1;
|
||||
}
|
||||
|
||||
static int locfile_line_length(struct locfile* l, int line) {
|
||||
assert(line < l->nlines);
|
||||
return l->linemap[line+1] - l->linemap[line] -1; // -1 to omit \n
|
||||
}
|
||||
|
||||
void locfile_locate(struct locfile* l, location loc, const char* fmt, ...) {
|
||||
va_list fmtargs;
|
||||
va_start(fmtargs, fmt);
|
||||
int startline;
|
||||
int offset;
|
||||
|
||||
if (loc.start != -1) {
|
||||
startline = locfile_get_line(l, loc.start);
|
||||
offset = l->linemap[startline];
|
||||
}
|
||||
|
||||
jv m1 = jv_string_vfmt(fmt, fmtargs);
|
||||
if (!jv_is_valid(m1)) {
|
||||
jq_report_error(l->jq, m1);
|
||||
return;
|
||||
}
|
||||
if (loc.start == -1) {
|
||||
jq_report_error(l->jq, jv_string_fmt("jq: error: %s\n<unknown location>", jv_string_value(m1)));
|
||||
jv_free(m1);
|
||||
return;
|
||||
}
|
||||
jv m2 = jv_string_fmt("%s at %s, line %d:\n%.*s%*s", jv_string_value(m1),
|
||||
jv_string_value(l->fname), startline + 1,
|
||||
locfile_line_length(l, startline), l->data + offset,
|
||||
loc.start - offset, "");
|
||||
jv_free(m1);
|
||||
jq_report_error(l->jq, m2);
|
||||
return;
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
#ifndef _LOCFILE_H
|
||||
#define _LOCFILE_H
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include "jv_alloc.h"
|
||||
#ifndef LOCFILE_H
|
||||
#define LOCFILE_H
|
||||
|
||||
#include "jq.h"
|
||||
|
||||
typedef struct {
|
||||
int start, end;
|
||||
} location;
|
||||
@@ -12,68 +10,20 @@ typedef struct {
|
||||
static const location UNKNOWN_LOCATION = {-1, -1};
|
||||
|
||||
struct locfile {
|
||||
jv fname;
|
||||
const char* data;
|
||||
int length;
|
||||
int* linemap;
|
||||
int nlines;
|
||||
char *error;
|
||||
jq_state *jq;
|
||||
int refct;
|
||||
};
|
||||
|
||||
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");
|
||||
}
|
||||
struct locfile* locfile_init(jq_state *, const char *, const char *, int);
|
||||
struct locfile* locfile_retain(struct locfile *);
|
||||
int locfile_get_line(struct locfile *, int);
|
||||
void locfile_free(struct locfile *);
|
||||
void locfile_locate(struct locfile *, location, const char *, ...);
|
||||
|
||||
#endif
|
||||
Loaded 100 of 139 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user