Compare commits
710 Commits
v0.9.6
...
v0.10.0-pr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5ff33fcc6 | ||
|
|
c60979fff7 | ||
|
|
961ad6ebca | ||
|
|
f18237a005 | ||
|
|
cba93e61b4 | ||
|
|
e0a6e5d2f9 | ||
|
|
a9ee323760 | ||
|
|
977db86700 | ||
|
|
93d36d40d8 | ||
|
|
cabc7ffca8 | ||
|
|
521b70c715 | ||
|
|
b6c5503c5b | ||
|
|
e7e2ba4790 | ||
|
|
8749923f1a | ||
|
|
25a3e19384 | ||
|
|
b6b686665a | ||
|
|
4f5468469b | ||
|
|
7bc7f23125 | ||
|
|
25ed652fc0 | ||
|
|
cc2913352a | ||
|
|
ad796ebbec | ||
|
|
edd561f8ba | ||
|
|
0b1c4fb54f | ||
|
|
9f4eb4f7db | ||
|
|
f6e3a3917e | ||
|
|
1b536bf5f8 | ||
|
|
e3afdb6c02 | ||
|
|
918b36e28f | ||
|
|
ce26637410 | ||
|
|
2053c72008 | ||
|
|
275bde6461 | ||
|
|
f85382edd4 | ||
|
|
e016e92c41 | ||
|
|
2594b8e3f9 | ||
|
|
1e1ef594c8 | ||
|
|
01c660faba | ||
|
|
9f76237705 | ||
|
|
59d3e3f3da | ||
|
|
e5dd237f12 | ||
|
|
e9729bea7e | ||
|
|
d46b17d8a0 | ||
|
|
383d25226e | ||
|
|
745eff0783 | ||
|
|
ac301045b9 | ||
|
|
e1f3ca8172 | ||
|
|
4ff4ceeb22 | ||
|
|
4126992a8f | ||
|
|
fd99f63bd6 | ||
|
|
46dc7c3a77 | ||
|
|
a8cb551465 | ||
|
|
5a5674809c | ||
|
|
761e8a2ac6 | ||
|
|
dfa7effa14 | ||
|
|
09c022e209 | ||
|
|
8666a75161 | ||
|
|
68018d8d04 | ||
|
|
3d2c014801 | ||
|
|
4f9c341103 | ||
|
|
563f03554f | ||
|
|
219376044a | ||
|
|
591dac8b41 | ||
|
|
2bc96ade33 | ||
|
|
95c4456ccc | ||
|
|
6e6b8b404f | ||
|
|
27052c21be | ||
|
|
ec744f7385 | ||
|
|
d8c5105c91 | ||
|
|
acd5fb19f5 | ||
|
|
52ac486814 | ||
|
|
a64b32bf9c | ||
|
|
b299800e64 | ||
|
|
60c430abad | ||
|
|
255cce4f9a | ||
|
|
1ed99c2574 | ||
|
|
64b54d4380 | ||
|
|
6170973b48 | ||
|
|
1172e5bdce | ||
|
|
b0123567cd | ||
|
|
81598621e8 | ||
|
|
239ac496b2 | ||
|
|
76fb91619a | ||
|
|
e3a2d43ffa | ||
|
|
b3f4716616 | ||
|
|
c602038597 | ||
|
|
03b469212e | ||
|
|
db3f6e077e | ||
|
|
06816c51a5 | ||
|
|
9e9e8e82b2 | ||
|
|
031d4ebedc | ||
|
|
3446715af8 | ||
|
|
c7e68dab62 | ||
|
|
7093ced2d8 | ||
|
|
179f4dfe22 | ||
|
|
03517ce22e | ||
|
|
290f99b4d1 | ||
|
|
7f10bc2a1b | ||
|
|
9cb48003b0 | ||
|
|
6df961292d | ||
|
|
65f855b251 | ||
|
|
5131881bf2 | ||
|
|
8fbad90e9d | ||
|
|
d0aceebaad | ||
|
|
01b6680000 | ||
|
|
638883f352 | ||
|
|
467c2fb28d | ||
|
|
0fd129a0d8 | ||
|
|
282125a84b | ||
|
|
97a2824473 | ||
|
|
eff1333269 | ||
|
|
3741a28d94 | ||
|
|
6dd4ec160d | ||
|
|
a6a3c09c05 | ||
|
|
620cfeabe0 | ||
|
|
070d64f365 | ||
|
|
1d3c98372a | ||
|
|
c1588d70cd | ||
|
|
ef28abe896 | ||
|
|
d251232f8a | ||
|
|
05334de855 | ||
|
|
539b55f826 | ||
|
|
0699832240 | ||
|
|
ce169163b9 | ||
|
|
b4af70ada9 | ||
|
|
424670d854 | ||
|
|
6ce4644120 | ||
|
|
eaf7e56083 | ||
|
|
e55a5d7486 | ||
|
|
e1d14b1324 | ||
|
|
04d09eb891 | ||
|
|
09b4f5dffd | ||
|
|
29ad96862f | ||
|
|
839d68d62c | ||
|
|
a4d3bf3cb2 | ||
|
|
a05bda9fc3 | ||
|
|
5936b57bac | ||
|
|
af2bcd389e | ||
|
|
4bec9b038b | ||
|
|
0b3ce5f65a | ||
|
|
cb8e820f5d | ||
|
|
0a4ce9d65e | ||
|
|
f20d74c1f3 | ||
|
|
3505be422e | ||
|
|
7e9542e79a | ||
|
|
a1c1a4889b | ||
|
|
7eeb8084bf | ||
|
|
7a5bd6ae6a | ||
|
|
d20e60afb3 | ||
|
|
7340263e6a | ||
|
|
6e8cecd13e | ||
|
|
f106a0854f | ||
|
|
68b09e87b3 | ||
|
|
11f2ecd675 | ||
|
|
7b6b8b0eeb | ||
|
|
67f9580c5d | ||
|
|
6a3fce97cf | ||
|
|
2bd266a7fc | ||
|
|
f6946b88d2 | ||
|
|
5e5df6becd | ||
|
|
6c4cb92249 | ||
|
|
c3407eac5e | ||
|
|
e46b3e24d6 | ||
|
|
90763de93c | ||
|
|
5380ffa471 | ||
|
|
c9f436cc47 | ||
|
|
39dc68fa4e | ||
|
|
d6c527f662 | ||
|
|
38a7f4f7d5 | ||
|
|
1605959a04 | ||
|
|
b837e0005a | ||
|
|
58937a5366 | ||
|
|
8562c03f80 | ||
|
|
1cd61b9169 | ||
|
|
c69e289afe | ||
|
|
91b46b05ad | ||
|
|
2412760f1c | ||
|
|
d83c5493c7 | ||
|
|
d041703dc6 | ||
|
|
ecba13c38e | ||
|
|
cd3a4bb8c8 | ||
|
|
97f72b93e1 | ||
|
|
e93d57983e | ||
|
|
43c4a3bfdc | ||
|
|
954cc0e8bc | ||
|
|
ad48325dff | ||
|
|
fa1ad20d5d | ||
|
|
0547dede21 | ||
|
|
284ae23db2 | ||
|
|
9105f28c13 | ||
|
|
06cc43b11f | ||
|
|
d879d0d924 | ||
|
|
25bc84817a | ||
|
|
8fb0dfad94 | ||
|
|
c2138037d2 | ||
|
|
fadd64c1e9 | ||
|
|
4552691aed | ||
|
|
bab5c0589f | ||
|
|
2a2c614eb4 | ||
|
|
12529ec81e | ||
|
|
0179609a49 | ||
|
|
860c551aa6 | ||
|
|
1ba3474a5a | ||
|
|
f26c283541 | ||
|
|
56e9dab2ce | ||
|
|
b1fcae5cec | ||
|
|
93245ac37a | ||
|
|
3f795e44c7 | ||
|
|
e732e5158e | ||
|
|
2f5c033f09 | ||
|
|
6099369019 | ||
|
|
8d2b65386c | ||
|
|
ed835225cf | ||
|
|
43c1bc8d5f | ||
|
|
17832fe18c | ||
|
|
252f3f0bd6 | ||
|
|
e042aad819 | ||
|
|
9966daf0cf | ||
|
|
daf5e9cccf | ||
|
|
bf63d731d3 | ||
|
|
12abfc0fcf | ||
|
|
dea1b520f7 | ||
|
|
a5c268491e | ||
|
|
bf34f553bb | ||
|
|
97c61404ca | ||
|
|
c40d9f54a2 | ||
|
|
5e08593358 | ||
|
|
1f06b12f86 | ||
|
|
c7351f724e | ||
|
|
1851bce497 | ||
|
|
5fb8503fd2 | ||
|
|
792716eefc | ||
|
|
15a6c779b8 | ||
|
|
93d24e7106 | ||
|
|
b8a185c112 | ||
|
|
e242e65569 | ||
|
|
62ab33a434 | ||
|
|
f403916ef8 | ||
|
|
38f1585ac6 | ||
|
|
1f757270d9 | ||
|
|
e6de8401bf | ||
|
|
df2e34ac51 | ||
|
|
7bbd3a7e36 | ||
|
|
85a736d49b | ||
|
|
f9eb313f7c | ||
|
|
9cec486a1b | ||
|
|
7734c654a7 | ||
|
|
8e5fff6c5f | ||
|
|
faa9a740db | ||
|
|
70e39e9902 | ||
|
|
9f0b3963cb | ||
|
|
7ec2ce851c | ||
|
|
94ee4223d2 | ||
|
|
a64f4219e9 | ||
|
|
78e96cc312 | ||
|
|
89b111edca | ||
|
|
ec38943c53 | ||
|
|
ea654ef235 | ||
|
|
288b705450 | ||
|
|
73ca579056 | ||
|
|
8b5d7dc181 | ||
|
|
f05f6294cd | ||
|
|
b2c466cf3f | ||
|
|
da1b9a0e91 | ||
|
|
6cbb5a9215 | ||
|
|
cfdbb86bfa | ||
|
|
d61783b2c0 | ||
|
|
65c1e1b9e5 | ||
|
|
17d509a45a | ||
|
|
c7649766fd | ||
|
|
c0ec5e53ba | ||
|
|
a0a18017e8 | ||
|
|
411b84fcc2 | ||
|
|
e499eeb8cc | ||
|
|
803d1de5db | ||
|
|
fc8117c8e7 | ||
|
|
8bef0ede1b | ||
|
|
88128cde48 | ||
|
|
d0217e62f0 | ||
|
|
bba680b636 | ||
|
|
feb914b5c4 | ||
|
|
0a65ea34f3 | ||
|
|
bf299edfc7 | ||
|
|
6b0122547e | ||
|
|
88c0e149b5 | ||
|
|
38091b2021 | ||
|
|
ce87f293aa | ||
|
|
dca028a84f | ||
|
|
be3c4ab24a | ||
|
|
67c9a14902 | ||
|
|
014bdb795f | ||
|
|
df7e8b2e64 | ||
|
|
2b5fdd3548 | ||
|
|
e92a0eb901 | ||
|
|
e72a67f5de | ||
|
|
65dc291ff5 | ||
|
|
0bfc190a86 | ||
|
|
f8303f2e7a | ||
|
|
8ad72b167c | ||
|
|
7747082ae8 | ||
|
|
a7727adca2 | ||
|
|
028b53816d | ||
|
|
5a77117a9b | ||
|
|
05777019c8 | ||
|
|
7ebaad5099 | ||
|
|
09885c8f41 | ||
|
|
4f5ebb279d | ||
|
|
91ebf88c97 | ||
|
|
a608c51e36 | ||
|
|
3877dcf83a | ||
|
|
72d176b77a | ||
|
|
8840968e07 | ||
|
|
b6b889bff6 | ||
|
|
a30bdcbb50 | ||
|
|
82275d49a6 | ||
|
|
ee335de222 | ||
|
|
01bf7c8c38 | ||
|
|
5529a1b0b3 | ||
|
|
363be18599 | ||
|
|
ae8ad3b68b | ||
|
|
348b850e36 | ||
|
|
92c267758e | ||
|
|
b7d1ab6105 | ||
|
|
f7f1b4f594 | ||
|
|
6492bea846 | ||
|
|
b1cb89b0c2 | ||
|
|
7ecd98b0a0 | ||
|
|
7d7d4db329 | ||
|
|
e6bfe1fc88 | ||
|
|
151d3a9610 | ||
|
|
905ed36afd | ||
|
|
7fe9c9366e | ||
|
|
d5237d1a07 | ||
|
|
7bd3b29a11 | ||
|
|
60aa74257f | ||
|
|
ca0492d997 | ||
|
|
944133de6e | ||
|
|
174fdd40da | ||
|
|
ffa823f748 | ||
|
|
a83f7a822e | ||
|
|
29d527bee1 | ||
|
|
75e282c2ac | ||
|
|
8419d9114b | ||
|
|
1c414af7b9 | ||
|
|
834e8c64c5 | ||
|
|
1b3bb86546 | ||
|
|
aa560f42e7 | ||
|
|
4e69cd28cd | ||
|
|
5f0e30e17a | ||
|
|
d682771c35 | ||
|
|
ace3c3e421 | ||
|
|
94005b0c22 | ||
|
|
e9177c8932 | ||
|
|
d62c2d913e | ||
|
|
9ea88fe247 | ||
|
|
e0867a5d11 | ||
|
|
ae91101ea1 | ||
|
|
515057c41a | ||
|
|
d946ba426e | ||
|
|
07874cf77f | ||
|
|
1d9f9e838b | ||
|
|
101691e970 | ||
|
|
e2498c31ea | ||
|
|
9d8c6122cc | ||
|
|
227dda38a2 | ||
|
|
e2091413ea | ||
|
|
4976e82f0f | ||
|
|
5e949d2c6f | ||
|
|
fec7688241 | ||
|
|
2732f6036e | ||
|
|
387c44031a | ||
|
|
6cbd1c5fb1 | ||
|
|
447b9e1ea7 | ||
|
|
be08bcaafc | ||
|
|
1b5e8e0181 | ||
|
|
d2ffbd0395 | ||
|
|
88cb607975 | ||
|
|
e392956e2a | ||
|
|
3028081fa2 | ||
|
|
4003c59471 | ||
|
|
2e042f0c59 | ||
|
|
9a4238d4e2 | ||
|
|
c184dc8d2f | ||
|
|
32f41a04ac | ||
|
|
4b8174f75a | ||
|
|
313e14bc54 | ||
|
|
7aca31992b | ||
|
|
56f53e508f | ||
|
|
6c18dc63aa | ||
|
|
7b498065b5 | ||
|
|
81bd225ff7 | ||
|
|
074090a0aa | ||
|
|
3fcbcca8e4 | ||
|
|
dbaf12b043 | ||
|
|
9eb9b48534 | ||
|
|
e085fd1d57 | ||
|
|
9cc71b320b | ||
|
|
7b74cf1ab9 | ||
|
|
fb0c0e07f7 | ||
|
|
c6bb4a23ae | ||
|
|
70e271959b | ||
|
|
379abeb262 | ||
|
|
9e884847b1 | ||
|
|
5dadf9a087 | ||
|
|
c0630b782a | ||
|
|
62beb73aa2 | ||
|
|
7b6fe0159f | ||
|
|
dad22b1686 | ||
|
|
a715a51865 | ||
|
|
d4ec2319f9 | ||
|
|
88b980ac17 | ||
|
|
867c01d5e8 | ||
|
|
c8a064af3e | ||
|
|
12439f2b99 | ||
|
|
fb47ea301f | ||
|
|
6adecbd7aa | ||
|
|
f71e34fd9f | ||
|
|
dfe89588f0 | ||
|
|
d89b68a279 | ||
|
|
2a4a01cb7b | ||
|
|
c81b7f6bb4 | ||
|
|
0c11afad7a | ||
|
|
d6b26c9975 | ||
|
|
98c628f3eb | ||
|
|
36b2026075 | ||
|
|
7c535ff1a3 | ||
|
|
c6436ea6d1 | ||
|
|
5a8dee3cbe | ||
|
|
d9450d6e12 | ||
|
|
80377b3705 | ||
|
|
847a76b3a2 | ||
|
|
2c3d46bb80 | ||
|
|
e0cb6d4531 | ||
|
|
78f0177ac4 | ||
|
|
4688434c08 | ||
|
|
8913eeb1c1 | ||
|
|
75574e97cc | ||
|
|
f4089bc164 | ||
|
|
b0f04d91bf | ||
|
|
3b514d194c | ||
|
|
3ba405383e | ||
|
|
87f6c8087f | ||
|
|
90a83c8f11 | ||
|
|
27f892a14b | ||
|
|
bf4525d82d | ||
|
|
6bfb1a7fff | ||
|
|
a53ab7438c | ||
|
|
d85a080f9b | ||
|
|
4dbfc9483e | ||
|
|
53097ab183 | ||
|
|
9978a370f1 | ||
|
|
24995f46cb | ||
|
|
7ddc8c6aeb | ||
|
|
4a447f5c12 | ||
|
|
e56647f24d | ||
|
|
25238b53c9 | ||
|
|
1ed798342a | ||
|
|
1d6eb07c62 | ||
|
|
8e3d76b7ea | ||
|
|
d8838503b2 | ||
|
|
78b7742354 | ||
|
|
3d9dca47b8 | ||
|
|
c06c96bc1f | ||
|
|
db128dbc40 | ||
|
|
d6f87a8254 | ||
|
|
4c5f37db0f | ||
|
|
3e5338c902 | ||
|
|
848b7c7a34 | ||
|
|
4bf5dd15e9 | ||
|
|
d4273d8e3f | ||
|
|
780347776b | ||
|
|
5dd6986ad4 | ||
|
|
51bf41009e | ||
|
|
4defe734e2 | ||
|
|
e3cb4ebfdc | ||
|
|
c6345279cc | ||
|
|
e5a9af9a31 | ||
|
|
c0e1e31572 | ||
|
|
1e58c365ed | ||
|
|
bf87b76adb | ||
|
|
c8e06b5837 | ||
|
|
ee5cd06077 | ||
|
|
140352b637 | ||
|
|
b369321e2f | ||
|
|
b9aaba7b16 | ||
|
|
07519732a1 | ||
|
|
ae71f3c186 | ||
|
|
e1236f9deb | ||
|
|
3c9bfb5b4d | ||
|
|
86b50b0a93 | ||
|
|
da6706cb93 | ||
|
|
2842a109da | ||
|
|
021ddefb10 | ||
|
|
7d0b47c5cb | ||
|
|
9351a1f900 | ||
|
|
0ac48369fe | ||
|
|
e57ee17532 | ||
|
|
a897683272 | ||
|
|
38eb981d2c | ||
|
|
b524472b9e | ||
|
|
fc04083cb2 | ||
|
|
b1225951f2 | ||
|
|
24fd2e1849 | ||
|
|
5e5c975a9c | ||
|
|
c6336e920f | ||
|
|
cd19625522 | ||
|
|
3ac95a9213 | ||
|
|
e57ea9b501 | ||
|
|
14b335a51e | ||
|
|
319e746a55 | ||
|
|
eb4d721175 | ||
|
|
a4f850c0c6 | ||
|
|
0a8e25b405 | ||
|
|
1557a76225 | ||
|
|
d4fa379f11 | ||
|
|
e09c5fcb3c | ||
|
|
815fe25f2c | ||
|
|
5e5c84ba27 | ||
|
|
2974b23f26 | ||
|
|
697c21b120 | ||
|
|
1f72a52015 | ||
|
|
43bcf1051d | ||
|
|
bf8aa502f9 | ||
|
|
f0e92343cb | ||
|
|
48efd6689e | ||
|
|
090e689689 | ||
|
|
9d16df5f25 | ||
|
|
02651c93a7 | ||
|
|
2b1d4b6672 | ||
|
|
9087dac6fe | ||
|
|
762ed994c1 | ||
|
|
2c8a9d1160 | ||
|
|
f613316046 | ||
|
|
6b1bc15f37 | ||
|
|
9a77a0c201 | ||
|
|
755cdbb238 | ||
|
|
1996db4b95 | ||
|
|
6297f69e70 | ||
|
|
a796f9f8a8 | ||
|
|
0de9c57ade | ||
|
|
95dc01cdcb | ||
|
|
364d3996f4 | ||
|
|
33af9e878b | ||
|
|
9f8b9ea806 | ||
|
|
d53876ee1b | ||
|
|
4f654e81c8 | ||
|
|
aa33ddcf19 | ||
|
|
c8a57676b4 | ||
|
|
d0d2bc1996 | ||
|
|
2b8d2b0026 | ||
|
|
735953a262 | ||
|
|
1c686f10a1 | ||
|
|
b7088510c5 | ||
|
|
3bdb921ee5 | ||
|
|
74b48ff56b | ||
|
|
9410370cc5 | ||
|
|
743ddf83c1 | ||
|
|
caa707325a | ||
|
|
3c588e67b8 | ||
|
|
6c26dad048 | ||
|
|
393e2c125e | ||
|
|
e56dc2ed6a | ||
|
|
4a449ed85e | ||
|
|
88dbe90075 | ||
|
|
a6f6451434 | ||
|
|
8a4370c1f6 | ||
|
|
7a068450b3 | ||
|
|
ae3222e4c2 | ||
|
|
27b4bfa3fa | ||
|
|
8af229947f | ||
|
|
f235a2f539 | ||
|
|
b0ebb479f6 | ||
|
|
df92e21520 | ||
|
|
a1a25cc57f | ||
|
|
e9aaf8e0af | ||
|
|
7a80e407af | ||
|
|
57f8d535fb | ||
|
|
170a6096b9 | ||
|
|
fcc444a100 | ||
|
|
8ccb3c21e1 | ||
|
|
0484d4bb77 | ||
|
|
3ce9567f62 | ||
|
|
765e812b77 | ||
|
|
1a63c9296b | ||
|
|
9510b5aea5 | ||
|
|
490e859fbf | ||
|
|
85c4a2fdc2 | ||
|
|
3b9c9f6a97 | ||
|
|
d1f64d3059 | ||
|
|
f62bcdc803 | ||
|
|
2434fd778f | ||
|
|
1a38726fb7 | ||
|
|
24cffb2a69 | ||
|
|
527918545e | ||
|
|
4d268f67ae | ||
|
|
a65c2f4312 | ||
|
|
c490f2b849 | ||
|
|
282f7fc2e3 | ||
|
|
52348af8ec | ||
|
|
39d15ead6f | ||
|
|
d232109fce | ||
|
|
8e9c43610d | ||
|
|
53a8c20cb9 | ||
|
|
333f60a2a6 | ||
|
|
0bacc20a58 | ||
|
|
3e932c9bdf | ||
|
|
cf8a170133 | ||
|
|
67a89d4b6b | ||
|
|
85c2cda7b6 | ||
|
|
61757a6518 | ||
|
|
e245d08e54 | ||
|
|
29f797dc24 | ||
|
|
54ce1d8d2f | ||
|
|
8e47f70066 | ||
|
|
01548089ee | ||
|
|
de8d598f46 | ||
|
|
63aad4b9bf | ||
|
|
33cdb7a541 | ||
|
|
7c2f769a9a | ||
|
|
e084550390 | ||
|
|
3c282e8cf9 | ||
|
|
3c4fbdb50e | ||
|
|
18cdc28963 | ||
|
|
5f004e7167 | ||
|
|
96489607ab | ||
|
|
7436e44416 | ||
|
|
8d30e51603 | ||
|
|
64b582e397 | ||
|
|
8b86d07bfc | ||
|
|
e3fefdebe1 | ||
|
|
46aec4a593 | ||
|
|
2feb3e1d7a | ||
|
|
2609f45799 | ||
|
|
9053cbb90f | ||
|
|
3794d7ab65 | ||
|
|
7eeca21a05 | ||
|
|
70464154c7 | ||
|
|
1b29078fad | ||
|
|
864b078610 | ||
|
|
1a8b319ce2 | ||
|
|
a353514fc8 | ||
|
|
06e294fb3e | ||
|
|
961d4c4a3a | ||
|
|
876aea39e5 | ||
|
|
67be2ba95b | ||
|
|
53d2d080f4 | ||
|
|
998fbeb381 | ||
|
|
1c6e4b7750 | ||
|
|
8fbe21c79c | ||
|
|
d6d0faac6e | ||
|
|
2d4f01e6cb | ||
|
|
b42ad3170e | ||
|
|
a8dddc81f1 | ||
|
|
2e1e6f784b | ||
|
|
2af9b95c7a | ||
|
|
90be010c2b | ||
|
|
3b6b16cf77 | ||
|
|
c0c5c87c29 | ||
|
|
f5bbf4b515 | ||
|
|
c7465608a7 | ||
|
|
03f0a4289b | ||
|
|
bb2a6b73fe | ||
|
|
8e66091dd2 | ||
|
|
a5c114a848 | ||
|
|
254b2c27ac | ||
|
|
29fcb4504c | ||
|
|
ec7402b80a | ||
|
|
4501519c4f | ||
|
|
58ad7dab1b | ||
|
|
4da26a2f8d | ||
|
|
9e6aed0760 | ||
|
|
7033f11d56 | ||
|
|
8fcac42f34 | ||
|
|
4a6a97ee75 | ||
|
|
2174d8fe8c | ||
|
|
eb6f487e2a | ||
|
|
6bbe68dfcb | ||
|
|
bbeceae42e | ||
|
|
cfe785762d | ||
|
|
fdbb329fb6 | ||
|
|
9f1100b967 | ||
|
|
94706d6139 | ||
|
|
b63609e2fa | ||
|
|
84c420139d | ||
|
|
027d21035e | ||
|
|
cc9de01c99 | ||
|
|
61c6f240e9 | ||
|
|
997d673b83 | ||
|
|
6c72846d63 | ||
|
|
8bd6e1d119 | ||
|
|
6484a8e6a4 | ||
|
|
0e8e108680 | ||
|
|
3435b6c4a4 | ||
|
|
d4af6af594 | ||
|
|
b834abd293 | ||
|
|
01a6dd79c4 | ||
|
|
948b6cf7e7 | ||
|
|
b1718f329e | ||
|
|
7237f549a6 | ||
|
|
30b1660005 | ||
|
|
200fe07473 | ||
|
|
86cb22d8c9 | ||
|
|
321766fd46 | ||
|
|
3eedad96ed | ||
|
|
4b26dac08a | ||
|
|
04ef069a20 | ||
|
|
b925ed60e3 | ||
|
|
dfd85a7c53 | ||
|
|
6ca63d4c68 | ||
|
|
2325b547fd | ||
|
|
34e454c054 | ||
|
|
302386d22c |
48
.github/actions/setup-deps/action.yml
vendored
Normal file
48
.github/actions/setup-deps/action.yml
vendored
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
name: "Setup LLGO Dependencies"
|
||||||
|
description: "Install all required dependencies for LLGO"
|
||||||
|
inputs:
|
||||||
|
llvm-version:
|
||||||
|
description: "LLVM version to install"
|
||||||
|
required: true
|
||||||
|
default: "18"
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Install macOS dependencies
|
||||||
|
if: runner.os == 'macOS'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
brew update
|
||||||
|
brew install llvm@${{inputs.llvm-version}} bdw-gc openssl libffi
|
||||||
|
brew link --force libffi
|
||||||
|
echo "$(brew --prefix llvm@${{inputs.llvm-version}})/bin" >> $GITHUB_PATH
|
||||||
|
|
||||||
|
# Install optional deps for demos.
|
||||||
|
#
|
||||||
|
# NOTE: Keep this list updated as new deps are introduced.
|
||||||
|
opt_deps=(
|
||||||
|
cjson # for github.com/goplus/llgo/c/cjson
|
||||||
|
sqlite # for github.com/goplus/llgo/c/sqlite
|
||||||
|
python@3.12 # for github.com/goplus/llgo/py
|
||||||
|
)
|
||||||
|
brew install "${opt_deps[@]}"
|
||||||
|
- name: Install Ubuntu dependencies
|
||||||
|
if: runner.os == 'Linux'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-${{inputs.llvm-version}} main" | sudo tee /etc/apt/sources.list.d/llvm.list
|
||||||
|
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y llvm-${{inputs.llvm-version}}-dev clang-${{inputs.llvm-version}} libclang-${{inputs.llvm-version}}-dev lld-${{inputs.llvm-version}} pkg-config libgc-dev libssl-dev zlib1g-dev libffi-dev libcjson-dev libunwind-dev
|
||||||
|
echo "/usr/lib/llvm-${{inputs.llvm-version}}/bin" >> $GITHUB_PATH
|
||||||
|
|
||||||
|
# Install optional deps for demos.
|
||||||
|
#
|
||||||
|
# NOTE: Keep this list updated as new deps are introduced.
|
||||||
|
opt_deps=(
|
||||||
|
libcjson-dev # for github.com/goplus/llgo/c/cjson
|
||||||
|
libsqlite3-dev # for github.com/goplus/llgo/c/sqlite
|
||||||
|
python3.12-dev # for github.com/goplus/llgo/py
|
||||||
|
)
|
||||||
|
sudo apt-get install -y "${opt_deps[@]}"
|
||||||
35
.github/actions/test-helloworld/action.yml
vendored
Normal file
35
.github/actions/test-helloworld/action.yml
vendored
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
name: 'Test Hello World'
|
||||||
|
description: 'Test Hello World with specific Go and module versions'
|
||||||
|
inputs:
|
||||||
|
go-version:
|
||||||
|
description: 'Go version being tested'
|
||||||
|
required: true
|
||||||
|
mod-version:
|
||||||
|
description: 'Go module version to use'
|
||||||
|
required: true
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Test Hello World
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "Testing with Go ${{ inputs.go-version }} and go.mod ${{ inputs.mod-version }}"
|
||||||
|
mkdir -p _test/helloworld && cd _test/helloworld
|
||||||
|
cat > go.mod << 'EOL'
|
||||||
|
module hello
|
||||||
|
go ${{ inputs.mod-version }}
|
||||||
|
EOL
|
||||||
|
cat > main.go << 'EOL'
|
||||||
|
package main
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
)
|
||||||
|
func main() {
|
||||||
|
fmt.Println("Hello, LLGo!")
|
||||||
|
println("Hello, LLGo!")
|
||||||
|
c.Printf(c.Str("Hello, LLGo!\n"))
|
||||||
|
}
|
||||||
|
EOL
|
||||||
|
go mod tidy
|
||||||
|
llgo run .
|
||||||
3
.github/codecov.yml
vendored
Normal file
3
.github/codecov.yml
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
coverage:
|
||||||
|
ignore:
|
||||||
|
- "compiler/chore"
|
||||||
10
.github/dependabot.yml
vendored
10
.github/dependabot.yml
vendored
@@ -17,3 +17,13 @@ updates:
|
|||||||
directory: "/" # Location of package manifests
|
directory: "/" # Location of package manifests
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: "daily"
|
||||||
|
|
||||||
|
- package-ecosystem: "gomod" # See documentation for possible values
|
||||||
|
directory: "/compiler/" # Location of package manifests
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
|
||||||
|
- package-ecosystem: "gomod" # See documentation for possible values
|
||||||
|
directory: "/runtime/" # Location of package manifests
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
|||||||
75
.github/workflows/doc.yml
vendored
Normal file
75
.github/workflows/doc.yml
vendored
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
name: Docs
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "**" ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ "**" ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
doc_verify:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '20'
|
||||||
|
|
||||||
|
- name: Install embedme
|
||||||
|
run: npm install -g embedme
|
||||||
|
|
||||||
|
- name: Verify README.md embedded code
|
||||||
|
run: npx embedme --verify README.md
|
||||||
|
|
||||||
|
doc_test:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os:
|
||||||
|
- macos-latest
|
||||||
|
- ubuntu-24.04
|
||||||
|
runs-on: ${{matrix.os}}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: '1.23'
|
||||||
|
|
||||||
|
- name: Install dependencies on macOS
|
||||||
|
if: startsWith(matrix.os, 'macos')
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
source doc/_readme/scripts/install_macos.sh
|
||||||
|
|
||||||
|
- name: Install dependencies on Ubuntu
|
||||||
|
if: startsWith(matrix.os, 'ubuntu')
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
source doc/_readme/scripts/install_ubuntu.sh
|
||||||
|
|
||||||
|
- name: Install llgo
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
git() {
|
||||||
|
if [ "$1" = "clone" ]; then
|
||||||
|
# do nothing because we already have the branch
|
||||||
|
cd ..
|
||||||
|
else
|
||||||
|
command git "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
source doc/_readme/scripts/install_llgo.sh
|
||||||
|
echo "LLGO_ROOT=$GITHUB_WORKSPACE" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Test doc code blocks
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
source doc/_readme/scripts/run.sh
|
||||||
|
|
||||||
30
.github/workflows/fmt.yml
vendored
Normal file
30
.github/workflows/fmt.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
name: Format Check
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "**" ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ "**" ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
fmt:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: '1.23'
|
||||||
|
|
||||||
|
- name: Check formatting
|
||||||
|
run: |
|
||||||
|
for dir in . compiler runtime; do
|
||||||
|
pushd $dir
|
||||||
|
if [ -n "$(go fmt ./...)" ]; then
|
||||||
|
echo "Some files are not properly formatted. Please run 'go fmt ./...'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
popd
|
||||||
|
done
|
||||||
|
echo "All files are properly formatted."
|
||||||
83
.github/workflows/go.yml
vendored
83
.github/workflows/go.yml
vendored
@@ -5,12 +5,11 @@ name: Go
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ "*" ]
|
branches: [ "**" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "*" ]
|
branches: [ "**" ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
test:
|
test:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
@@ -19,53 +18,15 @@ jobs:
|
|||||||
- ubuntu-24.04
|
- ubuntu-24.04
|
||||||
llvm: [18]
|
llvm: [18]
|
||||||
runs-on: ${{matrix.os}}
|
runs-on: ${{matrix.os}}
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: compiler
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
if: startsWith(matrix.os, 'macos')
|
uses: ./.github/actions/setup-deps
|
||||||
run: |
|
with:
|
||||||
brew update
|
llvm-version: ${{matrix.llvm}}
|
||||||
brew install llvm@${{matrix.llvm}} pkg-config bdw-gc openssl
|
|
||||||
echo "$(brew --prefix llvm@${{matrix.llvm}})/bin" >> $GITHUB_PATH
|
|
||||||
|
|
||||||
# Install optional deps for demos.
|
|
||||||
#
|
|
||||||
# NOTE: Keep this list updated as new deps are introduced.
|
|
||||||
opt_deps=(
|
|
||||||
cjson # for github.com/goplus/llgo/c/cjson
|
|
||||||
sqlite # for github.com/goplus/llgo/c/sqlite
|
|
||||||
python@3.12 # for github.com/goplus/llgo/py
|
|
||||||
)
|
|
||||||
brew install "${opt_deps[@]}"
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
if: startsWith(matrix.os, 'ubuntu')
|
|
||||||
run: |
|
|
||||||
echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-${{matrix.llvm}} main" | sudo tee /etc/apt/sources.list.d/llvm.list
|
|
||||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y llvm-${{matrix.llvm}}-dev clang-${{matrix.llvm}} lld-${{matrix.llvm}} pkg-config libgc-dev libssl-dev zlib1g-dev
|
|
||||||
echo "/usr/lib/llvm-${{matrix.llvm}}/bin" >> $GITHUB_PATH
|
|
||||||
|
|
||||||
# Install optional deps for demos.
|
|
||||||
#
|
|
||||||
# NOTE: Keep this list updated as new deps are introduced.
|
|
||||||
opt_deps=(
|
|
||||||
libcjson-dev # for github.com/goplus/llgo/c/cjson
|
|
||||||
libsqlite3-dev # for github.com/goplus/llgo/c/sqlite
|
|
||||||
python3.12-dev # for github.com/goplus/llgo/py
|
|
||||||
)
|
|
||||||
sudo apt-get install -y "${opt_deps[@]}"
|
|
||||||
|
|
||||||
- name: Install further optional dependencies for demos
|
|
||||||
run: |
|
|
||||||
wget -P ./_demo/llama2-c https://huggingface.co/karpathy/tinyllamas/resolve/main/stories15M.bin
|
|
||||||
py_deps=(
|
|
||||||
numpy # for github.com/goplus/llgo/py/numpy
|
|
||||||
torch # for github.com/goplus/llgo/py/torch
|
|
||||||
)
|
|
||||||
pip3 install --break-system-packages "${py_deps[@]}"
|
|
||||||
|
|
||||||
- name: Clang information
|
- name: Clang information
|
||||||
run: |
|
run: |
|
||||||
@@ -76,7 +37,7 @@ jobs:
|
|||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.20'
|
go-version: '1.23'
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: go build -v ./...
|
run: go build -v ./...
|
||||||
@@ -89,31 +50,7 @@ jobs:
|
|||||||
if: startsWith(matrix.os, 'macos')
|
if: startsWith(matrix.os, 'macos')
|
||||||
run: go test -v -coverprofile="coverage.txt" -covermode=atomic ./...
|
run: go test -v -coverprofile="coverage.txt" -covermode=atomic ./...
|
||||||
|
|
||||||
- name: Install
|
|
||||||
run: go install ./...
|
|
||||||
|
|
||||||
- name: LLGO tests
|
|
||||||
if: ${{!startsWith(matrix.os, 'ubuntu')}}
|
|
||||||
run: |
|
|
||||||
echo "Test result on ${{matrix.os}} with LLVM ${{matrix.llvm}}" > result.md
|
|
||||||
bash .github/workflows/test_llgo.sh
|
|
||||||
|
|
||||||
- name: Test demos
|
|
||||||
continue-on-error: true
|
|
||||||
run: bash .github/workflows/test_demo.sh
|
|
||||||
|
|
||||||
- name: Show test result
|
|
||||||
run: cat result.md
|
|
||||||
|
|
||||||
- name: PR comment with test result
|
|
||||||
uses: thollander/actions-comment-pull-request@v2
|
|
||||||
if: false
|
|
||||||
with:
|
|
||||||
filePath: result.md
|
|
||||||
comment_tag: test-result-on-${{matrix.os}}-with-llvm-${{matrix.llvm}}
|
|
||||||
|
|
||||||
- name: Upload coverage reports to Codecov
|
- name: Upload coverage reports to Codecov
|
||||||
uses: codecov/codecov-action@v4
|
uses: codecov/codecov-action@v5
|
||||||
with:
|
with:
|
||||||
token: ${{secrets.CODECOV_TOKEN}}
|
token: ${{secrets.CODECOV_TOKEN}}
|
||||||
slug: goplus/llgo
|
|
||||||
|
|||||||
145
.github/workflows/llgo.yml
vendored
Normal file
145
.github/workflows/llgo.yml
vendored
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
# This workflow will build a golang project
|
||||||
|
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go
|
||||||
|
|
||||||
|
name: LLGo
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "**" ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ "**" ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
llgo-test:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os:
|
||||||
|
- macos-latest
|
||||||
|
- ubuntu-24.04
|
||||||
|
llvm: [18]
|
||||||
|
go: ['1.20', '1.21', '1.22', '1.23']
|
||||||
|
runs-on: ${{matrix.os}}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install dependencies
|
||||||
|
uses: ./.github/actions/setup-deps
|
||||||
|
with:
|
||||||
|
llvm-version: ${{matrix.llvm}}
|
||||||
|
- name: Install further optional dependencies for demos
|
||||||
|
run: |
|
||||||
|
wget -P ./_demo/llama2-c https://huggingface.co/karpathy/tinyllamas/resolve/main/stories15M.bin
|
||||||
|
py_deps=(
|
||||||
|
numpy # for github.com/goplus/llgo/py/numpy
|
||||||
|
torch # for github.com/goplus/llgo/py/torch
|
||||||
|
)
|
||||||
|
pip3.12 install --break-system-packages "${py_deps[@]}"
|
||||||
|
|
||||||
|
- name: Set up Go for build
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: '1.23'
|
||||||
|
|
||||||
|
- name: Install
|
||||||
|
working-directory: compiler
|
||||||
|
run: |
|
||||||
|
go install ./...
|
||||||
|
echo "LLGO_ROOT=$GITHUB_WORKSPACE" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Set up Go for testing
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: ${{matrix.go}}
|
||||||
|
|
||||||
|
- name: Verify Go version
|
||||||
|
run: |
|
||||||
|
go_version=$(go version | cut -d' ' -f3 | sed 's/go//')
|
||||||
|
if [[ "$go_version" != "${{matrix.go}}"* ]]; then
|
||||||
|
echo "Expected Go version ${{matrix.go}}, but got $go_version"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "Using Go version: $go_version"
|
||||||
|
|
||||||
|
- name: _xtool build tests
|
||||||
|
run: |
|
||||||
|
cd _xtool
|
||||||
|
llgo build -v ./...
|
||||||
|
|
||||||
|
- name: LLGO tests
|
||||||
|
if: ${{!startsWith(matrix.os, 'ubuntu')}}
|
||||||
|
run: |
|
||||||
|
echo "Test result on ${{matrix.os}} with LLVM ${{matrix.llvm}}" > result.md
|
||||||
|
bash ./.github/workflows/test_llgo.sh
|
||||||
|
|
||||||
|
- name: Test demos
|
||||||
|
run: |
|
||||||
|
# TODO(lijie): force python3-embed to be linked with python-3.12-embed
|
||||||
|
# Currently, python3-embed is python-3.13-embed, doesn't work with pytorch
|
||||||
|
# Will remove this after pytorch is fixed.
|
||||||
|
pcdir=$HOME/pc
|
||||||
|
mkdir -p $pcdir
|
||||||
|
libdir=$(pkg-config --variable=libdir python-3.12-embed)
|
||||||
|
echo "libdir: $libdir"
|
||||||
|
ln -s $libdir/pkgconfig/python-3.12-embed.pc $pcdir/python3-embed.pc
|
||||||
|
export PKG_CONFIG_PATH=$pcdir
|
||||||
|
bash .github/workflows/test_demo.sh
|
||||||
|
|
||||||
|
- name: Show test result
|
||||||
|
run: cat result.md
|
||||||
|
|
||||||
|
- name: LLDB tests
|
||||||
|
if: ${{startsWith(matrix.os, 'macos')}}
|
||||||
|
working-directory: compiler
|
||||||
|
run: |
|
||||||
|
echo "Test lldb with llgo plugin on ${{matrix.os}} with LLVM ${{matrix.llvm}}"
|
||||||
|
bash _lldb/runtest.sh -v
|
||||||
|
|
||||||
|
helloworld-test:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-24.04, macos-latest]
|
||||||
|
llvm: [18]
|
||||||
|
go: ['1.20', '1.21', '1.22', '1.23']
|
||||||
|
runs-on: ${{matrix.os}}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install dependencies
|
||||||
|
uses: ./.github/actions/setup-deps
|
||||||
|
with:
|
||||||
|
llvm-version: ${{matrix.llvm}}
|
||||||
|
|
||||||
|
- name: Set up Go 1.23 for building llgo
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: '1.23'
|
||||||
|
|
||||||
|
- name: Install llgo
|
||||||
|
working-directory: compiler
|
||||||
|
run: |
|
||||||
|
go install ./...
|
||||||
|
echo "LLGO_ROOT=$GITHUB_WORKSPACE" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Set up Go for testing
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: ${{matrix.go}}
|
||||||
|
|
||||||
|
- name: Test Hello World with go.mod 1.20
|
||||||
|
if: matrix.go == '1.20' || matrix.go == '1.21' || matrix.go == '1.22' || matrix.go == '1.23'
|
||||||
|
uses: ./.github/actions/test-helloworld
|
||||||
|
with:
|
||||||
|
go-version: ${{matrix.go}}
|
||||||
|
mod-version: '1.20'
|
||||||
|
|
||||||
|
- name: Test Hello World with go.mod 1.21
|
||||||
|
if: matrix.go == '1.21' || matrix.go == '1.22' || matrix.go == '1.23'
|
||||||
|
uses: ./.github/actions/test-helloworld
|
||||||
|
with:
|
||||||
|
go-version: ${{matrix.go}}
|
||||||
|
mod-version: '1.21'
|
||||||
|
|
||||||
|
- name: Test Hello World with go.mod 1.22
|
||||||
|
if: matrix.go == '1.22' || matrix.go == '1.23'
|
||||||
|
uses: ./.github/actions/test-helloworld
|
||||||
|
with:
|
||||||
|
go-version: ${{matrix.go}}
|
||||||
|
mod-version: '1.22'
|
||||||
2
.github/workflows/populate_darwin_sysroot.sh
vendored
2
.github/workflows/populate_darwin_sysroot.sh
vendored
@@ -11,7 +11,7 @@ DARWIN_ARM64_LLVM_PREFIX=.sysroot/darwin/arm64/opt/homebrew/opt/llvm@18
|
|||||||
mkdir -p "${DARWIN_AMD64_LLVM_PREFIX}" "${DARWIN_ARM64_LLVM_PREFIX}"
|
mkdir -p "${DARWIN_AMD64_LLVM_PREFIX}" "${DARWIN_ARM64_LLVM_PREFIX}"
|
||||||
|
|
||||||
BREW_LLVM_FORMULA_JSON="$(mktemp)"
|
BREW_LLVM_FORMULA_JSON="$(mktemp)"
|
||||||
curl -fsSL https://formulae.brew.sh/api/formula/llvm.json > "${BREW_LLVM_FORMULA_JSON}"
|
curl -fsSL https://formulae.brew.sh/api/formula/llvm@18.json > "${BREW_LLVM_FORMULA_JSON}"
|
||||||
BREW_LLVM_AMD64_BOTTLE_URL=$(jq -r '.bottle.stable.files.sonoma.url' "${BREW_LLVM_FORMULA_JSON}")
|
BREW_LLVM_AMD64_BOTTLE_URL=$(jq -r '.bottle.stable.files.sonoma.url' "${BREW_LLVM_FORMULA_JSON}")
|
||||||
BREW_LLVM_ARM64_BOTTLE_URL=$(jq -r '.bottle.stable.files.arm64_sonoma.url' "${BREW_LLVM_FORMULA_JSON}")
|
BREW_LLVM_ARM64_BOTTLE_URL=$(jq -r '.bottle.stable.files.arm64_sonoma.url' "${BREW_LLVM_FORMULA_JSON}")
|
||||||
curl -fsSL -H "Authorization: Bearer QQ==" "${BREW_LLVM_AMD64_BOTTLE_URL}" | tar -xzf - --strip-components=2 -C "${DARWIN_AMD64_LLVM_PREFIX}"
|
curl -fsSL -H "Authorization: Bearer QQ==" "${BREW_LLVM_AMD64_BOTTLE_URL}" | tar -xzf - --strip-components=2 -C "${DARWIN_AMD64_LLVM_PREFIX}"
|
||||||
|
|||||||
11
.github/workflows/release-build.yml
vendored
11
.github/workflows/release-build.yml
vendored
@@ -11,9 +11,18 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
- name: Cache Darwin sysroot
|
||||||
|
id: cache-sysroot
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
.sysroot/darwin.tar.gz
|
||||||
|
key: darwin-sysroot-${{ runner.os }}-${{ hashFiles('.github/workflows/populate_darwin_sysroot.sh') }}
|
||||||
- name: Populate Darwin sysroot
|
- name: Populate Darwin sysroot
|
||||||
|
if: steps.cache-sysroot.outputs.cache-hit != 'true'
|
||||||
run: bash .github/workflows/populate_darwin_sysroot.sh
|
run: bash .github/workflows/populate_darwin_sysroot.sh
|
||||||
- name: Create Darwin sysroot tarball
|
- name: Create Darwin sysroot tarball
|
||||||
|
if: steps.cache-sysroot.outputs.cache-hit != 'true'
|
||||||
run: tar -czvf .sysroot/darwin.tar.gz -C .sysroot darwin
|
run: tar -czvf .sysroot/darwin.tar.gz -C .sysroot darwin
|
||||||
- name: Upload Darwin sysroot tarball
|
- name: Upload Darwin sysroot tarball
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
@@ -32,7 +41,7 @@ jobs:
|
|||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: 1.20.x
|
go-version: 1.23.x
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v3
|
uses: docker/setup-qemu-action@v3
|
||||||
- name: Download Darwin sysroot tarball
|
- name: Download Darwin sysroot tarball
|
||||||
|
|||||||
6
.github/workflows/test_demo.sh
vendored
6
.github/workflows/test_demo.sh
vendored
@@ -1,13 +1,13 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# llgo run subdirectories under _demo and _pydemo
|
# llgo run subdirectories under _demo and _pydemo that contain *.go files
|
||||||
total=0
|
total=0
|
||||||
failed=0
|
failed=0
|
||||||
failed_cases=""
|
failed_cases=""
|
||||||
for d in ./_demo/* ./_pydemo/*; do
|
for d in ./_demo/* ./_pydemo/*; do
|
||||||
total=$((total+1))
|
if [ -d "$d" ] && [ -n "$(ls "$d"/*.go 2>/dev/null)" ]; then
|
||||||
if [ -d "$d" ]; then
|
total=$((total+1))
|
||||||
echo "Testing $d"
|
echo "Testing $d"
|
||||||
if ! (cd "$d" && llgo run .); then
|
if ! (cd "$d" && llgo run .); then
|
||||||
echo "FAIL"
|
echo "FAIL"
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -26,6 +26,9 @@ build.dir/
|
|||||||
# Test binary, built with `go test -c`
|
# Test binary, built with `go test -c`
|
||||||
*.test
|
*.test
|
||||||
|
|
||||||
|
# Debug symbols
|
||||||
|
*.dSYM
|
||||||
|
|
||||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
*.out
|
*.out
|
||||||
*.swp
|
*.swp
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ before:
|
|||||||
|
|
||||||
builds:
|
builds:
|
||||||
- id: llgo-darwin-amd64
|
- id: llgo-darwin-amd64
|
||||||
|
dir: compiler
|
||||||
main: ./cmd/llgo
|
main: ./cmd/llgo
|
||||||
|
binary: bin/llgo
|
||||||
flags:
|
flags:
|
||||||
- -tags=darwin,amd64,byollvm
|
- -tags=darwin,amd64,byollvm
|
||||||
ldflags:
|
ldflags:
|
||||||
@@ -32,7 +34,9 @@ builds:
|
|||||||
- darwin_amd64
|
- darwin_amd64
|
||||||
mod_timestamp: "{{.CommitTimestamp}}"
|
mod_timestamp: "{{.CommitTimestamp}}"
|
||||||
- id: llgo-darwin-arm64
|
- id: llgo-darwin-arm64
|
||||||
|
dir: compiler
|
||||||
main: ./cmd/llgo
|
main: ./cmd/llgo
|
||||||
|
binary: bin/llgo
|
||||||
flags:
|
flags:
|
||||||
- -tags=darwin,arm64,byollvm
|
- -tags=darwin,arm64,byollvm
|
||||||
ldflags:
|
ldflags:
|
||||||
@@ -48,7 +52,9 @@ builds:
|
|||||||
- darwin_arm64
|
- darwin_arm64
|
||||||
mod_timestamp: "{{.CommitTimestamp}}"
|
mod_timestamp: "{{.CommitTimestamp}}"
|
||||||
- id: llgo-linux-amd64
|
- id: llgo-linux-amd64
|
||||||
|
dir: compiler
|
||||||
main: ./cmd/llgo
|
main: ./cmd/llgo
|
||||||
|
binary: bin/llgo
|
||||||
flags:
|
flags:
|
||||||
- -tags=linux,amd64,byollvm
|
- -tags=linux,amd64,byollvm
|
||||||
ldflags:
|
ldflags:
|
||||||
@@ -64,7 +70,9 @@ builds:
|
|||||||
- linux_amd64
|
- linux_amd64
|
||||||
mod_timestamp: "{{.CommitTimestamp}}"
|
mod_timestamp: "{{.CommitTimestamp}}"
|
||||||
- id: llgo-linux-arm64
|
- id: llgo-linux-arm64
|
||||||
|
dir: compiler
|
||||||
main: ./cmd/llgo
|
main: ./cmd/llgo
|
||||||
|
binary: bin/llgo
|
||||||
flags:
|
flags:
|
||||||
- -tags=linux,arm64,byollvm
|
- -tags=linux,arm64,byollvm
|
||||||
ldflags:
|
ldflags:
|
||||||
@@ -88,6 +96,7 @@ archives:
|
|||||||
files:
|
files:
|
||||||
- LICENSE
|
- LICENSE
|
||||||
- README.md
|
- README.md
|
||||||
|
- runtime
|
||||||
|
|
||||||
checksum:
|
checksum:
|
||||||
name_template: "{{.ProjectName}}{{.Version}}.checksums.txt"
|
name_template: "{{.ProjectName}}{{.Version}}.checksums.txt"
|
||||||
|
|||||||
59
README.md
59
README.md
@@ -24,7 +24,7 @@ How can these be achieved?
|
|||||||
LLGo := Go + C + Python
|
LLGo := Go + C + Python
|
||||||
```
|
```
|
||||||
|
|
||||||
LLGo is compatible with C and Python through the language's **Application Binary Interface (ABI)**, while LLGo is compatible with Go through its **syntax (source code)**.
|
LLGo is compatible with C and Python through the language's **Application Binary Interface (ABI)**, while LLGo is compatible with Go through its **syntax (source code)**. And here C doesn't just include C, but all languages that are ABI compatible with C, including C/C++, Objective-C, Swift, etc.
|
||||||
|
|
||||||
|
|
||||||
## C/C++ standard libary support
|
## C/C++ standard libary support
|
||||||
@@ -47,6 +47,8 @@ You can import a C/C++ standard library in LLGo!
|
|||||||
|
|
||||||
Here is a simple example:
|
Here is a simple example:
|
||||||
|
|
||||||
|
<!-- embedme doc/_readme/llgo_simple/simple.go -->
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@@ -73,10 +75,12 @@ llgo run .
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## How support C/C++ and Python
|
## How to support C/C++ and Python
|
||||||
|
|
||||||
LLGo use `go:linkname` to link an extern symbol througth its ABI:
|
LLGo use `go:linkname` to link an extern symbol througth its ABI:
|
||||||
|
|
||||||
|
<!-- embedme doc/_readme/llgo_call_c/call_c.go#L3-L6 -->
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import _ "unsafe" // for go:linkname
|
import _ "unsafe" // for go:linkname
|
||||||
|
|
||||||
@@ -86,6 +90,8 @@ func Sqrt(x float64) float64
|
|||||||
|
|
||||||
You can directly integrate it into [your own code](_demo/linkname/linkname.go):
|
You can directly integrate it into [your own code](_demo/linkname/linkname.go):
|
||||||
|
|
||||||
|
<!-- embedme doc/_readme/llgo_call_c/call_c.go -->
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@@ -101,6 +107,8 @@ func main() {
|
|||||||
|
|
||||||
Or put it into a package (see [c/math](c/math/math.go)):
|
Or put it into a package (see [c/math](c/math/math.go)):
|
||||||
|
|
||||||
|
<!-- embedme doc/_readme/llgo_call_cmath/call_cmath.go -->
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@@ -135,6 +143,8 @@ Note: For third-party libraries (such as pandas and pytorch), you still need to
|
|||||||
|
|
||||||
Here is an example:
|
Here is an example:
|
||||||
|
|
||||||
|
<!-- embedme doc/_readme/llgo_call_py/call_py.go -->
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@@ -152,6 +162,8 @@ func main() {
|
|||||||
|
|
||||||
It is equivalent to the following Python code:
|
It is equivalent to the following Python code:
|
||||||
|
|
||||||
|
<!-- embedme doc/_readme/llgo_call_py/call_math.py -->
|
||||||
|
|
||||||
```py
|
```py
|
||||||
import math
|
import math
|
||||||
|
|
||||||
@@ -163,6 +175,8 @@ Here, We call `py.Float(2)` to create a Python number 2, and pass it to Python
|
|||||||
|
|
||||||
Let's look at a slightly more complex example. For example, we use `numpy` to calculate:
|
Let's look at a slightly more complex example. For example, we use `numpy` to calculate:
|
||||||
|
|
||||||
|
<!-- embedme doc/_readme/llgo_py_list/py_list.go -->
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@@ -214,6 +228,7 @@ The currently supported libraries include:
|
|||||||
* [c/bdwgc](https://pkg.go.dev/github.com/goplus/llgo/c/bdwgc)
|
* [c/bdwgc](https://pkg.go.dev/github.com/goplus/llgo/c/bdwgc)
|
||||||
* [c/cjson](https://pkg.go.dev/github.com/goplus/llgo/c/cjson)
|
* [c/cjson](https://pkg.go.dev/github.com/goplus/llgo/c/cjson)
|
||||||
* [c/clang](https://pkg.go.dev/github.com/goplus/llgo/c/clang)
|
* [c/clang](https://pkg.go.dev/github.com/goplus/llgo/c/clang)
|
||||||
|
* [c/ffi](https://pkg.go.dev/github.com/goplus/llgo/c/ffi)
|
||||||
* [c/libuv](https://pkg.go.dev/github.com/goplus/llgo/c/libuv)
|
* [c/libuv](https://pkg.go.dev/github.com/goplus/llgo/c/libuv)
|
||||||
* [c/llama2](https://pkg.go.dev/github.com/goplus/llgo/c/llama2)
|
* [c/llama2](https://pkg.go.dev/github.com/goplus/llgo/c/llama2)
|
||||||
* [c/lua](https://pkg.go.dev/github.com/goplus/llgo/c/lua)
|
* [c/lua](https://pkg.go.dev/github.com/goplus/llgo/c/lua)
|
||||||
@@ -235,7 +250,7 @@ Here are some examples related to them:
|
|||||||
|
|
||||||
## Go syntax support
|
## Go syntax support
|
||||||
|
|
||||||
All Go syntax (not including `cgo`) is already supported. Here are some examples:
|
All Go syntax (including `cgo`) is already supported. Here are some examples:
|
||||||
|
|
||||||
* [concat](_demo/concat/concat.go): define a variadic function
|
* [concat](_demo/concat/concat.go): define a variadic function
|
||||||
* [genints](_demo/genints/genints.go): various forms of closure usage (including C function, recv.method and anonymous function)
|
* [genints](_demo/genints/genints.go): various forms of closure usage (including C function, recv.method and anonymous function)
|
||||||
@@ -303,6 +318,7 @@ Here are the Go packages that can be imported correctly:
|
|||||||
* [encoding/base32](https://pkg.go.dev/encoding/base32)
|
* [encoding/base32](https://pkg.go.dev/encoding/base32)
|
||||||
* [encoding/base64](https://pkg.go.dev/encoding/base64)
|
* [encoding/base64](https://pkg.go.dev/encoding/base64)
|
||||||
* [encoding/csv](https://pkg.go.dev/encoding/csv)
|
* [encoding/csv](https://pkg.go.dev/encoding/csv)
|
||||||
|
* [net/textproto](https://pkg.go.dev/net/textproto)
|
||||||
* [hash](https://pkg.go.dev/hash)
|
* [hash](https://pkg.go.dev/hash)
|
||||||
* [hash/adler32](https://pkg.go.dev/hash/adler32)
|
* [hash/adler32](https://pkg.go.dev/hash/adler32)
|
||||||
* [hash/crc32](https://pkg.go.dev/hash/crc32) (partially)
|
* [hash/crc32](https://pkg.go.dev/hash/crc32) (partially)
|
||||||
@@ -325,8 +341,8 @@ Here are the Go packages that can be imported correctly:
|
|||||||
|
|
||||||
- [Go 1.20+](https://go.dev)
|
- [Go 1.20+](https://go.dev)
|
||||||
- [LLVM 18](https://llvm.org)
|
- [LLVM 18](https://llvm.org)
|
||||||
- [LLD 18](https://lld.llvm.org)
|
|
||||||
- [Clang 18](https://clang.llvm.org)
|
- [Clang 18](https://clang.llvm.org)
|
||||||
|
- [LLD 18](https://lld.llvm.org)
|
||||||
- [pkg-config 0.29+](https://www.freedesktop.org/wiki/Software/pkg-config/)
|
- [pkg-config 0.29+](https://www.freedesktop.org/wiki/Software/pkg-config/)
|
||||||
- [bdwgc/libgc 8.0+](https://www.hboehm.info/gc/)
|
- [bdwgc/libgc 8.0+](https://www.hboehm.info/gc/)
|
||||||
- [OpenSSL 3.0+](https://www.openssl.org/)
|
- [OpenSSL 3.0+](https://www.openssl.org/)
|
||||||
@@ -339,24 +355,45 @@ Follow these steps to generate the `llgo` command (its usage is the same as the
|
|||||||
|
|
||||||
### on macOS
|
### on macOS
|
||||||
|
|
||||||
|
<!-- embedme doc/_readme/scripts/install_macos.sh#L2-L1000 -->
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
brew update
|
brew update
|
||||||
brew install llvm@18 pkg-config bdw-gc openssl
|
brew install llvm@18 bdw-gc openssl cjson libffi pkg-config
|
||||||
brew install python@3.12 # optional
|
brew install python@3.12 # optional
|
||||||
|
brew link --force libffi
|
||||||
go install -v github.com/goplus/llgo/cmd/llgo@latest
|
go install -v github.com/goplus/llgo/cmd/llgo@latest
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### on Linux (Debian/Ubuntu)
|
### on Linux
|
||||||
|
|
||||||
|
#### Debian/Ubuntu
|
||||||
|
|
||||||
|
<!-- embedme doc/_readme/scripts/install_ubuntu.sh#L2-L1000 -->
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-18 main" | sudo tee /etc/apt/sources.list.d/llvm.list
|
echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-18 main" | sudo tee /etc/apt/sources.list.d/llvm.list
|
||||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y llvm-18-dev clang-18 lld-18 pkg-config libgc-dev libssl-dev zlib1g-dev
|
sudo apt-get install -y llvm-18-dev clang-18 libclang-18-dev lld-18 pkg-config libgc-dev libssl-dev zlib1g-dev libcjson-dev libsqlite3-dev libunwind-dev
|
||||||
sudo apt-get install -y python3.12-dev # optional
|
sudo apt-get install -y python3.12-dev # optional
|
||||||
go install -v github.com/goplus/llgo/cmd/llgo@latest
|
go install -v github.com/goplus/llgo/cmd/llgo@latest
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Alpine Linux
|
||||||
|
|
||||||
|
```sh
|
||||||
|
apk add go llvm18-dev clang18-dev lld18 pkgconf gc-dev openssl-dev zlib-dev
|
||||||
|
apk add python3-dev # optional
|
||||||
|
apk add g++ # build only
|
||||||
|
export LLVM_CONFIG=/usr/lib/llvm18/bin/llvm-config
|
||||||
|
export CGO_CPPFLAGS="$($LLVM_CONFIG --cppflags)"
|
||||||
|
export CGO_CXXFLAGS=-std=c++17
|
||||||
|
export CGO_LDFLAGS="$($LLVM_CONFIG --ldflags) $($LLVM_CONFIG --libs all)"
|
||||||
|
go install -v -tags=byollvm -ldflags="-X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=$LLVM_CONFIG" github.com/goplus/llgo/cmd/llgo@latest
|
||||||
|
```
|
||||||
|
|
||||||
### on Windows
|
### on Windows
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
@@ -372,11 +409,15 @@ TODO
|
|||||||
|
|
||||||
How do I generate these tools?
|
How do I generate these tools?
|
||||||
|
|
||||||
|
<!-- embedme doc/_readme/scripts/install_llgo.sh#L2-L1000 -->
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone https://github.com/goplus/llgo.git
|
git clone https://github.com/goplus/llgo.git
|
||||||
cd llgo
|
cd llgo/compiler
|
||||||
|
go install -v ./cmd/...
|
||||||
go install -v ./chore/... # compile all tools except pydump
|
go install -v ./chore/... # compile all tools except pydump
|
||||||
cd chore/_xtool
|
export LLGO_ROOT=$PWD/..
|
||||||
|
cd ../_xtool
|
||||||
llgo install ./... # compile pydump
|
llgo install ./... # compile pydump
|
||||||
go install github.com/goplus/hdq/chore/pysigfetch@v0.8.1 # compile pysigfetch
|
go install github.com/goplus/hdq/chore/pysigfetch@v0.8.1 # compile pysigfetch
|
||||||
```
|
```
|
||||||
|
|||||||
31
_demo/async/async/async.go
Normal file
31
_demo/async/async/async.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package async
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Void = [0]byte
|
||||||
|
|
||||||
|
type Future[T any] interface {
|
||||||
|
Then(cb func(T))
|
||||||
|
}
|
||||||
|
|
||||||
|
type future[T any] struct {
|
||||||
|
cb func(func(T))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *future[T]) Then(cb func(T)) {
|
||||||
|
f.cb(cb)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Async[T any](fn func(func(T))) Future[T] {
|
||||||
|
return &future[T]{fn}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Run[T any](future Future[T]) T {
|
||||||
|
var ret T
|
||||||
|
future.Then(func(v T) {
|
||||||
|
ret = v
|
||||||
|
})
|
||||||
|
return ret
|
||||||
|
}
|
||||||
23
_demo/async/main.go
Normal file
23
_demo/async/main.go
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/_demo/async/async"
|
||||||
|
"github.com/goplus/llgo/_demo/async/timeout"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Sleep(i int, d time.Duration) async.Future[int] {
|
||||||
|
return async.Async(func(resolve func(int)) {
|
||||||
|
timeout.Timeout(d).Then(func(async.Void) {
|
||||||
|
resolve(i)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
async.Run(async.Async(func(resolve func(async.Void)) {
|
||||||
|
println("read file")
|
||||||
|
defer resolve(async.Void{})
|
||||||
|
}))
|
||||||
|
}
|
||||||
16
_demo/async/timeout/timeout.go
Normal file
16
_demo/async/timeout/timeout.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package timeout
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/_demo/async/async"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Timeout(d time.Duration) async.Future[async.Void] {
|
||||||
|
return async.Async(func(resolve func(async.Void)) {
|
||||||
|
go func() {
|
||||||
|
time.Sleep(d)
|
||||||
|
resolve(async.Void{})
|
||||||
|
}()
|
||||||
|
})
|
||||||
|
}
|
||||||
16
_demo/cgofull/bar.go
Normal file
16
_demo/cgofull/bar.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo CFLAGS: -DBAR
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "foo.h"
|
||||||
|
static void foo(Foo* f) {
|
||||||
|
printf("foo in bar: %d\n", f->a);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
func Bar(f *C.Foo) {
|
||||||
|
C.print_foo(f)
|
||||||
|
C.foo(f)
|
||||||
|
}
|
||||||
157
_demo/cgofull/cgofull.go
Normal file
157
_demo/cgofull/cgofull.go
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo windows,!amd64 CFLAGS: -D_WIN32
|
||||||
|
#cgo !windows CFLAGS: -D_POSIX
|
||||||
|
#cgo windows,amd64 CFLAGS: -D_WIN64
|
||||||
|
#cgo linux,amd64 CFLAGS: -D_LINUX64
|
||||||
|
#cgo !windows,amd64 CFLAGS: -D_UNIX64
|
||||||
|
#cgo pkg-config: python3-embed
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <Python.h>
|
||||||
|
#include "foo.h"
|
||||||
|
typedef struct {
|
||||||
|
int a;
|
||||||
|
} s4;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int a;
|
||||||
|
int b;
|
||||||
|
} s8;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int a;
|
||||||
|
int b;
|
||||||
|
int c;
|
||||||
|
} s12;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int a;
|
||||||
|
int b;
|
||||||
|
int c;
|
||||||
|
int d;
|
||||||
|
} s16;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int a;
|
||||||
|
int b;
|
||||||
|
int c;
|
||||||
|
int d;
|
||||||
|
int e;
|
||||||
|
} s20;
|
||||||
|
|
||||||
|
static int test_structs(s4* s4, s8* s8, s12* s12, s16* s16, s20* s20) {
|
||||||
|
printf("s4.a: %d\n", s4->a);
|
||||||
|
printf("s8.a: %d, s8.b: %d\n", s8->a, s8->b);
|
||||||
|
printf("s12.a: %d, s12.b: %d, s12.c: %d\n", s12->a, s12->b, s12->c);
|
||||||
|
printf("s16.a: %d, s16.b: %d, s16.c: %d, s16.d: %d\n", s16->a, s16->b, s16->c, s16->d);
|
||||||
|
printf("s20.a: %d, s20.b: %d, s20.c: %d, s20.d: %d, s20.e: %d\n", s20->a, s20->b, s20->c, s20->d, s20->e);
|
||||||
|
|
||||||
|
return s4->a + s8->a + s8->b + s12->a + s12->b + s12->c + s16->a + s16->b + s16->c + s16->d + s20->a + s20->b + s20->c + s20->d + s20->e;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_macros() {
|
||||||
|
#ifdef FOO
|
||||||
|
printf("FOO is defined\n");
|
||||||
|
#endif
|
||||||
|
#ifdef BAR
|
||||||
|
printf("BAR is defined\n");
|
||||||
|
#endif
|
||||||
|
#ifdef _WIN32
|
||||||
|
printf("WIN32 is defined\n");
|
||||||
|
#endif
|
||||||
|
#ifdef _POSIX
|
||||||
|
printf("POSIX is defined\n");
|
||||||
|
#endif
|
||||||
|
#ifdef _WIN64
|
||||||
|
printf("WIN64 is defined\n");
|
||||||
|
#endif
|
||||||
|
#ifdef _LINUX64
|
||||||
|
printf("LINUX64 is defined\n");
|
||||||
|
#endif
|
||||||
|
#ifdef _UNIX64
|
||||||
|
printf("UNIX64 is defined\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MY_VERSION "1.0.0"
|
||||||
|
#define MY_CODE 0x12345678
|
||||||
|
|
||||||
|
static void test_void() {
|
||||||
|
printf("test_void\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef int (*Cb)(int);
|
||||||
|
|
||||||
|
extern int go_callback(int);
|
||||||
|
|
||||||
|
extern int c_callback(int i);
|
||||||
|
|
||||||
|
static void test_callback(Cb cb) {
|
||||||
|
printf("test_callback, cb: %p, go_callback: %p, c_callback: %p\n", cb, go_callback, c_callback);
|
||||||
|
printf("test_callback, *cb: %p, *go_callback: %p, *c_callback: %p\n", *(void**)cb, *(void**)(go_callback), *(void**)(c_callback));
|
||||||
|
printf("cb result: %d\n", cb(123));
|
||||||
|
printf("done\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int go_callback_not_use_in_go(int);
|
||||||
|
|
||||||
|
static void run_callback() {
|
||||||
|
test_callback(c_callback);
|
||||||
|
test_callback(go_callback_not_use_in_go);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/_demo/cgofull/pymod1"
|
||||||
|
"github.com/goplus/llgo/_demo/cgofull/pymod2"
|
||||||
|
)
|
||||||
|
|
||||||
|
//export go_callback_not_use_in_go
|
||||||
|
func go_callback_not_use_in_go(i C.int) C.int {
|
||||||
|
return i + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
//export go_callback
|
||||||
|
func go_callback(i C.int) C.int {
|
||||||
|
return i + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
runPy()
|
||||||
|
f := &C.Foo{a: 1}
|
||||||
|
Foo(f)
|
||||||
|
Bar(f)
|
||||||
|
C.test_macros()
|
||||||
|
r := C.test_structs(&C.s4{a: 1}, &C.s8{a: 1, b: 2}, &C.s12{a: 1, b: 2, c: 3}, &C.s16{a: 1, b: 2, c: 3, d: 4}, &C.s20{a: 1, b: 2, c: 3, d: 4, e: 5})
|
||||||
|
fmt.Println(r)
|
||||||
|
if r != 35 {
|
||||||
|
panic("test_structs failed")
|
||||||
|
}
|
||||||
|
fmt.Println(C.MY_VERSION)
|
||||||
|
fmt.Println(int(C.MY_CODE))
|
||||||
|
C.test_void()
|
||||||
|
|
||||||
|
println("call run_callback")
|
||||||
|
C.run_callback()
|
||||||
|
|
||||||
|
// test _Cgo_ptr and _cgoCheckResult
|
||||||
|
println("call with go_callback")
|
||||||
|
C.test_callback((C.Cb)(C.go_callback))
|
||||||
|
|
||||||
|
println("call with c_callback")
|
||||||
|
C.test_callback((C.Cb)(C.c_callback))
|
||||||
|
}
|
||||||
|
|
||||||
|
func runPy() {
|
||||||
|
Initialize()
|
||||||
|
defer Finalize()
|
||||||
|
Run("print('Hello, Python!')")
|
||||||
|
C.PyObject_Print((*C.PyObject)(unsafe.Pointer(pymod1.Float(1.23))), C.stderr, 0)
|
||||||
|
C.PyObject_Print((*C.PyObject)(unsafe.Pointer(pymod2.Long(123))), C.stdout, 0)
|
||||||
|
// test _Cgo_use
|
||||||
|
C.PyObject_Print((*C.PyObject)(unsafe.Pointer(C.PyComplex_FromDoubles(C.double(1.23), C.double(4.56)))), C.stdout, 0)
|
||||||
|
}
|
||||||
12
_demo/cgofull/foo.c
Normal file
12
_demo/cgofull/foo.c
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include "foo.h"
|
||||||
|
|
||||||
|
void print_foo(Foo *f)
|
||||||
|
{
|
||||||
|
printf("print_foo: %d\n", f->a);
|
||||||
|
}
|
||||||
|
|
||||||
|
int c_callback(int i)
|
||||||
|
{
|
||||||
|
return i + 1;
|
||||||
|
}
|
||||||
16
_demo/cgofull/foo.go
Normal file
16
_demo/cgofull/foo.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo CFLAGS: -DFOO
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "foo.h"
|
||||||
|
static void foo(Foo* f) {
|
||||||
|
printf("foo in bar: %d\n", f->a);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
func Foo(f *C.Foo) {
|
||||||
|
C.print_foo(f)
|
||||||
|
C.foo(f)
|
||||||
|
}
|
||||||
7
_demo/cgofull/foo.h
Normal file
7
_demo/cgofull/foo.h
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int a;
|
||||||
|
} Foo;
|
||||||
|
|
||||||
|
extern void print_foo(Foo* f);
|
||||||
24
_demo/cgofull/py.go
Normal file
24
_demo/cgofull/py.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo pkg-config: python3-embed
|
||||||
|
#include <Python.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func Initialize() {
|
||||||
|
C.Py_Initialize()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Finalize() {
|
||||||
|
C.Py_Finalize()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Run(code string) error {
|
||||||
|
if C.PyRun_SimpleString(C.CString(code)) != 0 {
|
||||||
|
C.PyErr_Print()
|
||||||
|
return fmt.Errorf("failed to run code")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
11
_demo/cgofull/pymod1/pymod1.go
Normal file
11
_demo/cgofull/pymod1/pymod1.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package pymod1
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo pkg-config: python3-embed
|
||||||
|
#include <Python.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
func Float(f float64) *C.PyObject {
|
||||||
|
return C.PyFloat_FromDouble(C.double(f))
|
||||||
|
}
|
||||||
11
_demo/cgofull/pymod2/pymod2.go
Normal file
11
_demo/cgofull/pymod2/pymod2.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package pymod2
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo pkg-config: python3-embed
|
||||||
|
#include <Python.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
func Long(l int64) *C.PyObject {
|
||||||
|
return C.PyLong_FromLongLong(C.longlong(l))
|
||||||
|
}
|
||||||
28
_demo/checkfile/demo.go
Normal file
28
_demo/checkfile/demo.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
tempDir := os.TempDir()
|
||||||
|
noexist := filepath.Join(tempDir, "noexist.txt")
|
||||||
|
|
||||||
|
if _, err := os.Stat(noexist); err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
fmt.Println("noexist:", err.Error())
|
||||||
|
} else {
|
||||||
|
fmt.Println("exist,other err:", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Open(noexist); err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
fmt.Println("noexist:", err.Error())
|
||||||
|
} else {
|
||||||
|
fmt.Println("exist,other err:", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
_demo/commandrun/commandrun.go
Normal file
18
_demo/commandrun/commandrun.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"os/exec"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var data bytes.Buffer
|
||||||
|
cmd := exec.Command("echo", "hello llgo")
|
||||||
|
cmd.Stdout = &data
|
||||||
|
err := cmd.Run()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
println("len:", len(data.Bytes()))
|
||||||
|
println("data:", data.String())
|
||||||
|
}
|
||||||
42
_demo/failed/stacktrace/main.go
Normal file
42
_demo/failed/stacktrace/main.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MyStruct[T any] struct {
|
||||||
|
value T
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MyStruct[T]) Method() {
|
||||||
|
fmt.Println("In generic method")
|
||||||
|
genericFunc[T](m.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func genericFunc[T any](v T) {
|
||||||
|
fmt.Println("In generic function")
|
||||||
|
normalFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
func normalFunc() {
|
||||||
|
fmt.Println("In normal function")
|
||||||
|
panic("panic occurs here")
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
m := &MyStruct[string]{value: "hello"}
|
||||||
|
m.Method()
|
||||||
|
}
|
||||||
|
|
||||||
|
//Expected:
|
||||||
|
// In generic method
|
||||||
|
// In generic function
|
||||||
|
// In normal function
|
||||||
|
// panic: panic occurs here
|
||||||
|
|
||||||
|
// [0x00C6D310 github.com/goplus/llgo/internal/runtime.Rethrow+0x2f, SP = 0x60]
|
||||||
|
// [0x00C6CF44 github.com/goplus/llgo/internal/runtime.Panic+0x2d, SP = 0x50]
|
||||||
|
// [0x00C69420 main.normalFunc+0xf, SP = 0xa8]
|
||||||
|
// [0x00C69564 main.genericFunc[string]+0x18, SP = 0x74]
|
||||||
|
// [0x00C694A8 main.(*MyStruct[string]).Method+0x1f, SP = 0x84]
|
||||||
|
// [0x00C6936C main+0x4, SP = 0x40]
|
||||||
13
_demo/mimeheader/mimeheader.go
Normal file
13
_demo/mimeheader/mimeheader.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "net/textproto"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
h := make(textproto.MIMEHeader)
|
||||||
|
h.Set("host", "www.example.com")
|
||||||
|
println(h.Get("Host"))
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expected output:
|
||||||
|
www.example.com
|
||||||
|
*/
|
||||||
34
_demo/mkdirdemo/mkdir.go
Normal file
34
_demo/mkdirdemo/mkdir.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
tempDir, err := os.MkdirTemp("", "example*")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Failed to create temp directory:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer os.Remove(tempDir)
|
||||||
|
fmt.Println("Temp directory:", tempDir)
|
||||||
|
|
||||||
|
tempFile, err := os.CreateTemp("", "example*.txt")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Failed to create temp file:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer tempFile.Close()
|
||||||
|
defer os.Remove(tempFile.Name())
|
||||||
|
fmt.Println("Temp file:", tempFile.Name())
|
||||||
|
|
||||||
|
nestedDir := filepath.Join("nested", "directory")
|
||||||
|
err = os.MkdirAll(nestedDir, 0755)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Failed to create nested directory:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("Nest directory:", nestedDir)
|
||||||
|
}
|
||||||
42
_demo/reflectfunc/reflectfunc.go
Normal file
42
_demo/reflectfunc/reflectfunc.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func add(a, b int) int {
|
||||||
|
return a + b
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fn := func(a, b int) int {
|
||||||
|
return a + b
|
||||||
|
}
|
||||||
|
var i int
|
||||||
|
fn1 := func() {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
fn2 := func() func() {
|
||||||
|
return func() {
|
||||||
|
println("closure", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fns := []any{add, fn, fn1, fn2}
|
||||||
|
for _, fn := range fns {
|
||||||
|
v := reflect.ValueOf(fn)
|
||||||
|
fmt.Println(v.Type())
|
||||||
|
fmt.Println(v.Kind())
|
||||||
|
if v.Kind() != reflect.Func {
|
||||||
|
panic(fmt.Sprintf("not func: %T", fn))
|
||||||
|
}
|
||||||
|
|
||||||
|
t := v.Type()
|
||||||
|
fmt.Println(t)
|
||||||
|
fmt.Println(t.Kind())
|
||||||
|
if t.Kind() != reflect.Func {
|
||||||
|
panic(fmt.Sprintf("not func: %T", fn))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
31
_demo/syncdebug/syncdebug.go
Normal file
31
_demo/syncdebug/syncdebug.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
llsync "github.com/goplus/llgo/c/pthread/sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type L struct {
|
||||||
|
mu sync.Mutex
|
||||||
|
s string
|
||||||
|
i int
|
||||||
|
w io.Writer
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
l := &L{s: "hello", i: 123, w: os.Stdout}
|
||||||
|
println("sizeof(L):", unsafe.Sizeof(L{}))
|
||||||
|
println("sizeof(sync.Mutex):", unsafe.Sizeof(sync.Mutex{}))
|
||||||
|
println("sizeof(llsync.Mutex):", unsafe.Sizeof(llsync.Mutex{}))
|
||||||
|
println("l:", l, "l.s:", l.s, "l.i:", l.i, "l.w:", l.w)
|
||||||
|
l.mu.Lock()
|
||||||
|
println("locked")
|
||||||
|
println("l:", l, "l.s:", l.s, "l.i:", l.i, "l.w:", l.w)
|
||||||
|
l.w.Write([]byte(l.s))
|
||||||
|
l.w.Write([]byte("\n"))
|
||||||
|
l.mu.Unlock()
|
||||||
|
}
|
||||||
@@ -61,7 +61,9 @@ func printType(t clang.Type, data *Data) {
|
|||||||
case clang.TypeIncompleteArray, clang.TypeVariableArray, clang.TypeDependentSizedArray, clang.TypeConstantArray:
|
case clang.TypeIncompleteArray, clang.TypeVariableArray, clang.TypeDependentSizedArray, clang.TypeConstantArray:
|
||||||
printType(t.ArrayElementType(), data)
|
printType(t.ArrayElementType(), data)
|
||||||
case clang.TypeTypedef:
|
case clang.TypeTypedef:
|
||||||
printType(t.CanonicalType(), data)
|
printType(t.TypeDeclaration().TypedefDeclUnderlyingType(), data)
|
||||||
|
case clang.TypeElaborated:
|
||||||
|
printType(t.NamedType(), data)
|
||||||
case clang.TypeFunctionProto:
|
case clang.TypeFunctionProto:
|
||||||
printType(t.ResultType(), data)
|
printType(t.ResultType(), data)
|
||||||
for i := 0; i < int(t.NumArgTypes()); i++ {
|
for i := 0; i < int(t.NumArgTypes()); i++ {
|
||||||
@@ -105,6 +107,8 @@ func printMacro(cursor clang.Cursor, unit *clang.TranslationUnit) {
|
|||||||
var numTokens c.Uint
|
var numTokens c.Uint
|
||||||
var tokens *clang.Token
|
var tokens *clang.Token
|
||||||
unit.Tokenize(ran, &tokens, &numTokens)
|
unit.Tokenize(ran, &tokens, &numTokens)
|
||||||
|
defer unit.DisposeTokens(tokens, numTokens)
|
||||||
|
|
||||||
tokensSlice := unsafe.Slice(tokens, int(numTokens))
|
tokensSlice := unsafe.Slice(tokens, int(numTokens))
|
||||||
for _, tok := range tokensSlice {
|
for _, tok := range tokensSlice {
|
||||||
tokStr := unit.Token(tok)
|
tokStr := unit.Token(tok)
|
||||||
@@ -38,7 +38,7 @@ func main() {
|
|||||||
items := cjson.Array()
|
items := cjson.Array()
|
||||||
mod := py.ImportModule(pyLib)
|
mod := py.ImportModule(pyLib)
|
||||||
keys := mod.ModuleGetDict().DictKeys()
|
keys := mod.ModuleGetDict().DictKeys()
|
||||||
for i, n := uintptr(0), keys.ListLen(); i < n; i++ {
|
for i, n := 0, keys.ListLen(); i < n; i++ {
|
||||||
key := keys.ListItem(i)
|
key := keys.ListItem(i)
|
||||||
val := mod.GetAttr(key)
|
val := mod.GetAttr(key)
|
||||||
doc := val.GetAttrString(c.Str("__doc__"))
|
doc := val.GetAttrString(c.Str("__doc__"))
|
||||||
32
c/c.go
32
c/c.go
@@ -33,9 +33,13 @@ type (
|
|||||||
Float = float32
|
Float = float32
|
||||||
Double = float64
|
Double = float64
|
||||||
Pointer = unsafe.Pointer
|
Pointer = unsafe.Pointer
|
||||||
FilePtr = unsafe.Pointer
|
FilePtr = *FILE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type FILE struct {
|
||||||
|
Unused [8]byte
|
||||||
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
Int C.int
|
Int C.int
|
||||||
Uint C.uint
|
Uint C.uint
|
||||||
@@ -51,6 +55,23 @@ type integer interface {
|
|||||||
~int | ~uint | ~uintptr | ~int32 | ~uint32 | ~int64 | ~uint64
|
~int | ~uint | ~uintptr | ~int32 | ~uint32 | ~int64 | ~uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SizeT = uintptr
|
||||||
|
|
||||||
|
type IntptrT = uintptr
|
||||||
|
type UintptrT = uintptr
|
||||||
|
type Int8T = int8
|
||||||
|
type Int16T = int16
|
||||||
|
type Int32T = int32
|
||||||
|
type Int64T = int64
|
||||||
|
|
||||||
|
type Uint8T = uint8
|
||||||
|
type Uint16T = uint16
|
||||||
|
type Uint32T = uint32
|
||||||
|
type Uint64T = uint64
|
||||||
|
|
||||||
|
type IntmaxT = LongLong
|
||||||
|
type UintmaxT = UlongLong
|
||||||
|
|
||||||
//go:linkname Str llgo.cstr
|
//go:linkname Str llgo.cstr
|
||||||
func Str(string) *Char
|
func Str(string) *Char
|
||||||
|
|
||||||
@@ -85,6 +106,9 @@ func Calloc(num uintptr, size uintptr) Pointer
|
|||||||
//go:linkname Free C.free
|
//go:linkname Free C.free
|
||||||
func Free(ptr Pointer)
|
func Free(ptr Pointer)
|
||||||
|
|
||||||
|
//go:linkname Realloc C.realloc
|
||||||
|
func Realloc(ptr Pointer, size uintptr) Pointer
|
||||||
|
|
||||||
//go:linkname Memcpy C.memcpy
|
//go:linkname Memcpy C.memcpy
|
||||||
func Memcpy(dst, src Pointer, n uintptr) Pointer
|
func Memcpy(dst, src Pointer, n uintptr) Pointer
|
||||||
|
|
||||||
@@ -216,6 +240,9 @@ func Fputc(c Int, fp FilePtr) Int
|
|||||||
//go:linkname Fputs C.fputs
|
//go:linkname Fputs C.fputs
|
||||||
func Fputs(s *Char, fp FilePtr) Int
|
func Fputs(s *Char, fp FilePtr) Int
|
||||||
|
|
||||||
|
//go:linkname Fread C.fread
|
||||||
|
func Fread(data Pointer, size, count uintptr, fp FilePtr) uintptr
|
||||||
|
|
||||||
//go:linkname Fflush C.fflush
|
//go:linkname Fflush C.fflush
|
||||||
func Fflush(fp FilePtr) Int
|
func Fflush(fp FilePtr) Int
|
||||||
|
|
||||||
@@ -270,3 +297,6 @@ func GetoptLong(argc Int, argv **Char, optstring *Char, longopts *Option, longin
|
|||||||
func GetoptLongOnly(argc Int, argv **Char, optstring *Char, longopts *Option, longindex *Int) Int
|
func GetoptLongOnly(argc Int, argv **Char, optstring *Char, longopts *Option, longindex *Int) Int
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//go:linkname Sysconf C.sysconf
|
||||||
|
func Sysconf(name Int) Long
|
||||||
|
|||||||
669
c/cjson/cjson.go
669
c/cjson/cjson.go
@@ -26,87 +26,25 @@ const (
|
|||||||
LLGoPackage = "link: $(pkg-config --libs libcjson); -lcjson"
|
LLGoPackage = "link: $(pkg-config --libs libcjson); -lcjson"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Bool c.Int
|
||||||
|
|
||||||
// llgo:type C
|
// llgo:type C
|
||||||
type JSON struct {
|
type JSON struct {
|
||||||
Unused [0]byte
|
Unused [0]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname Parse C.cJSON_Parse
|
|
||||||
func Parse(value *c.Char) *JSON
|
|
||||||
|
|
||||||
//go:linkname ParseWithLength C.cJSON_ParseWithLength
|
|
||||||
func ParseWithLength(value *byte, valueLength uintptr) *JSON
|
|
||||||
|
|
||||||
func ParseBytes(value []byte) *JSON {
|
func ParseBytes(value []byte) *JSON {
|
||||||
return ParseWithLength(unsafe.SliceData(value), uintptr(len(value)))
|
return ParseWithLength((*c.Char)(unsafe.Pointer(unsafe.SliceData(value))), uintptr(len(value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseString(value string) *JSON {
|
func ParseString(value string) *JSON {
|
||||||
return ParseWithLength(unsafe.StringData(value), uintptr(len(value)))
|
return ParseWithLength((*c.Char)(unsafe.Pointer(unsafe.StringData(value))), uintptr(len(value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname Null C.cJSON_CreateNull
|
// CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
||||||
func Null() *JSON
|
|
||||||
|
|
||||||
//go:linkname True C.cJSON_CreateTrue
|
|
||||||
func True() *JSON
|
|
||||||
|
|
||||||
//go:linkname False C.cJSON_CreateFalse
|
|
||||||
func False() *JSON
|
|
||||||
|
|
||||||
//go:linkname Bool C.cJSON_CreateBool
|
|
||||||
func Bool(boolean c.Int) *JSON
|
|
||||||
|
|
||||||
//go:linkname Number C.cJSON_CreateNumber
|
|
||||||
func Number(num float64) *JSON
|
|
||||||
|
|
||||||
//go:linkname String C.cJSON_CreateString
|
|
||||||
func String(str *c.Char) *JSON
|
|
||||||
|
|
||||||
//go:linkname Array C.cJSON_CreateArray
|
|
||||||
func Array() *JSON
|
|
||||||
|
|
||||||
//go:linkname Object C.cJSON_CreateObject
|
|
||||||
func Object() *JSON
|
|
||||||
|
|
||||||
// raw json
|
|
||||||
//
|
//
|
||||||
//go:linkname Raw C.cJSON_CreateRaw
|
// Render a cJSON entity to text for transfer/storage without any formatting.
|
||||||
func Raw(raw *c.Char) *JSON
|
|
||||||
|
|
||||||
// Create a string where valuestring references a string so
|
|
||||||
// it will not be freed by Delete
|
|
||||||
//
|
//
|
||||||
//go:linkname StringRef C.cJSON_CreateStringReference
|
|
||||||
func StringRef(str *c.Char) *JSON
|
|
||||||
|
|
||||||
// Create an object that only references it's elements so
|
|
||||||
// they will not be freed by Delete
|
|
||||||
//
|
|
||||||
//go:linkname ObjectRef C.cJSON_CreateObjectReference
|
|
||||||
func ObjectRef(child *JSON) *JSON
|
|
||||||
|
|
||||||
// Create an array that only references it's elements so
|
|
||||||
// they will not be freed by Delete
|
|
||||||
//
|
|
||||||
//go:linkname ArrayRef C.cJSON_CreateArrayReference
|
|
||||||
func ArrayRef(child *JSON) *JSON
|
|
||||||
|
|
||||||
// Delete a JSON entity and all subentities.
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).Delete C.cJSON_Delete
|
|
||||||
func (o *JSON) Delete() {}
|
|
||||||
|
|
||||||
// Append item to the specified array.
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).AddItem C.cJSON_AddItemToArray
|
|
||||||
func (o *JSON) AddItem(item *JSON) c.Int { return 0 }
|
|
||||||
|
|
||||||
// Append item to the specified object.
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).SetItem C.cJSON_AddItemToObject
|
|
||||||
func (o *JSON) SetItem(key *c.Char, item *JSON) c.Int { return 0 }
|
|
||||||
|
|
||||||
// llgo:link (*JSON).CStr C.cJSON_PrintUnformatted
|
// llgo:link (*JSON).CStr C.cJSON_PrintUnformatted
|
||||||
func (o *JSON) CStr() *c.Char { return nil }
|
func (o *JSON) CStr() *c.Char { return nil }
|
||||||
|
|
||||||
@@ -115,39 +53,618 @@ func (o *JSON) CStr() *c.Char { return nil }
|
|||||||
// llgo:link (*JSON).Cstr C.cJSON_PrintUnformatted
|
// llgo:link (*JSON).Cstr C.cJSON_PrintUnformatted
|
||||||
func (o *JSON) Cstr() *c.Char { return nil }
|
func (o *JSON) Cstr() *c.Char { return nil }
|
||||||
|
|
||||||
|
// malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks
|
||||||
|
//
|
||||||
|
//go:linkname FreeCStr C.cJSON_free
|
||||||
|
func FreeCStr(*c.Char)
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(const char*) cJSON_Version(void);
|
||||||
|
//
|
||||||
|
// returns the version of cJSON as a string
|
||||||
|
//
|
||||||
|
//go:linkname Version C.cJSON_Version
|
||||||
|
func Version() *c.Char
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
||||||
|
//
|
||||||
|
// Memory Management: the caller is always responsible to free
|
||||||
|
// the results from all variants of cJSON_Parse (with cJSON_Delete)
|
||||||
|
// and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or
|
||||||
|
// cJSON_free as appropriate). The exception is cJSON_PrintPreallocated,
|
||||||
|
// where the caller has full responsibility of the buffer.
|
||||||
|
//
|
||||||
|
//go:linkname Parse C.cJSON_Parse
|
||||||
|
func Parse(value *c.Char) *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
|
||||||
|
//
|
||||||
|
// Memory Management: the caller is always responsible to free
|
||||||
|
// the results from all variants of cJSON_Parse (with cJSON_Delete)
|
||||||
|
// and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or
|
||||||
|
// cJSON_free as appropriate). The exception is cJSON_PrintPreallocated,
|
||||||
|
// where the caller has full responsibility of the buffer.
|
||||||
|
//
|
||||||
|
//go:linkname ParseWithLength C.cJSON_ParseWithLength
|
||||||
|
func ParseWithLength(value *c.Char, valueLength uintptr) *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_Bool require_null_terminated);
|
||||||
|
//
|
||||||
|
// ParseWithOpts allows you to require (and check) that the JSON is null terminated,
|
||||||
|
// and to retrieve the pointer to the final byte parsed.
|
||||||
|
// If you supply a ptr in return_parse_end and parsing fails, then
|
||||||
|
// return_parse_end will contain a pointer to the error so will match
|
||||||
|
// cJSON_GetErrorPtr().
|
||||||
|
//
|
||||||
|
//go:linkname ParseWithOpts C.cJSON_ParseWithOpts
|
||||||
|
func ParseWithOpts(value *c.Char, return_parse_end **c.Char, require_null_terminated Bool) *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_Bool require_null_terminated);
|
||||||
|
//
|
||||||
|
// ParseWithOpts allows you to require (and check) that the JSON is null terminated,
|
||||||
|
// and to retrieve the pointer to the final byte parsed.
|
||||||
|
// If you supply a ptr in return_parse_end and parsing fails, then
|
||||||
|
// return_parse_end will contain a pointer to the error so will match
|
||||||
|
// cJSON_GetErrorPtr().
|
||||||
|
//
|
||||||
|
//go:linkname ParseWithLengthOpts C.cJSON_ParseWithLengthOpts
|
||||||
|
func ParseWithLengthOpts(value *c.Char, buffer_length uintptr, return_parse_end **c.Char, require_null_terminated Bool) *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
||||||
// Render a JSON entity to text for transfer/storage.
|
// Render a JSON entity to text for transfer/storage.
|
||||||
//
|
//
|
||||||
// llgo:link (*JSON).Print C.cJSON_Print
|
// llgo:link (*JSON).Print C.cJSON_Print
|
||||||
func (o *JSON) Print() *c.Char { return nil }
|
func (o *JSON) Print() *c.Char { return nil }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
||||||
// Render a JSON entity to text for transfer/storage without any formatting.
|
// Render a JSON entity to text for transfer/storage without any formatting.
|
||||||
//
|
//
|
||||||
// llgo:link (*JSON).PrintUnformatted C.cJSON_PrintUnformatted
|
// llgo:link (*JSON).PrintUnformatted C.cJSON_PrintUnformatted
|
||||||
func (o *JSON) PrintUnformatted() *c.Char { return nil }
|
func (o *JSON) PrintUnformatted() *c.Char { return nil }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_Bool fmt);
|
||||||
|
//
|
||||||
// Render a JSON entity to text using a buffered strategy.
|
// Render a JSON entity to text using a buffered strategy.
|
||||||
//
|
|
||||||
// prebuffer is a guess at the final size. guessing well reduces reallocation.
|
// prebuffer is a guess at the final size. guessing well reduces reallocation.
|
||||||
//
|
|
||||||
// fmt=0 gives unformatted, =1 gives formatted.
|
// fmt=0 gives unformatted, =1 gives formatted.
|
||||||
//
|
//
|
||||||
// llgo:link (*JSON).PrintBuffered C.cJSON_PrintBuffered
|
// llgo:link (*JSON).PrintBuffered C.cJSON_PrintBuffered
|
||||||
func (o *JSON) PrintBuffered(prebuffer c.Int, fmt c.Int) *c.Char { return nil }
|
func (o *JSON) PrintBuffered(prebuffer c.Int, fmt Bool) *c.Char { return nil }
|
||||||
|
|
||||||
// llgo:link (*JSON).GetObjectItemCaseSensitive C.cJSON_GetObjectItemCaseSensitive
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_Bool format);
|
||||||
func (o *JSON) GetObjectItemCaseSensitive(key *c.Char) *JSON { return nil }
|
//
|
||||||
|
// Render a cJSON entity to text using a buffer already allocated in memory with given
|
||||||
|
// length. Returns 1 on success and 0 on failure.
|
||||||
|
// note that cJSON is not always 100% accurate in estimating how much memory it will use,
|
||||||
|
// so to be safe allocate 5 bytes more than you actually need
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).PrintPreallocated C.cJSON_PrintPreallocated
|
||||||
|
func (o *JSON) PrintPreallocated(buffer *c.Char, length c.Int, format Bool) Bool {
|
||||||
|
return Bool(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
|
||||||
|
// Delete a JSON entity and all subentities.
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).Delete C.cJSON_Delete
|
||||||
|
func (o *JSON) Delete() {}
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
||||||
|
//
|
||||||
|
// Returns the number of items in an array (or object).
|
||||||
|
//
|
||||||
// llgo:link (*JSON).GetArraySize C.cJSON_GetArraySize
|
// llgo:link (*JSON).GetArraySize C.cJSON_GetArraySize
|
||||||
func (o *JSON) GetArraySize() c.Int { return 0 }
|
func (o *JSON) GetArraySize() c.Int { return 0 }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
||||||
|
//
|
||||||
|
// Retrieve item number "index" from array "array". Returns NULL if unsuccessful.
|
||||||
|
//
|
||||||
// llgo:link (*JSON).GetArrayItem C.cJSON_GetArrayItem
|
// llgo:link (*JSON).GetArrayItem C.cJSON_GetArrayItem
|
||||||
func (o *JSON) GetArrayItem(index c.Int) *JSON { return nil }
|
func (o *JSON) GetArrayItem(index c.Int) *JSON { return nil }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
||||||
|
//
|
||||||
|
// Get item "string" from object. Case insensitive.
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).GetObjectItem C.cJSON_GetObjectItem
|
||||||
|
func (o *JSON) GetObjectItem(s *c.Char) *JSON { return nil }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
|
||||||
|
//
|
||||||
|
// Get item "string" from object. Case sensitive.
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).GetObjectItemCaseSensitive C.cJSON_GetObjectItemCaseSensitive
|
||||||
|
func (o *JSON) GetObjectItemCaseSensitive(key *c.Char) *JSON { return nil }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).HasObjectItem C.cJSON_HasObjectItem
|
||||||
|
func (o *JSON) HasObjectItem(s *c.Char) Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
||||||
|
//
|
||||||
|
// For analysing failed parses. This returns a pointer to the parse error.
|
||||||
|
// You'll probably need to look a few chars back to make sense of it.
|
||||||
|
// Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds.
|
||||||
|
//
|
||||||
|
//go:linkname GetErrorPtr C.cJSON_GetErrorPtr
|
||||||
|
func GetErrorPtr() *c.Char
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
|
||||||
|
//
|
||||||
|
// Check item type and return its value
|
||||||
|
//
|
||||||
// llgo:link (*JSON).GetStringValue C.cJSON_GetStringValue
|
// llgo:link (*JSON).GetStringValue C.cJSON_GetStringValue
|
||||||
func (o *JSON) GetStringValue() *c.Char { return nil }
|
func (o *JSON) GetStringValue() *c.Char { return nil }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item);
|
||||||
|
//
|
||||||
|
// Check item type and return its value
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).GetNumberValue C.cJSON_GetNumberValue
|
||||||
|
func (o *JSON) GetNumberValue() c.Double { return 0 }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsInvalid(const cJSON * const item);
|
||||||
|
//
|
||||||
|
// These functions check the type of an item
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).IsInvalid C.cJSON_IsInvalid
|
||||||
|
func (o *JSON) IsInvalid() Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsFalse(const cJSON * const item);
|
||||||
|
//
|
||||||
|
// These functions check the type of an item
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).IsFalse C.cJSON_IsFalse
|
||||||
|
func (o *JSON) IsFalse() Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsTrue(const cJSON * const item);
|
||||||
|
//
|
||||||
|
// These functions check the type of an item
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).IsTrue C.cJSON_IsTrue
|
||||||
|
func (o *JSON) IsTrue() Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsBool(const cJSON * const item);
|
||||||
|
//
|
||||||
|
// These functions check the type of an item
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).IsBool C.cJSON_IsBool
|
||||||
|
func (o *JSON) IsBool() Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsNull(const cJSON * const item);
|
||||||
|
//
|
||||||
|
// These functions check the type of an item
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).IsNull C.cJSON_IsNull
|
||||||
|
func (o *JSON) IsNull() Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsNumber(const cJSON * const item);
|
||||||
|
//
|
||||||
|
// These functions check the type of an item
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).IsNumber C.cJSON_IsNumber
|
||||||
|
func (o *JSON) IsNumber() Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsString(const cJSON * const item);
|
||||||
|
//
|
||||||
|
// These functions check the type of an item
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).IsString C.cJSON_IsString
|
||||||
|
func (o *JSON) IsString() Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsArray(const cJSON * const item);
|
||||||
|
//
|
||||||
|
// These functions check the type of an item
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).IsArray C.cJSON_IsArray
|
||||||
|
func (o *JSON) IsArray() Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsObject(const cJSON * const item);
|
||||||
|
//
|
||||||
|
// These functions check the type of an item
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).IsObject C.cJSON_IsObject
|
||||||
|
func (o *JSON) IsObject() Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsRaw(const cJSON * const item);
|
||||||
|
//
|
||||||
|
// These functions check the type of an item
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).IsRaw C.cJSON_IsRaw
|
||||||
|
func (o *JSON) IsRaw() Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
||||||
|
//
|
||||||
|
// These calls create a cJSON item of the appropriate type.
|
||||||
|
//
|
||||||
|
//go:linkname Null C.cJSON_CreateNull
|
||||||
|
func Null() *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
||||||
|
//
|
||||||
|
// same as Null func
|
||||||
|
//
|
||||||
|
//go:linkname CreateNull C.cJSON_CreateNull
|
||||||
|
func CreateNull() *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
||||||
|
//
|
||||||
|
//go:linkname True C.cJSON_CreateTrue
|
||||||
|
func True() *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
||||||
|
//
|
||||||
|
// same as True func
|
||||||
|
//
|
||||||
|
//go:linkname CreateTrue C.cJSON_CreateTrue
|
||||||
|
func CreateTrue() *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
||||||
|
//
|
||||||
|
//go:linkname False C.cJSON_CreateFalse
|
||||||
|
func False() *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
||||||
|
//
|
||||||
|
// same as False func
|
||||||
|
//
|
||||||
|
//go:linkname CreateFalse C.cJSON_CreateFalse
|
||||||
|
func CreateFalse() *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_Bool boolean);
|
||||||
|
//
|
||||||
|
// same as Bool func
|
||||||
|
//
|
||||||
|
//go:linkname CreateBool C.cJSON_CreateBool
|
||||||
|
func CreateBool(boolean c.Int) *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
||||||
|
//
|
||||||
|
//go:linkname Number C.cJSON_CreateNumber
|
||||||
|
func Number(num float64) *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
||||||
|
//
|
||||||
|
// same as Number func
|
||||||
|
//
|
||||||
|
//go:linkname CreateNumber C.cJSON_CreateNumber
|
||||||
|
func CreateNumber(num float64) *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
||||||
|
//
|
||||||
|
//go:linkname String C.cJSON_CreateString
|
||||||
|
func String(str *c.Char) *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
||||||
|
//
|
||||||
|
// same as String func
|
||||||
|
//
|
||||||
|
//go:linkname CreateString C.cJSON_CreateString
|
||||||
|
func CreateString(str *c.Char) *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
||||||
|
// raw json
|
||||||
|
//
|
||||||
|
//go:linkname Raw C.cJSON_CreateRaw
|
||||||
|
func Raw(raw *c.Char) *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
||||||
|
//
|
||||||
|
// same as Raw func
|
||||||
|
//
|
||||||
|
//go:linkname CreateRaw C.cJSON_CreateRaw
|
||||||
|
func CreateRaw(raw *c.Char) *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
||||||
|
//
|
||||||
|
//go:linkname Array C.cJSON_CreateArray
|
||||||
|
func Array() *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
||||||
|
//
|
||||||
|
// same as Array func
|
||||||
|
//
|
||||||
|
//go:linkname CreateArray C.cJSON_CreateArray
|
||||||
|
func CreateArray() *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
||||||
|
//
|
||||||
|
//go:linkname Object C.cJSON_CreateObject
|
||||||
|
func Object() *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
||||||
|
//
|
||||||
|
// same as Object func
|
||||||
|
//
|
||||||
|
//go:linkname CreateObject C.cJSON_CreateObject
|
||||||
|
func CreateObject() *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
||||||
|
//
|
||||||
|
// Create a string where valuestring references a string so
|
||||||
|
// it will not be freed by Delete
|
||||||
|
//
|
||||||
|
//go:linkname StringRef C.cJSON_CreateStringReference
|
||||||
|
func StringRef(str *c.Char) *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
||||||
|
//
|
||||||
|
// same as StringRef func
|
||||||
|
//
|
||||||
|
//go:linkname CreateStringReference C.cJSON_CreateStringReference
|
||||||
|
func CreateStringReference(str *c.Char) *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
||||||
|
//
|
||||||
|
// Create an object that only references it's elements so
|
||||||
|
// they will not be freed by Delete
|
||||||
|
//
|
||||||
|
//go:linkname ObjectRef C.cJSON_CreateObjectReference
|
||||||
|
func ObjectRef(child *JSON) *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
||||||
|
//
|
||||||
|
// same as ObjectRef func
|
||||||
|
//
|
||||||
|
//go:linkname CreateObjectReference C.cJSON_CreateObjectReference
|
||||||
|
func CreateObjectReference(child *JSON) *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
||||||
|
//
|
||||||
|
// Create an array that only references it's elements so
|
||||||
|
// they will not be freed by Delete
|
||||||
|
//
|
||||||
|
//go:linkname ArrayRef C.cJSON_CreateArrayReference
|
||||||
|
func ArrayRef(child *JSON) *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
||||||
|
//
|
||||||
|
// same as ArrayRef func
|
||||||
|
//
|
||||||
|
//go:linkname CreateArrayReference C.cJSON_CreateArrayReference
|
||||||
|
func CreateArrayReference(child *JSON) *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
||||||
|
//
|
||||||
|
//go:linkname CreateIntArray C.cJSON_CreateIntArray
|
||||||
|
func CreateIntArray(numbers *c.Int, count c.Int) *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
||||||
|
//
|
||||||
|
//go:linkname CreateFloatArray C.cJSON_CreateFloatArray
|
||||||
|
func CreateFloatArray(numbers *c.Float, count c.Int) *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
||||||
|
//
|
||||||
|
//go:linkname CreateDoubleArray C.cJSON_CreateDoubleArray
|
||||||
|
func CreateDoubleArray(numbers *c.Double, count c.Int) *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);
|
||||||
|
//
|
||||||
|
//go:linkname CreateStringArray C.cJSON_CreateStringArray
|
||||||
|
func CreateStringArray(strings *c.Char, count c.Int) *JSON
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||||
|
//
|
||||||
|
// Append item to the specified array.
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).AddItem C.cJSON_AddItemToArray
|
||||||
|
func (o *JSON) AddItem(item *JSON) Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||||
|
//
|
||||||
|
// same as AddItem func
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).AddItemToArray C.cJSON_AddItemToArray
|
||||||
|
func (o *JSON) AddItemToArray(item *JSON) Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||||
|
//
|
||||||
|
// Append item to the specified object.
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).SetItem C.cJSON_AddItemToObject
|
||||||
|
func (o *JSON) SetItem(key *c.Char, item *JSON) Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||||
|
//
|
||||||
|
// same as SetItem func
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).AddItemToObject C.cJSON_AddItemToObject
|
||||||
|
func (o *JSON) AddItemToObject(key *c.Char, item *JSON) Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
||||||
|
//
|
||||||
|
// Use this when string is definitely const (i.e. a literal, or as good as),
|
||||||
|
// and will definitely survive the cJSON object.
|
||||||
|
// warning that When this function was used, make sure to always check that
|
||||||
|
// (item->type & cJSON_StringIsConst) is zero before writing to `item->string`
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).AddItemToObjectCS C.cJSON_AddItemToObjectCS
|
||||||
|
func (o *JSON) AddItemToObjectCS(s *c.Char, item *JSON) Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||||
|
//
|
||||||
|
// Append reference to item to the specified array/object.
|
||||||
|
// Use this when you want to add an existing cJSON to a new cJSON,
|
||||||
|
// but don't want to corrupt your existing cJSON.
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).AddItemReferenceToArray C.cJSON_AddItemReferenceToArray
|
||||||
|
func (o *JSON) AddItemReferenceToArray(item *JSON) Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).AddItemReferenceToObject C.cJSON_AddItemReferenceToObject
|
||||||
|
func (o *JSON) AddItemReferenceToObject(s *c.Char, item *JSON) Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
|
||||||
|
//
|
||||||
|
// Remove/Detach items from Arrays/Objects.
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).DetachItemViaPointer C.cJSON_DetachItemViaPointer
|
||||||
|
func (o *JSON) DetachItemViaPointer(item *JSON) *JSON { return nil }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).DetachItemFromArray C.cJSON_DetachItemFromArray
|
||||||
|
func (o *JSON) DetachItemFromArray(which c.Int) *JSON { return nil }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).DeleteItemFromArray C.cJSON_DeleteItemFromArray
|
||||||
|
func (o *JSON) DeleteItemFromArray(which c.Int) {}
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).DetachItemFromObject C.cJSON_DetachItemFromObject
|
||||||
|
func (o *JSON) DetachItemFromObject(s *c.Char) *JSON { return nil }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).DetachItemFromObjectCaseSensitive C.cJSON_DetachItemFromObjectCaseSensitive
|
||||||
|
func (o *JSON) DetachItemFromObjectCaseSensitive(s *c.Char) *JSON { return nil }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).DeleteItemFromObject C.cJSON_DeleteItemFromObject
|
||||||
|
func (o *JSON) DeleteItemFromObject(s *c.Char) {}
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).DeleteItemFromObjectCaseSensitive C.cJSON_DeleteItemFromObjectCaseSensitive
|
||||||
|
func (o *JSON) DeleteItemFromObjectCaseSensitive(s *c.Char) {}
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||||
|
//
|
||||||
|
// Update array items.
|
||||||
|
// Shifts pre-existing items to the right.
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).InsertItemInArray C.cJSON_InsertItemInArray
|
||||||
|
func (o *JSON) InsertItemInArray(which c.Int, newitem *JSON) Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).ReplaceItemViaPointer C.cJSON_ReplaceItemViaPointer
|
||||||
|
func (o *JSON) ReplaceItemViaPointer(item *JSON, replacement *JSON) Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).ReplaceItemInArray C.cJSON_ReplaceItemInArray
|
||||||
|
func (o *JSON) ReplaceItemInArray(which c.Int, newitem *JSON) Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).ReplaceItemInObject C.cJSON_ReplaceItemInObject
|
||||||
|
func (o *JSON) ReplaceItemInObject(s *c.Char, newitem *JSON) Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).ReplaceItemInObjectCaseSensitive C.cJSON_ReplaceItemInObjectCaseSensitive
|
||||||
|
func (o *JSON) ReplaceItemInObjectCaseSensitive(s *c.Char, newitem *JSON) Bool {
|
||||||
|
return Bool(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_Bool recurse);
|
||||||
|
//
|
||||||
|
// Duplicate a cJSON item
|
||||||
|
//
|
||||||
|
// Duplicate will create a new, identical cJSON item to the one you pass,
|
||||||
|
// in new memory that will need to be released. With recurse!=0,
|
||||||
|
// it will duplicate any children connected to the item.
|
||||||
|
// The item->next and ->prev pointers are always zero on return from Duplicate.
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).Duplicate C.cJSON_Duplicate
|
||||||
|
func (o *JSON) Duplicate(recurse Bool) *JSON { return nil }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON_Bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_Bool case_sensitive);
|
||||||
|
//
|
||||||
|
// Recursively compare two cJSON items for equality. If either a or b is NULL or invalid,
|
||||||
|
// they will be considered unequal. case_sensitive determines if object keys are treated
|
||||||
|
// case sensitive (1) or case insensitive (0)
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).Compare C.cJSON_Compare
|
||||||
|
func (o *JSON) Compare(b *JSON, case_sensitive Bool) Bool { return Bool(0) }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
||||||
|
//
|
||||||
|
// Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
|
||||||
|
// The input pointer json cannot point to a read-only address area, such as a string constant,
|
||||||
|
// but should point to a readable and writable address area.
|
||||||
|
//
|
||||||
|
//go:linkname Minify C.cJSON_Minify
|
||||||
|
func Minify()
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
|
||||||
|
//
|
||||||
|
// Helper functions for creating and adding items to an object at the same time.
|
||||||
|
// They return the added item or NULL on failure.
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).AddNullToObject C.cJSON_AddNullToObject
|
||||||
|
func (o *JSON) AddNullToObject(name *c.Char) *JSON { return nil }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).AddTrueToObject C.cJSON_AddTrueToObject
|
||||||
|
func (o *JSON) AddTrueToObject(name *c.Char) *JSON { return nil }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).AddFalseToObject C.cJSON_AddFalseToObject
|
||||||
|
func (o *JSON) AddFalseToObject(name *c.Char) *JSON { return nil }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_Bool boolean);
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).AddBoolToObject C.cJSON_AddBoolToObject
|
||||||
|
func (o *JSON) AddBoolToObject(name *c.Char, b Bool) *JSON { return nil }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).AddNumberToObject C.cJSON_AddNumberToObject
|
||||||
|
func (o *JSON) AddNumberToObject(name *c.Char, num c.Double) *JSON { return nil }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).AddStringToObject C.cJSON_AddStringToObject
|
||||||
|
func (o *JSON) AddStringToObject(name *c.Char, s *c.Char) *JSON { return nil }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).AddRawToObject C.cJSON_AddRawToObject
|
||||||
|
func (o *JSON) AddRawToObject(name *c.Char, raw *c.Char) *JSON { return nil }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).AddObjectToObject C.cJSON_AddObjectToObject
|
||||||
|
func (o *JSON) AddObjectToObject(name *c.Char) *JSON { return nil }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).AddArrayToObject C.cJSON_AddArrayToObject
|
||||||
|
func (o *JSON) AddArrayToObject(name *c.Char) *JSON { return nil }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||||
|
//
|
||||||
|
// helper for the cJSON_SetNumberValue macro
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).SetNumberHelper C.cJSON_SetNumberHelper
|
||||||
|
func (o *JSON) SetNumberHelper(number c.Double) c.Double { return 0 }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
|
||||||
|
//
|
||||||
|
// Change the valuestring of a cJSON_String object, only takes effect when type of
|
||||||
|
// object is cJSON_String
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).SetValuestring C.cJSON_SetValuestring
|
||||||
|
func (o *JSON) SetValuestring(v *c.Char) *c.Char { return nil }
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
||||||
|
//
|
||||||
|
// malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks
|
||||||
|
//
|
||||||
|
//go:linkname Malloc C.cJSON_malloc
|
||||||
|
func Malloc(size uintptr)
|
||||||
|
|
||||||
|
// CJSON_PUBLIC(void) cJSON_free(void *object);
|
||||||
|
//
|
||||||
//go:linkname Free C.cJSON_free
|
//go:linkname Free C.cJSON_free
|
||||||
func Free(ptr unsafe.Pointer)
|
func Free(ptr unsafe.Pointer)
|
||||||
|
|
||||||
//go:linkname FreeCStr C.cJSON_free
|
|
||||||
func FreeCStr(*c.Char)
|
|
||||||
|
|||||||
35
c/clang/_demo/inclusion/inclusion.go
Normal file
35
c/clang/_demo/inclusion/inclusion.go
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/clang"
|
||||||
|
"github.com/goplus/llgo/compiler/chore/_xtool/llcppsymg/clangutils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
_, unit, err := clangutils.CreateTranslationUnit(&clangutils.Config{
|
||||||
|
File: "#include <stddef.h>",
|
||||||
|
Temp: true,
|
||||||
|
IsCpp: false,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
println(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
clang.GetInclusions(unit, func(included_file clang.File, inclusion_stack *clang.SourceLocation, include_len c.Uint, client_data c.Pointer) {
|
||||||
|
filename := included_file.FileName()
|
||||||
|
c.Printf(c.Str("Included file: %s Include length: %d\n"), filename.CStr(), include_len)
|
||||||
|
inclusions := unsafe.Slice(inclusion_stack, include_len)
|
||||||
|
for i := range inclusions {
|
||||||
|
loc := inclusions[i]
|
||||||
|
var file clang.File
|
||||||
|
var line, column c.Uint
|
||||||
|
loc.SpellingLocation(&file, &line, &column, nil)
|
||||||
|
filename = file.FileName()
|
||||||
|
c.Printf(c.Str(" included from: %s:%d:%d\n"), filename.CStr(), line, column)
|
||||||
|
}
|
||||||
|
}, nil)
|
||||||
|
}
|
||||||
@@ -15,9 +15,53 @@ CXChildVisitResult wrap_visitor(CXCursor cursor, CXCursor parent, CXClientData d
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
CXString wrap_clang_getCursorSpelling(CXCursor *cur) { return clang_getCursorSpelling(*cur); }
|
void wrap_clang_getLocation(CXTranslationUnit tu, CXFile file, unsigned line, unsigned column, CXSourceLocation *loc) {
|
||||||
|
*loc = clang_getLocation(tu, file, line, column);
|
||||||
|
}
|
||||||
|
|
||||||
CXString wrap_clang_Cursor_getMangling(CXCursor *cur) { return clang_Cursor_getMangling(*cur); }
|
void wrap_clang_getLocationForOffset(CXTranslationUnit tu, CXFile file, unsigned offset, CXSourceLocation *loc) {
|
||||||
|
*loc = clang_getLocationForOffset(tu, file, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wrap_clang_getTranslationUnitCursor(CXTranslationUnit uint, CXCursor *cur) {
|
||||||
|
*cur = clang_getTranslationUnitCursor(uint);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned wrap_clang_equalCursors(CXCursor *cursor1, CXCursor *cursor2) {
|
||||||
|
return clang_equalCursors(*cursor1, *cursor2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int wrap_clang_Cursor_isNull(CXCursor *cursor) { return clang_Cursor_isNull(*cursor); }
|
||||||
|
|
||||||
|
void wrap_clang_getCursorSemanticParent(CXCursor *C, CXCursor *parent) { *parent = clang_getCursorSemanticParent(*C); }
|
||||||
|
|
||||||
|
void wrap_clang_getCursorDefinition(CXCursor *C, CXCursor *def) { *def = clang_getCursorDefinition(*C); }
|
||||||
|
|
||||||
|
void wrap_clang_getCursorLexicalParent(CXCursor *C, CXCursor *parent) { *parent = clang_getCursorLexicalParent(*C); }
|
||||||
|
|
||||||
|
void wrap_clang_getOverriddenCursors(CXCursor *cursor, CXCursor **overridden, unsigned *num_overridden) {
|
||||||
|
clang_getOverriddenCursors(*cursor, overridden, num_overridden);
|
||||||
|
}
|
||||||
|
|
||||||
|
CXFile wrap_clang_getIncludedFile(CXCursor *cursor) { return clang_getIncludedFile(*cursor); }
|
||||||
|
|
||||||
|
void wrap_clang_getCursor(CXTranslationUnit uint, CXSourceLocation *loc, CXCursor *cur) {
|
||||||
|
*cur = clang_getCursor(uint, *loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wrap_clang_getCursorLocation(CXCursor *cur, CXSourceLocation *loc) { *loc = clang_getCursorLocation(*cur); }
|
||||||
|
|
||||||
|
void wrap_clang_getCursorExtent(CXCursor *cur, CXSourceRange *range) { *range = clang_getCursorExtent(*cur); }
|
||||||
|
|
||||||
|
void wrap_clang_getCursorType(CXCursor *cur, CXType *typ) { *typ = clang_getCursorType(*cur); }
|
||||||
|
|
||||||
|
CXString wrap_clang_getTypeSpelling(CXType *typ) { return clang_getTypeSpelling(*typ); }
|
||||||
|
|
||||||
|
void wrap_clang_getTypedefDeclUnderlyingType(CXCursor *cur, CXType *typ) {
|
||||||
|
*typ = clang_getTypedefDeclUnderlyingType(*cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
long long wrap_clang_getEnumConstantDeclValue(CXCursor *cur) { return clang_getEnumConstantDeclValue(*cur); }
|
||||||
|
|
||||||
int wrap_clang_Cursor_getNumArguments(CXCursor *cur) { return clang_Cursor_getNumArguments(*cur); }
|
int wrap_clang_Cursor_getNumArguments(CXCursor *cur) { return clang_Cursor_getNumArguments(*cur); }
|
||||||
|
|
||||||
@@ -25,13 +69,27 @@ void wrap_clang_Cursor_getArgument(CXCursor *C, unsigned i, CXCursor *argCur) {
|
|||||||
*argCur = clang_Cursor_getArgument(*C, i);
|
*argCur = clang_Cursor_getArgument(*C, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wrap_clang_getTranslationUnitCursor(CXTranslationUnit uint, CXCursor *cur) {
|
void wrap_clang_getCanonicalType(CXType *typ, CXType *canonicalType) { *canonicalType = clang_getCanonicalType(*typ); }
|
||||||
*cur = clang_getTranslationUnitCursor(uint);
|
|
||||||
|
unsigned wrap_clang_isConstQualifiedType(CXType *typ) { return clang_isConstQualifiedType(*typ); }
|
||||||
|
|
||||||
|
unsigned wrap_clang_Cursor_isMacroFunctionLike(CXCursor *cur) { return clang_Cursor_isMacroFunctionLike(*cur); }
|
||||||
|
|
||||||
|
unsigned wrap_clang_Cursor_isMacroBuiltin(CXCursor *cur) { return clang_Cursor_isMacroBuiltin(*cur); }
|
||||||
|
|
||||||
|
unsigned wrap_clang_Cursor_isFunctionInlined(CXCursor *cur) { return clang_Cursor_isFunctionInlined(*cur); }
|
||||||
|
|
||||||
|
unsigned wrap_clang_isVolatileQualifiedType(CXType *T) { return clang_isVolatileQualifiedType(*T); }
|
||||||
|
|
||||||
|
unsigned wrap_clang_isRestrictQualifiedType(CXType *T) { return clang_isRestrictQualifiedType(*T); }
|
||||||
|
|
||||||
|
void wrap_clang_getPointeeType(CXType *pointerTyp, CXType *pointeeTyp) {
|
||||||
|
*pointeeTyp = clang_getPointeeType(*pointerTyp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wrap_clang_getCursorType(CXCursor *cur, CXType *typ) { *typ = clang_getCursorType(*cur); }
|
void wrap_clang_getNonReferenceType(CXType *typ, CXType *nonRefTyp) { *nonRefTyp = clang_getNonReferenceType(*typ); }
|
||||||
|
|
||||||
void wrap_clang_getCursorResultType(CXCursor *cur, CXType *typ) { *typ = clang_getCursorResultType(*cur); }
|
void wrap_clang_getTypeDeclaration(CXType *typ, CXCursor *cur) { *cur = clang_getTypeDeclaration(*typ); }
|
||||||
|
|
||||||
void wrap_clang_getResultType(CXType *typ, CXType *resultTyp) { *resultTyp = clang_getResultType(*typ); }
|
void wrap_clang_getResultType(CXType *typ, CXType *resultTyp) { *resultTyp = clang_getResultType(*typ); }
|
||||||
|
|
||||||
@@ -39,36 +97,105 @@ int wrap_clang_getNumArgTypes(CXType *typ) { return clang_getNumArgTypes(*typ);
|
|||||||
|
|
||||||
void wrap_clang_getArgType(CXType *typ, unsigned i, CXType *argTyp) { *argTyp = clang_getArgType(*typ, i); }
|
void wrap_clang_getArgType(CXType *typ, unsigned i, CXType *argTyp) { *argTyp = clang_getArgType(*typ, i); }
|
||||||
|
|
||||||
long long wrap_clang_getEnumConstantDeclValue(CXCursor *cur) { return clang_getEnumConstantDeclValue(*cur); }
|
unsigned wrap_clang_isFunctionTypeVariadic(CXType *typ) { return clang_isFunctionTypeVariadic(*typ); }
|
||||||
|
|
||||||
void wrap_clang_getPointeeType(CXType *pointerTyp, CXType *pointeeTyp) {
|
void wrap_clang_getCursorResultType(CXCursor *cur, CXType *typ) { *typ = clang_getCursorResultType(*cur); }
|
||||||
*pointeeTyp = clang_getPointeeType(*pointerTyp);
|
|
||||||
}
|
void wrap_clang_getElementType(CXType *Typ, CXType *elemTyp) { *elemTyp = clang_getElementType(*Typ); }
|
||||||
|
|
||||||
void wrap_clang_getArrayElementType(CXType *arrayTyp, CXType *elemTyp) {
|
void wrap_clang_getArrayElementType(CXType *arrayTyp, CXType *elemTyp) {
|
||||||
*elemTyp = clang_getArrayElementType(*arrayTyp);
|
*elemTyp = clang_getArrayElementType(*arrayTyp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wrap_clang_getCanonicalType(CXType *typ, CXType *canonicalType) { *canonicalType = clang_getCanonicalType(*typ); }
|
long long wrap_clang_getArraySize(CXType *arrayTyp) { return clang_getArraySize(*arrayTyp); }
|
||||||
|
|
||||||
CXString wrap_clang_getTypeSpelling(CXType *typ) { return clang_getTypeSpelling(*typ); }
|
void wrap_clang_Type_getNamedType(CXType *typ, CXType *namedTyp) { *namedTyp = clang_Type_getNamedType(*typ); }
|
||||||
|
|
||||||
CXString wrap_clang_getTokenSpelling(CXTranslationUnit unit, CXToken *token) {
|
long long wrap_clang_Type_getSizeOf(CXType *typ) { return clang_Type_getSizeOf(*typ); }
|
||||||
return clang_getTokenSpelling(unit, *token);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wrap_clang_getCursorLocation(CXCursor *cur, CXSourceLocation *loc) { *loc = clang_getCursorLocation(*cur); }
|
unsigned wrap_clang_Cursor_isAnonymous(CXCursor *cursor) { return clang_Cursor_isAnonymous(*cursor); }
|
||||||
|
|
||||||
void wrap_clang_getSpellingLocation(CXSourceLocation *loc, CXFile *file, unsigned *line, unsigned *column,
|
unsigned wrap_clang_Cursor_isAnonymousRecordDecl(CXCursor *cursor) {
|
||||||
unsigned *offset) {
|
return clang_Cursor_isAnonymousRecordDecl(*cursor);
|
||||||
clang_getSpellingLocation(*loc, file, line, column, offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CX_CXXAccessSpecifier wrap_clang_getCXXAccessSpecifier(CXCursor *cursor) {
|
enum CX_CXXAccessSpecifier wrap_clang_getCXXAccessSpecifier(CXCursor *cursor) {
|
||||||
return clang_getCXXAccessSpecifier(*cursor);
|
return clang_getCXXAccessSpecifier(*cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wrap_clang_getCursorExtent(CXCursor *cur, CXSourceRange *range) { *range = clang_getCursorExtent(*cur); }
|
enum CX_StorageClass wrap_clang_Cursor_getStorageClass(CXCursor *cursor) {
|
||||||
|
return clang_Cursor_getStorageClass(*cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
CXString wrap_clang_getCursorUSR(CXCursor *cur) { return clang_getCursorUSR(*cur); }
|
||||||
|
|
||||||
|
CXString wrap_clang_getCursorSpelling(CXCursor *cur) { return clang_getCursorSpelling(*cur); }
|
||||||
|
|
||||||
|
CXString wrap_clang_getCursorDisplayName(CXCursor *cur) { return clang_getCursorDisplayName(*cur); }
|
||||||
|
|
||||||
|
void wrap_clang_getCursorReferenced(CXCursor *cur, CXCursor *referenced) {
|
||||||
|
*referenced = clang_getCursorReferenced(*cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned wrap_clang_Cursor_isVariadic(CXCursor *cur) { return clang_Cursor_isVariadic(*cur); }
|
||||||
|
|
||||||
|
void wrap_clang_Cursor_getCommentRange(CXCursor *cur, CXSourceRange *range) {
|
||||||
|
*range = clang_Cursor_getCommentRange(*cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
CXString wrap_clang_Cursor_getRawCommentText(CXCursor *cursor) { return clang_Cursor_getRawCommentText(*cursor); }
|
||||||
|
|
||||||
|
CXString wrap_clang_Cursor_getMangling(CXCursor *cur) { return clang_Cursor_getMangling(*cur); }
|
||||||
|
|
||||||
|
unsigned wrap_clang_CXXConstructor_isConvertingConstructor(CXCursor *cursor) {
|
||||||
|
return clang_CXXConstructor_isConvertingConstructor(*cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned wrap_clang_CXXConstructor_isCopyConstructor(CXCursor *cursor) {
|
||||||
|
return clang_CXXConstructor_isCopyConstructor(*cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned wrap_clang_CXXConstructor_isDefaultConstructor(CXCursor *cursor) {
|
||||||
|
return clang_CXXConstructor_isDefaultConstructor(*cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned wrap_clang_CXXConstructor_isMoveConstructor(CXCursor *cursor) {
|
||||||
|
return clang_CXXConstructor_isMoveConstructor(*cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned wrap_clang_CXXField_isMutable(CXCursor *cursor) { return clang_CXXField_isMutable(*cursor); }
|
||||||
|
|
||||||
|
unsigned wrap_clang_CXXMethod_isDefaulted(CXCursor *cursor) { return clang_CXXMethod_isDefaulted(*cursor); }
|
||||||
|
|
||||||
|
unsigned wrap_clang_CXXMethod_isDeleted(CXCursor *cursor) { return clang_CXXMethod_isDeleted(*cursor); }
|
||||||
|
|
||||||
|
unsigned wrap_clang_CXXMethod_isPureVirtual(CXCursor *cursor) { return clang_CXXMethod_isPureVirtual(*cursor); }
|
||||||
|
|
||||||
|
unsigned wrap_clang_CXXMethod_isStatic(CXCursor *cursor) { return clang_CXXMethod_isStatic(*cursor); }
|
||||||
|
|
||||||
|
unsigned wrap_clang_CXXMethod_isVirtual(CXCursor *cursor) { return clang_CXXMethod_isVirtual(*cursor); }
|
||||||
|
|
||||||
|
unsigned wrap_clang_CXXMethod_isCopyAssignmentOperator(CXCursor *cursor) {
|
||||||
|
return clang_CXXMethod_isCopyAssignmentOperator(*cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned wrap_clang_CXXMethod_isMoveAssignmentOperator(CXCursor *cursor) {
|
||||||
|
return clang_CXXMethod_isMoveAssignmentOperator(*cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned wrap_clang_CXXMethod_isExplicit(CXCursor *cursor) { return clang_CXXMethod_isExplicit(*cursor); }
|
||||||
|
|
||||||
|
unsigned wrap_clang_CXXRecord_isAbstract(CXCursor *cursor) { return clang_CXXRecord_isAbstract(*cursor); }
|
||||||
|
|
||||||
|
unsigned wrap_clang_EnumDecl_isScoped(CXCursor *cursor) { return clang_EnumDecl_isScoped(*cursor); }
|
||||||
|
|
||||||
|
unsigned wrap_clang_CXXMethod_isConst(CXCursor *cursor) { return clang_CXXMethod_isConst(*cursor); }
|
||||||
|
|
||||||
|
CXTokenKind wrap_clang_getTokenKind(CXToken *token) { return clang_getTokenKind(*token); }
|
||||||
|
|
||||||
|
CXString wrap_clang_getTokenSpelling(CXTranslationUnit unit, CXToken *token) {
|
||||||
|
return clang_getTokenSpelling(unit, *token);
|
||||||
|
}
|
||||||
|
|
||||||
void wrap_clang_tokenize(CXTranslationUnit unit, CXSourceRange *Range, CXToken **Tokens, unsigned *NumTokens) {
|
void wrap_clang_tokenize(CXTranslationUnit unit, CXSourceRange *Range, CXToken **Tokens, unsigned *NumTokens) {
|
||||||
clang_tokenize(unit, *Range, Tokens, NumTokens);
|
clang_tokenize(unit, *Range, Tokens, NumTokens);
|
||||||
@@ -79,4 +206,15 @@ unsigned wrap_clang_visitChildren(CXCursor *parent, wrap_CXCursorVisitor visitor
|
|||||||
return clang_visitChildren(*parent, wrap_visitor, CXClientData(&data));
|
return clang_visitChildren(*parent, wrap_visitor, CXClientData(&data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int wrap_clang_Location_isInSystemHeader(CXSourceLocation *loc) { return clang_Location_isInSystemHeader(*loc); }
|
||||||
|
|
||||||
|
void wrap_clang_getSpellingLocation(CXSourceLocation *loc, CXFile *file, unsigned *line, unsigned *column,
|
||||||
|
unsigned *offset) {
|
||||||
|
clang_getSpellingLocation(*loc, file, line, column, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wrap_clang_getRangeStart(CXSourceRange *range, CXSourceLocation *loc) { *loc = clang_getRangeStart(*range); }
|
||||||
|
|
||||||
|
void wrap_clang_getRangeEnd(CXSourceRange *range, CXSourceLocation *loc) { *loc = clang_getRangeEnd(*range); }
|
||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|||||||
@@ -57,3 +57,12 @@ type StringSet struct {
|
|||||||
*/
|
*/
|
||||||
// llgo:link (*StringSet).Dispose C.clang_disposeStringSet
|
// llgo:link (*StringSet).Dispose C.clang_disposeStringSet
|
||||||
func (*StringSet) Dispose() {}
|
func (*StringSet) Dispose() {}
|
||||||
|
|
||||||
|
func GoString(clangStr String) (str string) {
|
||||||
|
defer clangStr.Dispose()
|
||||||
|
cstr := clangStr.CStr()
|
||||||
|
if cstr != nil {
|
||||||
|
str = c.GoString(cstr)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
1346
c/clang/clang.go
1346
c/clang/clang.go
File diff suppressed because it is too large
Load Diff
27
c/debug/_demo/funcinfo/main.go
Normal file
27
c/debug/_demo/funcinfo/main.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/debug"
|
||||||
|
)
|
||||||
|
|
||||||
|
type T struct {
|
||||||
|
n int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *T) Demo() {
|
||||||
|
println(t.n)
|
||||||
|
addr := debug.Address()
|
||||||
|
c.Printf(c.Str("addr:0x%x\n"), addr)
|
||||||
|
var info debug.Info
|
||||||
|
r := debug.Addrinfo(addr, &info)
|
||||||
|
if r == 0 {
|
||||||
|
panic("not found info")
|
||||||
|
}
|
||||||
|
c.Printf(c.Str("func file:%s name:%s base:0x%x addr:0x%x\n"), info.Fname, info.Sname, info.Fbase, info.Saddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
t := &T{100}
|
||||||
|
t.Demo()
|
||||||
|
}
|
||||||
26
c/debug/_demo/stacktrace/main.go
Normal file
26
c/debug/_demo/stacktrace/main.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c/debug"
|
||||||
|
)
|
||||||
|
|
||||||
|
type T struct {
|
||||||
|
n int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *T) Demo() {
|
||||||
|
println(t.n)
|
||||||
|
debug.StackTrace(0, func(fr *debug.Frame) bool {
|
||||||
|
var info debug.Info
|
||||||
|
debug.Addrinfo(unsafe.Pointer(fr.PC), &info)
|
||||||
|
println("[", fr.PC, "]", fr.Name, "+", fr.Offset, ", SP =", fr.SP)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
t := &T{100}
|
||||||
|
t.Demo()
|
||||||
|
}
|
||||||
39
c/debug/_wrap/debug.c
Normal file
39
c/debug/_wrap/debug.c
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#if defined(__linux__)
|
||||||
|
#define UNW_LOCAL_ONLY
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <features.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <libunwind.h>
|
||||||
|
|
||||||
|
void *llgo_address() {
|
||||||
|
return __builtin_return_address(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int llgo_addrinfo(void *addr, Dl_info *info) {
|
||||||
|
return dladdr(addr, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
void llgo_stacktrace(int skip, void *ctx, int (*fn)(void *ctx, void *pc, void *offset, void *sp, char *name)) {
|
||||||
|
unw_cursor_t cursor;
|
||||||
|
unw_context_t context;
|
||||||
|
unw_word_t offset, pc, sp;
|
||||||
|
char fname[256];
|
||||||
|
unw_getcontext(&context);
|
||||||
|
unw_init_local(&cursor, &context);
|
||||||
|
int depth = 0;
|
||||||
|
while (unw_step(&cursor) > 0) {
|
||||||
|
if (depth < skip) {
|
||||||
|
depth++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (unw_get_reg(&cursor, UNW_REG_IP, &pc) == 0) {
|
||||||
|
unw_get_proc_name(&cursor, fname, sizeof(fname), &offset);
|
||||||
|
unw_get_reg(&cursor, UNW_REG_SP, &sp);
|
||||||
|
if (fn(ctx, (void*)pc, (void*)offset, (void*)sp, fname) == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
49
c/debug/debug.go
Normal file
49
c/debug/debug.go
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
package debug
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo linux LDFLAGS: -lunwind
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LLGoPackage = "link"
|
||||||
|
LLGoFiles = "_wrap/debug.c"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Info struct {
|
||||||
|
Fname *c.Char
|
||||||
|
Fbase c.Pointer
|
||||||
|
Sname *c.Char
|
||||||
|
Saddr c.Pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:linkname Address C.llgo_address
|
||||||
|
func Address() unsafe.Pointer
|
||||||
|
|
||||||
|
//go:linkname Addrinfo C.llgo_addrinfo
|
||||||
|
func Addrinfo(addr unsafe.Pointer, info *Info) c.Int
|
||||||
|
|
||||||
|
//go:linkname stacktrace C.llgo_stacktrace
|
||||||
|
func stacktrace(skip c.Int, ctx unsafe.Pointer, fn func(ctx, pc, offset, sp unsafe.Pointer, name *c.Char) c.Int)
|
||||||
|
|
||||||
|
type Frame struct {
|
||||||
|
PC uintptr
|
||||||
|
Offset uintptr
|
||||||
|
SP unsafe.Pointer
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func StackTrace(skip int, fn func(fr *Frame) bool) {
|
||||||
|
stacktrace(c.Int(1+skip), unsafe.Pointer(&fn), func(ctx, pc, offset, sp unsafe.Pointer, name *c.Char) c.Int {
|
||||||
|
fn := *(*func(fr *Frame) bool)(ctx)
|
||||||
|
if !fn(&Frame{uintptr(pc), uintptr(offset), sp, c.GoString(name)}) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
})
|
||||||
|
}
|
||||||
25
c/ffi/_demo/_wrap/wrap.c
Normal file
25
c/ffi/_demo/_wrap/wrap.c
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
struct array
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int z;
|
||||||
|
int k;
|
||||||
|
};
|
||||||
|
|
||||||
|
int demo1(struct array a)
|
||||||
|
{
|
||||||
|
printf("c.demo1: %d %d %d %d\n",a.x,a.y,a.z,a.k);
|
||||||
|
return a.x+a.y+a.z+a.k;
|
||||||
|
}
|
||||||
|
|
||||||
|
int demo2( int (*fn)(struct array)) {
|
||||||
|
printf("c.demo2: %p\n",fn);
|
||||||
|
struct array a;
|
||||||
|
a.x = 1;
|
||||||
|
a.y = 2;
|
||||||
|
a.z = 3;
|
||||||
|
a.k = 4;
|
||||||
|
return (*fn)(a);
|
||||||
|
}
|
||||||
65
c/ffi/_demo/cfunc/main.go
Normal file
65
c/ffi/_demo/cfunc/main.go
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/ffi"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LLGoPackage = "link"
|
||||||
|
LLGoFiles = "../_wrap/wrap.c"
|
||||||
|
)
|
||||||
|
|
||||||
|
//llgo:type C
|
||||||
|
type Callback func(array) c.Int
|
||||||
|
|
||||||
|
//go:linkname demo1 C.demo1
|
||||||
|
func demo1(array) c.Int
|
||||||
|
|
||||||
|
//go:linkname demo2 C.demo2
|
||||||
|
func demo2(fn Callback) c.Int
|
||||||
|
|
||||||
|
//llgo:type C
|
||||||
|
type array struct {
|
||||||
|
x c.Int
|
||||||
|
y c.Int
|
||||||
|
z c.Int
|
||||||
|
k c.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
typeInt32 = &ffi.Type{4, 4, ffi.Sint32, nil}
|
||||||
|
typePointer = &ffi.Type{unsafe.Sizeof(0), uint16(unsafe.Alignof(0)), ffi.Pointer, nil}
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
cdemo1()
|
||||||
|
cdemo2()
|
||||||
|
}
|
||||||
|
|
||||||
|
func cdemo1() {
|
||||||
|
var cif ffi.Cif
|
||||||
|
tarray := &ffi.Type{0, 0, ffi.Struct, &[]*ffi.Type{typeInt32, typeInt32, typeInt32, typeInt32, nil}[0]}
|
||||||
|
status := ffi.PrepCif(&cif, ffi.DefaultAbi, 1, typeInt32, &[]*ffi.Type{tarray}[0])
|
||||||
|
if status != ffi.OK {
|
||||||
|
panic(status)
|
||||||
|
}
|
||||||
|
ar := array{1, 2, 3, 4}
|
||||||
|
var ret int32
|
||||||
|
ffi.Call(&cif, c.Func(demo1), unsafe.Pointer(&ret), &[]unsafe.Pointer{unsafe.Pointer(&ar)}[0])
|
||||||
|
c.Printf(c.Str("ret: %d\n"), ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
func cdemo2() {
|
||||||
|
var cif ffi.Cif
|
||||||
|
status := ffi.PrepCif(&cif, ffi.DefaultAbi, 1, typeInt32, &[]*ffi.Type{typePointer}[0])
|
||||||
|
if status != ffi.OK {
|
||||||
|
panic(status)
|
||||||
|
}
|
||||||
|
var ret int32
|
||||||
|
fn := c.Func(demo1)
|
||||||
|
ffi.Call(&cif, c.Func(demo2), unsafe.Pointer(&ret), &[]unsafe.Pointer{unsafe.Pointer(&fn)}[0])
|
||||||
|
c.Printf(c.Str("ret: %d\n"), ret)
|
||||||
|
}
|
||||||
93
c/ffi/_demo/closure/main.go
Normal file
93
c/ffi/_demo/closure/main.go
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/ffi"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LLGoPackage = "link"
|
||||||
|
LLGoFiles = "../_wrap/wrap.c"
|
||||||
|
)
|
||||||
|
|
||||||
|
//llgo:type C
|
||||||
|
type Callback func(array) c.Int
|
||||||
|
|
||||||
|
//go:linkname demo1 C.demo1
|
||||||
|
func demo1(array) c.Int
|
||||||
|
|
||||||
|
//go:linkname demo2 C.demo2
|
||||||
|
func demo2(fn Callback) c.Int
|
||||||
|
|
||||||
|
//llgo:type C
|
||||||
|
type array struct {
|
||||||
|
x c.Int
|
||||||
|
y c.Int
|
||||||
|
z c.Int
|
||||||
|
k c.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
func demo(a array) c.Int {
|
||||||
|
c.Printf(c.Str("go.demo %d %d %d %d\n"), a.x, a.y, a.z, a.k)
|
||||||
|
return a.x + a.y + a.z + a.k
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
typeInt32 = &ffi.Type{4, 4, ffi.Sint32, nil}
|
||||||
|
typePointer = &ffi.Type{unsafe.Sizeof(0), uint16(unsafe.Alignof(0)), ffi.Pointer, nil}
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
gofn()
|
||||||
|
c.Printf(c.Str("\n"))
|
||||||
|
goclosure()
|
||||||
|
}
|
||||||
|
|
||||||
|
func gofn() {
|
||||||
|
var cif ffi.Cif
|
||||||
|
status := ffi.PrepCif(&cif, ffi.DefaultAbi, 1, typeInt32, &[]*ffi.Type{typePointer}[0])
|
||||||
|
if status != ffi.OK {
|
||||||
|
panic(status)
|
||||||
|
}
|
||||||
|
var fncode unsafe.Pointer
|
||||||
|
closure := ffi.ClosureAlloc(&fncode)
|
||||||
|
defer ffi.ClosureFree(closure)
|
||||||
|
status = ffi.PreClosureLoc(closure, &cif, func(cif *ffi.Cif, ret unsafe.Pointer, args *unsafe.Pointer, userdata unsafe.Pointer) {
|
||||||
|
ar := *(*array)(ffi.Index(args, 0))
|
||||||
|
*(*c.Int)(ret) = demo(ar)
|
||||||
|
}, nil, fncode)
|
||||||
|
if status != ffi.OK {
|
||||||
|
panic(status)
|
||||||
|
}
|
||||||
|
var ret int32
|
||||||
|
ffi.Call(&cif, c.Func(demo2), unsafe.Pointer(&ret), &[]unsafe.Pointer{unsafe.Pointer(&fncode)}[0])
|
||||||
|
c.Printf(c.Str("ret: %d\n"), ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
func goclosure() {
|
||||||
|
var cif ffi.Cif
|
||||||
|
status := ffi.PrepCif(&cif, ffi.DefaultAbi, 1, typeInt32, &[]*ffi.Type{typePointer}[0])
|
||||||
|
if status != ffi.OK {
|
||||||
|
panic(status)
|
||||||
|
}
|
||||||
|
fn := func(ar array) c.Int {
|
||||||
|
c.Printf(c.Str("call closure %d\n"), cif.NArgs)
|
||||||
|
return demo(ar)
|
||||||
|
}
|
||||||
|
var fncode unsafe.Pointer
|
||||||
|
closure := ffi.ClosureAlloc(&fncode)
|
||||||
|
defer ffi.ClosureFree(closure)
|
||||||
|
status = ffi.PreClosureLoc(closure, &cif, func(cif *ffi.Cif, ret unsafe.Pointer, args *unsafe.Pointer, userdata unsafe.Pointer) {
|
||||||
|
ar := *(*array)(ffi.Index(args, 0))
|
||||||
|
fn := *(*func(array) c.Int)(userdata)
|
||||||
|
*(*c.Int)(ret) = fn(ar)
|
||||||
|
}, unsafe.Pointer(&fn), fncode)
|
||||||
|
if status != ffi.OK {
|
||||||
|
panic(status)
|
||||||
|
}
|
||||||
|
var ret int32
|
||||||
|
ffi.Call(&cif, c.Func(demo2), unsafe.Pointer(&ret), &[]unsafe.Pointer{unsafe.Pointer(&fncode)}[0])
|
||||||
|
c.Printf(c.Str("ret: %d\n"), ret)
|
||||||
|
}
|
||||||
26
c/ffi/_demo/printf/main.go
Normal file
26
c/ffi/_demo/printf/main.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/ffi"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
typeInt32 = &ffi.Type{4, 4, ffi.Sint32, nil}
|
||||||
|
typePointer = &ffi.Type{unsafe.Sizeof(0), uint16(unsafe.Alignof(0)), ffi.Pointer, nil}
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var cif ffi.Cif
|
||||||
|
status := ffi.PrepCifVar(&cif, ffi.DefaultAbi, 1, 2, typeInt32, &[]*ffi.Type{typePointer, typeInt32}[0])
|
||||||
|
if status != ffi.OK {
|
||||||
|
panic(status)
|
||||||
|
}
|
||||||
|
var ret int32
|
||||||
|
text := c.Str("hello world: %d\n")
|
||||||
|
var n int32 = 100
|
||||||
|
ffi.Call(&cif, c.Func(c.Printf), unsafe.Pointer(&ret), &[]unsafe.Pointer{unsafe.Pointer(&text), unsafe.Pointer(&n)}[0])
|
||||||
|
c.Printf(c.Str("ret: %d\n"), ret)
|
||||||
|
}
|
||||||
5
c/ffi/_wrap/libffi.c
Normal file
5
c/ffi/_wrap/libffi.c
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#include <ffi.h>
|
||||||
|
|
||||||
|
void *llog_ffi_closure_alloc(void **code) {
|
||||||
|
return ffi_closure_alloc(sizeof(ffi_closure), code);
|
||||||
|
}
|
||||||
7
c/ffi/abi.go
Normal file
7
c/ffi/abi.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
//go:build ((freebsd || linux || darwin) && arm64) || (windows && (amd64 || arm64))
|
||||||
|
|
||||||
|
package ffi
|
||||||
|
|
||||||
|
const (
|
||||||
|
DefaultAbi = 1
|
||||||
|
)
|
||||||
7
c/ffi/abi_amd64.go
Normal file
7
c/ffi/abi_amd64.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
//go:build freebsd || linux || darwin
|
||||||
|
|
||||||
|
package ffi
|
||||||
|
|
||||||
|
const (
|
||||||
|
DefaultAbi = 2
|
||||||
|
)
|
||||||
132
c/ffi/ffi.go
Normal file
132
c/ffi/ffi.go
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
package ffi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LLGoPackage = "link: $(pkg-config --libs libffi); -lffi"
|
||||||
|
LLGoFiles = "$(pkg-config --cflags libffi): _wrap/libffi.c"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
Void = iota
|
||||||
|
Int
|
||||||
|
Float
|
||||||
|
Double
|
||||||
|
LongDouble
|
||||||
|
Uint8
|
||||||
|
Sint8
|
||||||
|
Uint16
|
||||||
|
Sint16
|
||||||
|
Uint32
|
||||||
|
Sint32
|
||||||
|
Uint64
|
||||||
|
Sint64
|
||||||
|
Struct
|
||||||
|
Pointer
|
||||||
|
Complex
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
OK = iota
|
||||||
|
BAD_TYPEDEF
|
||||||
|
BAD_ABI
|
||||||
|
BAD_ARGTYPE
|
||||||
|
)
|
||||||
|
|
||||||
|
type Type struct {
|
||||||
|
Size uintptr
|
||||||
|
Alignment uint16
|
||||||
|
Type uint16
|
||||||
|
Elements **Type
|
||||||
|
}
|
||||||
|
|
||||||
|
/*typedef struct {
|
||||||
|
ffi_abi abi;
|
||||||
|
unsigned nargs;
|
||||||
|
ffi_type **arg_types;
|
||||||
|
ffi_type *rtype;
|
||||||
|
unsigned bytes;
|
||||||
|
unsigned flags;
|
||||||
|
#ifdef FFI_EXTRA_CIF_FIELDS
|
||||||
|
FFI_EXTRA_CIF_FIELDS;
|
||||||
|
#endif
|
||||||
|
} ffi_cif;
|
||||||
|
*/
|
||||||
|
|
||||||
|
type Cif struct {
|
||||||
|
Abi c.Uint
|
||||||
|
NArgs c.Uint
|
||||||
|
ArgTypes **Type
|
||||||
|
RType *Type
|
||||||
|
Bytes c.Uint
|
||||||
|
Flags c.Uint
|
||||||
|
//Extra c.Uint
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ffi_status
|
||||||
|
ffi_prep_cif(ffi_cif *cif,
|
||||||
|
ffi_abi abi,
|
||||||
|
unsigned int nargs,
|
||||||
|
ffi_type *rtype,
|
||||||
|
ffi_type **atypes);
|
||||||
|
*/
|
||||||
|
//go:linkname PrepCif C.ffi_prep_cif
|
||||||
|
func PrepCif(cif *Cif, abi c.Uint, nargs c.Uint, rtype *Type, atype **Type) c.Uint
|
||||||
|
|
||||||
|
/*
|
||||||
|
ffi_status ffi_prep_cif_var(ffi_cif *cif,
|
||||||
|
ffi_abi abi,
|
||||||
|
unsigned int nfixedargs,
|
||||||
|
unsigned int ntotalargs,
|
||||||
|
ffi_type *rtype,
|
||||||
|
ffi_type **atypes);
|
||||||
|
*/
|
||||||
|
//go:linkname PrepCifVar C.ffi_prep_cif_var
|
||||||
|
func PrepCifVar(cif *Cif, abi c.Uint, nfixedargs c.Uint, ntotalargs c.Uint, rtype *Type, atype **Type) c.Uint
|
||||||
|
|
||||||
|
/*
|
||||||
|
void ffi_call(ffi_cif *cif,
|
||||||
|
void (*fn)(void),
|
||||||
|
void *rvalue,
|
||||||
|
void **avalue);
|
||||||
|
*/
|
||||||
|
//go:linkname Call C.ffi_call
|
||||||
|
func Call(cif *Cif, fn unsafe.Pointer, rvalue unsafe.Pointer, avalue *unsafe.Pointer)
|
||||||
|
|
||||||
|
// void *ffi_closure_alloc (size_t size, void **code);
|
||||||
|
//
|
||||||
|
//go:linkname ClosureAlloc C.llog_ffi_closure_alloc
|
||||||
|
func ClosureAlloc(code *unsafe.Pointer) unsafe.Pointer
|
||||||
|
|
||||||
|
// void ffi_closure_free (void *);
|
||||||
|
//
|
||||||
|
//go:linkname ClosureFree C.ffi_closure_free
|
||||||
|
func ClosureFree(unsafe.Pointer)
|
||||||
|
|
||||||
|
/*
|
||||||
|
ffi_status
|
||||||
|
ffi_prep_closure_loc (ffi_closure*,
|
||||||
|
ffi_cif *,
|
||||||
|
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||||
|
void *user_data,
|
||||||
|
void *codeloc);
|
||||||
|
*/
|
||||||
|
|
||||||
|
//llgo:type C
|
||||||
|
type ClosureFunc func(cif *Cif, ret unsafe.Pointer, args *unsafe.Pointer, userdata unsafe.Pointer)
|
||||||
|
|
||||||
|
//go:linkname PreClosureLoc C.ffi_prep_closure_loc
|
||||||
|
func PreClosureLoc(closure unsafe.Pointer, cif *Cif, fn ClosureFunc, userdata unsafe.Pointer, codeloc unsafe.Pointer) c.Uint
|
||||||
|
|
||||||
|
func add(ptr unsafe.Pointer, offset uintptr) unsafe.Pointer {
|
||||||
|
return unsafe.Pointer(uintptr(ptr) + offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Index(args *unsafe.Pointer, i uintptr) unsafe.Pointer {
|
||||||
|
return (*(*unsafe.Pointer)(add(unsafe.Pointer(args), i*unsafe.Sizeof(0))))
|
||||||
|
}
|
||||||
@@ -9,10 +9,10 @@ import (
|
|||||||
var DEFAULT_PORT c.Int = 8080
|
var DEFAULT_PORT c.Int = 8080
|
||||||
var DEFAULT_BACKLOG c.Int = 128
|
var DEFAULT_BACKLOG c.Int = 128
|
||||||
|
|
||||||
var (
|
type WriteReq struct {
|
||||||
Req *libuv.Write
|
Req libuv.Write
|
||||||
Buf libuv.Buf
|
Buf libuv.Buf
|
||||||
)
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Initialize the default event loop
|
// Initialize the default event loop
|
||||||
@@ -39,9 +39,13 @@ func main() {
|
|||||||
loop.Run(libuv.RUN_DEFAULT)
|
loop.Run(libuv.RUN_DEFAULT)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FreeWriteReq() {
|
func FreeWriteReq(req *libuv.Write) {
|
||||||
|
wr := (*WriteReq)(c.Pointer(req))
|
||||||
// Free the buffer base.
|
// Free the buffer base.
|
||||||
c.Free(c.Pointer(Buf.Base))
|
if wr.Buf.Base != nil {
|
||||||
|
c.Free(c.Pointer(wr.Buf.Base))
|
||||||
|
wr.Buf.Base = nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func AllocBuffer(handle *libuv.Handle, suggestedSize uintptr, buf *libuv.Buf) {
|
func AllocBuffer(handle *libuv.Handle, suggestedSize uintptr, buf *libuv.Buf) {
|
||||||
@@ -54,16 +58,16 @@ func EchoWrite(req *libuv.Write, status c.Int) {
|
|||||||
if status != 0 {
|
if status != 0 {
|
||||||
c.Fprintf(c.Stderr, c.Str("Write error: %s\n"), libuv.Strerror(libuv.Errno(status)))
|
c.Fprintf(c.Stderr, c.Str("Write error: %s\n"), libuv.Strerror(libuv.Errno(status)))
|
||||||
}
|
}
|
||||||
FreeWriteReq()
|
FreeWriteReq(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func EchoRead(client *libuv.Stream, nread c.Long, buf *libuv.Buf) {
|
func EchoRead(client *libuv.Stream, nread c.Long, buf *libuv.Buf) {
|
||||||
if nread > 0 {
|
if nread > 0 {
|
||||||
|
req := new(WriteReq)
|
||||||
// Initialize the buffer with the data read.
|
// Initialize the buffer with the data read.
|
||||||
Buf = libuv.InitBuf(buf.Base, c.Uint(nread))
|
req.Buf = libuv.InitBuf(buf.Base, c.Uint(nread))
|
||||||
// Write the data back to the client.
|
// Write the data back to the client.
|
||||||
Req = &libuv.Write{}
|
req.Req.Write(client, &req.Buf, 1, EchoWrite)
|
||||||
Req.Write(client, &Buf, 1, EchoWrite)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if nread < 0 {
|
if nread < 0 {
|
||||||
@@ -96,7 +100,6 @@ func OnNewConnection(server *libuv.Stream, status c.Int) {
|
|||||||
// Initialize the client TCP handle.
|
// Initialize the client TCP handle.
|
||||||
if libuv.InitTcp(libuv.DefaultLoop(), client) < 0 {
|
if libuv.InitTcp(libuv.DefaultLoop(), client) < 0 {
|
||||||
c.Fprintf(c.Stderr, c.Str("Failed to initialize client\n"))
|
c.Fprintf(c.Stderr, c.Str("Failed to initialize client\n"))
|
||||||
c.Free(c.Pointer(client))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
27
c/libuv/check.go
Normal file
27
c/libuv/check.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package libuv
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* Handle types. */
|
||||||
|
|
||||||
|
type Check struct {
|
||||||
|
Unused [120]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function type */
|
||||||
|
|
||||||
|
// llgo:type C
|
||||||
|
type CheckCb func(Check *Check)
|
||||||
|
|
||||||
|
//go:linkname InitCheck C.uv_check_init
|
||||||
|
func InitCheck(loop *Loop, Check *Check) c.Int
|
||||||
|
|
||||||
|
// llgo:link (*Check).Start C.uv_check_start
|
||||||
|
func (Check *Check) Start(CheckCb CheckCb) c.Int { return 0 }
|
||||||
|
|
||||||
|
// llgo:link (*Check).Stop C.uv_check_stop
|
||||||
|
func (Check *Check) Stop() c.Int { return 0 }
|
||||||
@@ -95,7 +95,7 @@ const (
|
|||||||
ECHARSET Errno = -4080
|
ECHARSET Errno = -4080
|
||||||
ENONET Errno = -4056
|
ENONET Errno = -4056
|
||||||
UNKNOWN Errno = -4094
|
UNKNOWN Errno = -4094
|
||||||
EOF Errno = -1
|
EOF Errno = -4095
|
||||||
EREMOTEIO Errno = -4030
|
EREMOTEIO Errno = -4030
|
||||||
ERRNO_MAX Errno = EOF - 1
|
ERRNO_MAX Errno = EOF - 1
|
||||||
)
|
)
|
||||||
|
|||||||
27
c/libuv/idle.go
Normal file
27
c/libuv/idle.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package libuv
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* Handle types. */
|
||||||
|
|
||||||
|
type Idle struct {
|
||||||
|
Unused [120]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function type */
|
||||||
|
|
||||||
|
// llgo:type C
|
||||||
|
type IdleCb func(idle *Idle)
|
||||||
|
|
||||||
|
//go:linkname InitIdle C.uv_idle_init
|
||||||
|
func InitIdle(loop *Loop, idle *Idle) c.Int
|
||||||
|
|
||||||
|
// llgo:link (*Idle).Start C.uv_idle_start
|
||||||
|
func (idle *Idle) Start(idleCb IdleCb) c.Int { return 0 }
|
||||||
|
|
||||||
|
// llgo:link (*Idle).Stop C.uv_idle_stop
|
||||||
|
func (idle *Idle) Stop() c.Int { return 0 }
|
||||||
@@ -99,7 +99,8 @@ type Loop struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Poll struct {
|
type Poll struct {
|
||||||
Unused [0]byte
|
Data c.Pointer
|
||||||
|
Unused [160]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Request types. */
|
/* Request types. */
|
||||||
@@ -212,6 +213,16 @@ func LoopNew() *Loop {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// llgo:link (*Loop).SetData C.uv_loop_set_data
|
||||||
|
func (loop *Loop) SetData(data c.Pointer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// llgo:link (*Loop).GetData C.uv_loop_get_data
|
||||||
|
func (loop *Loop) GetData() c.Pointer {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// llgo:link (*Loop).Now C.uv_now
|
// llgo:link (*Loop).Now C.uv_now
|
||||||
func (loop *Loop) Now() c.UlongLong {
|
func (loop *Loop) Now() c.UlongLong {
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -83,18 +83,21 @@ type Tcp struct {
|
|||||||
Unused [256]byte
|
Unused [256]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(spongehah): Udp
|
||||||
type Udp struct {
|
type Udp struct {
|
||||||
Unused [0]byte
|
Unused [224]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Request types. */
|
/* Request types. */
|
||||||
|
|
||||||
|
// TODO(spongehah): Req
|
||||||
type Req struct {
|
type Req struct {
|
||||||
Unused [0]byte
|
Unused [64]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(spongehah): UdpSend
|
||||||
type UdpSend struct {
|
type UdpSend struct {
|
||||||
Unused [0]byte
|
Unused [320]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(spongehah): Write
|
// TODO(spongehah): Write
|
||||||
@@ -109,16 +112,19 @@ type Connect struct {
|
|||||||
Unused [88]byte
|
Unused [88]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(spongehah): GetAddrInfo
|
||||||
type GetAddrInfo struct {
|
type GetAddrInfo struct {
|
||||||
Unused [0]byte
|
Unused [160]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(spongehah): GetNameInfo
|
||||||
type GetNameInfo struct {
|
type GetNameInfo struct {
|
||||||
Unused [0]byte
|
Unused [1320]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(spongehah): Shutdown
|
||||||
type Shutdown struct {
|
type Shutdown struct {
|
||||||
Unused [0]byte
|
Unused [80]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
@@ -259,6 +265,11 @@ func (req *Req) GetType() ReqType {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// llgo:link (*Req).Cancel C.uv_cancel
|
||||||
|
func (req *Req) Cancel() c.Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
|
|
||||||
/* Stream related function and method */
|
/* Stream related function and method */
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
/* Handle types. */
|
/* Handle types. */
|
||||||
|
|
||||||
type Signal struct {
|
type Signal struct {
|
||||||
Unused [0]byte
|
Unused [152]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
|
|||||||
78
c/libuv/thread.go
Normal file
78
c/libuv/thread.go
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
package libuv
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Thread struct {
|
||||||
|
Unused [8]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type ThreadOptions struct {
|
||||||
|
flags c.Uint
|
||||||
|
stackSize uintptr
|
||||||
|
}
|
||||||
|
|
||||||
|
type Work struct {
|
||||||
|
Unused [128]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------
|
||||||
|
|
||||||
|
/* Function type */
|
||||||
|
|
||||||
|
// llgo:type C
|
||||||
|
type ThreadCb func(arg c.Pointer)
|
||||||
|
|
||||||
|
//llgo:type C
|
||||||
|
type WorkCb func(req *Work)
|
||||||
|
|
||||||
|
//llgo:type C
|
||||||
|
type AfterWorkCb func(req *Work, status c.Int)
|
||||||
|
|
||||||
|
// ----------------------------------------------
|
||||||
|
|
||||||
|
/* Thread related functions and method. */
|
||||||
|
|
||||||
|
//go:linkname ThreadEqual C.uv_thread_equal
|
||||||
|
func ThreadEqual(t1 *Thread, t2 *Thread) c.Int
|
||||||
|
|
||||||
|
//go:linkname ThreadGetCPU C.uv_thread_getcpu
|
||||||
|
func ThreadGetCPU() c.Int
|
||||||
|
|
||||||
|
//go:linkname ThreadSelf C.uv_thread_self
|
||||||
|
func ThreadSelf() Thread
|
||||||
|
|
||||||
|
// llgo:link (*Thread).Create C.uv_thread_create
|
||||||
|
func (t *Thread) Create(entry ThreadCb, arg c.Pointer) c.Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// llgo:link (*Thread).CreateEx C.uv_thread_create_ex
|
||||||
|
func (t *Thread) CreateEx(entry ThreadCb, params *ThreadOptions, arg c.Pointer) c.Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// llgo:link (*Thread).Join C.uv_thread_join
|
||||||
|
func (t *Thread) Join() c.Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// llgo:link (*Thread).SetAffinity C.uv_thread_set_affinity
|
||||||
|
func (t *Thread) SetAffinity(cpuMask *c.Char, oldMask *c.Char, maskSize uintptr) c.Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// llgo:link (*Thread).GetAffinity C.uv_thread_get_affinity
|
||||||
|
func (t *Thread) GetAffinity(cpuMask *c.Char, maskSize uintptr) c.Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------
|
||||||
|
|
||||||
|
/* Work related functions and method. */
|
||||||
|
|
||||||
|
//go:linkname QueueWork C.uv_queue_work
|
||||||
|
func QueueWork(loop *Loop, req *Work, workCb WorkCb, afterWorkCb AfterWorkCb) c.Int
|
||||||
@@ -12,12 +12,12 @@ import (
|
|||||||
|
|
||||||
// TODO(spongehah): Timer
|
// TODO(spongehah): Timer
|
||||||
type Timer struct {
|
type Timer struct {
|
||||||
Unused [0]byte
|
Unused [152]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
|
|
||||||
// llgo:type Cgit
|
// llgo:type C
|
||||||
type TimerCb func(timer *Timer)
|
type TimerCb func(timer *Timer)
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
@@ -28,7 +28,7 @@ type TimerCb func(timer *Timer)
|
|||||||
func InitTimer(loop *Loop, timer *Timer) c.Int
|
func InitTimer(loop *Loop, timer *Timer) c.Int
|
||||||
|
|
||||||
// llgo:link (*Timer).Start C.uv_timer_start
|
// llgo:link (*Timer).Start C.uv_timer_start
|
||||||
func (timer *Timer) Start(cb TimerCb, timeout uint64, repeat uint64) c.Int {
|
func (timer *Timer) Start(cb TimerCb, timeoutMs uint64, repeat uint64) c.Int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ func coroutineFunc(L *lua.State) c.Int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
L := lua.Newstate()
|
L := lua.Newstate__1()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
|
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ func coroutineFunc(L *lua.State) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
L := lua.Newstate()
|
L := lua.Newstate__1()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
|
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
|
|||||||
72
c/lua/_demo/crroutine-continue/corroutine.go
Normal file
72
c/lua/_demo/crroutine-continue/corroutine.go
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/lua"
|
||||||
|
)
|
||||||
|
|
||||||
|
func countdownContinue(L *lua.State, status c.Int, ctx lua.KContext) c.Int {
|
||||||
|
return countdown(L)
|
||||||
|
}
|
||||||
|
|
||||||
|
func countdown(L *lua.State) c.Int {
|
||||||
|
arg := L.Tointeger(lua.Upvalueindex(1))
|
||||||
|
c.Printf(c.Str("resume called with %d\n"), arg)
|
||||||
|
if arg > 0 {
|
||||||
|
L.Pushinteger(arg - 1)
|
||||||
|
L.Replace(lua.Upvalueindex(1))
|
||||||
|
L.Pushinteger(arg)
|
||||||
|
return L.Yieldk(1, c.Pointer(uintptr(0)), countdownContinue)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func createCountdown(L *lua.State) c.Int {
|
||||||
|
max := L.Checkinteger(1)
|
||||||
|
L.Pushinteger(max)
|
||||||
|
L.Pushcclosure(countdown, 1)
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
L := lua.Newstate__1()
|
||||||
|
L.Openlibs()
|
||||||
|
defer L.Close()
|
||||||
|
L.Register(c.Str("create_countdown"), createCountdown)
|
||||||
|
|
||||||
|
testcode := c.Str(`
|
||||||
|
local countdown = create_countdown(5)
|
||||||
|
local co = coroutine.create(countdown)
|
||||||
|
while true do
|
||||||
|
local success, value = coroutine.resume(co)
|
||||||
|
if not success then
|
||||||
|
print('Error:', value)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if value == nil then break end
|
||||||
|
print('Lua received:', value)
|
||||||
|
end
|
||||||
|
print('Countdown finished');
|
||||||
|
`)
|
||||||
|
|
||||||
|
if L.Dostring(testcode) != lua.OK {
|
||||||
|
c.Printf(c.Str("Error: %s\n"), L.Tostring(-1))
|
||||||
|
}
|
||||||
|
|
||||||
|
L.Openlibs()
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expected output:
|
||||||
|
resume called with 5
|
||||||
|
Lua received: 5
|
||||||
|
resume called with 4
|
||||||
|
Lua received: 4
|
||||||
|
resume called with 3
|
||||||
|
Lua received: 3
|
||||||
|
resume called with 2
|
||||||
|
Lua received: 2
|
||||||
|
resume called with 1
|
||||||
|
Lua received: 1
|
||||||
|
resume called with 0
|
||||||
|
Countdown finished
|
||||||
|
*/
|
||||||
64
c/lua/_demo/custom-panic/panic.go
Normal file
64
c/lua/_demo/custom-panic/panic.go
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/lua"
|
||||||
|
)
|
||||||
|
|
||||||
|
func triggerError(L *lua.State) c.Int {
|
||||||
|
L.Pushstring(c.Str("This is an error triggered"))
|
||||||
|
return L.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func triggerFormatError(L *lua.State) c.Int {
|
||||||
|
return L.LError(c.Str("This is an error code:(%d)"), 42)
|
||||||
|
}
|
||||||
|
|
||||||
|
func customPanic(L *lua.State) c.Int {
|
||||||
|
msg := L.Tostring(-1)
|
||||||
|
c.Printf(c.Str("Pani'c: %s\n"), msg)
|
||||||
|
os.Exit(1)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
L := lua.Newstate__1()
|
||||||
|
defer L.Close()
|
||||||
|
|
||||||
|
L.Openlibs()
|
||||||
|
|
||||||
|
L.Atpanic(customPanic)
|
||||||
|
|
||||||
|
L.Register(c.Str("trigger_error"), triggerError)
|
||||||
|
L.Register(c.Str("trigger_format_error"), triggerFormatError)
|
||||||
|
|
||||||
|
c.Printf(c.Str("1. error (protected):\n"))
|
||||||
|
L.Getglobal(c.Str("trigger_error"))
|
||||||
|
if L.Pcall(0, 0, 0) != lua.OK {
|
||||||
|
c.Printf(c.Str("Error: %s\n"), L.Tostring(-1))
|
||||||
|
L.Pop(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Printf(c.Str("2. format_error (protected):\n"))
|
||||||
|
L.Getglobal(c.Str("trigger_format_error"))
|
||||||
|
if L.Pcall(0, 0, 0) != lua.OK {
|
||||||
|
c.Printf(c.Str("Error: %s\n"), L.Tostring(-1))
|
||||||
|
L.Pop(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Printf(c.Str("3. Unprotected call (panic):\n"))
|
||||||
|
L.Getglobal(c.Str("trigger_error"))
|
||||||
|
// This will trigger unprotected panic and catch by customPanic
|
||||||
|
L.Call(0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expected output:
|
||||||
|
1. error (protected):
|
||||||
|
Error: This is an error triggered
|
||||||
|
2. format_error (protected):
|
||||||
|
Error: This is an error code:(42)
|
||||||
|
3. Unprotected call (panic):
|
||||||
|
Panic: This is an error triggered
|
||||||
|
*/
|
||||||
48
c/lua/_demo/debug/debug.go
Normal file
48
c/lua/_demo/debug/debug.go
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/lua"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Hook(L *lua.State, ar *lua.Debug) {
|
||||||
|
L.Getinfo(c.Str("nSl"), ar)
|
||||||
|
c.Printf(c.Str("Hook called:"))
|
||||||
|
if name := ar.Name; name != nil {
|
||||||
|
c.Printf(c.Str("name: %s,"), name)
|
||||||
|
}
|
||||||
|
if what := ar.What; what != nil {
|
||||||
|
c.Printf(c.Str("what: %s,"), what)
|
||||||
|
}
|
||||||
|
c.Printf(c.Str("source: %s,"), c.Pointer(unsafe.SliceData(ar.ShortSrc[:])))
|
||||||
|
c.Printf(c.Str("line: %d\n"), ar.Currentline)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
L := lua.Newstate__1()
|
||||||
|
defer L.Close()
|
||||||
|
L.Openlibs()
|
||||||
|
|
||||||
|
L.Sethook(Hook, lua.MASKLINE, 0)
|
||||||
|
|
||||||
|
code :=
|
||||||
|
`function hello(name)
|
||||||
|
print('Hello, ' .. name .. '!')
|
||||||
|
end
|
||||||
|
hello('llgo')`
|
||||||
|
if res := L.Dostring(c.Str(code)); res != lua.OK {
|
||||||
|
c.Printf(c.Str("error: %s\n"), L.Tostring(-1))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expected output:
|
||||||
|
Hook called:what: main,source: [string "function hello(name) ..."],line: 3
|
||||||
|
Hook called:what: main,source: [string "function hello(name) ..."],line: 1
|
||||||
|
Hook called:what: main,source: [string "function hello(name) ..."],line: 4
|
||||||
|
Hook called:name: hello,what: Lua,source: [string "function hello(name) ..."],line: 2
|
||||||
|
Hello, llgo!
|
||||||
|
Hook called:name: hello,what: Lua,source: [string "function hello(name) ..."],line: 3
|
||||||
|
*/
|
||||||
68
c/lua/_demo/dump/load/load.go
Normal file
68
c/lua/_demo/dump/load/load.go
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/lua"
|
||||||
|
)
|
||||||
|
|
||||||
|
func reader(L *lua.State, data c.Pointer, size *c.Ulong) *c.Char {
|
||||||
|
file := (*os.File)(data)
|
||||||
|
|
||||||
|
fileInfo, err := file.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
fileSize := fileInfo.Size()
|
||||||
|
|
||||||
|
buffer := make([]byte, fileSize)
|
||||||
|
bytesRead, err := file.Read(buffer)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
*size = c.Ulong(bytesRead)
|
||||||
|
|
||||||
|
if bytesRead > 0 {
|
||||||
|
return (*c.Char)(unsafe.Pointer(unsafe.SliceData(buffer)))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
L := lua.Newstate__1()
|
||||||
|
defer L.Close()
|
||||||
|
L.Openlibs()
|
||||||
|
|
||||||
|
file, err := os.Open("../llgofunc.luac")
|
||||||
|
if err != nil {
|
||||||
|
c.Printf(c.Str("Failed to open file for reading\n"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
if L.Load(reader, c.Pointer(file), c.Str("greet"), nil) != lua.OK {
|
||||||
|
c.Printf(c.Str("Failed to dump Lua function\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Printf(c.Str("Stack size before call: %d\n"), L.Gettop())
|
||||||
|
c.Printf(c.Str("Top element type after call: %s\n"), L.Typename(L.Type(-1)))
|
||||||
|
|
||||||
|
L.Pushstring(c.Str("World"))
|
||||||
|
if L.Pcall(1, 1, 0) != lua.OK {
|
||||||
|
c.Printf(c.Str("Failed to call function: %s\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if L.Isstring(-1) != 0 {
|
||||||
|
c.Printf(c.Str("Result: %s\n"), L.Tostring(-1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expected output:
|
||||||
|
Stack size before call: 1
|
||||||
|
Top element type after call: function
|
||||||
|
Result: Hello, World!
|
||||||
|
*/
|
||||||
56
c/lua/_demo/dump/save/save.go
Normal file
56
c/lua/_demo/dump/save/save.go
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/lua"
|
||||||
|
)
|
||||||
|
|
||||||
|
func writer(L *lua.State, p c.Pointer, sz c.Ulong, ud c.Pointer) c.Int {
|
||||||
|
file := (*os.File)(ud)
|
||||||
|
data := unsafe.Slice((*byte)(p), sz)
|
||||||
|
|
||||||
|
n, err := file.Write(data)
|
||||||
|
if err != nil || n != int(sz) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return lua.OK
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
L := lua.Newstate__1()
|
||||||
|
defer L.Close()
|
||||||
|
L.Openlibs()
|
||||||
|
|
||||||
|
if res := L.Loadstring(c.Str(`
|
||||||
|
function greet(name)
|
||||||
|
return 'Hello, ' .. name .. '!'
|
||||||
|
end
|
||||||
|
return greet
|
||||||
|
`)); res != lua.OK {
|
||||||
|
c.Printf(c.Str("error: %s\n"), L.Tostring(-1))
|
||||||
|
}
|
||||||
|
|
||||||
|
if res := L.Pcall(0, 1, 0); res != lua.OK {
|
||||||
|
c.Printf(c.Str("error: %s\n"), L.Tostring(-1))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !L.Isfunction(-1) {
|
||||||
|
c.Printf(c.Str("Expected a function, but got %s"), L.Typename(L.Type(-1)))
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Create("../llgofunc.luac")
|
||||||
|
if err != nil {
|
||||||
|
c.Printf(c.Str("Failed to open file for writing\n"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
if L.Dump(writer, c.Pointer(file), 0) != lua.OK {
|
||||||
|
c.Printf(c.Str("Failed to dump Lua function\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
L := lua.Newstate()
|
L := lua.Newstate__1()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
if res := L.Loadstring(c.Str("function doubleNumber(x) ! return x * 2 end")); res != lua.OK {
|
if res := L.Loadstring(c.Str("function doubleNumber(x) ! return x * 2 end")); res != lua.OK {
|
||||||
|
|||||||
42
c/lua/_demo/extraspace/extraspace.go
Normal file
42
c/lua/_demo/extraspace/extraspace.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/lua"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetData(L *lua.State) c.Int {
|
||||||
|
extra := (*int)(L.Getextraspace())
|
||||||
|
L.Pushfstring(c.Str("Stored integer is: %d"), *extra)
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
L := lua.Newstate__1()
|
||||||
|
defer L.Close()
|
||||||
|
|
||||||
|
L.Openlibs()
|
||||||
|
|
||||||
|
extra := (*int)(L.Getextraspace())
|
||||||
|
*extra = 42
|
||||||
|
|
||||||
|
difference := uintptr(unsafe.Pointer(L)) - uintptr(L.Getextraspace())
|
||||||
|
if difference == unsafe.Sizeof(uintptr(0)) {
|
||||||
|
c.Printf(c.Str("Extra space is pointer size\n"), unsafe.Sizeof(uintptr(0)))
|
||||||
|
}
|
||||||
|
|
||||||
|
L.Pushcfunction(GetData)
|
||||||
|
L.Setglobal(c.Str("GetData"))
|
||||||
|
|
||||||
|
if L.Dostring(c.Str("print(GetData())")) != lua.OK {
|
||||||
|
c.Printf(c.Str("Error: %s\n"), L.Tostring(-1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expected output:
|
||||||
|
Extra space is pointer size
|
||||||
|
Stored integer is: 42
|
||||||
|
*/
|
||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
L := lua.Newstate()
|
L := lua.Newstate__1()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
|
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
L := lua.Newstate()
|
L := lua.Newstate__1()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
|
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
L := lua.Newstate()
|
L := lua.Newstate__1()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
|
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
L := lua.Newstate()
|
L := lua.Newstate__1()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
if res := L.Dostring(c.Str("print('hello world')")); res != lua.OK {
|
if res := L.Dostring(c.Str("print('hello world')")); res != lua.OK {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
L := lua.Newstate()
|
L := lua.Newstate__1()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
|
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ func printStack(L *lua.State, message string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
L := lua.Newstate()
|
L := lua.Newstate__1()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
|
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ func printStack(L *lua.State, stateName *c.Char) {
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Create a new Lua state and open libraries
|
// Create a new Lua state and open libraries
|
||||||
L := lua.Newstate()
|
L := lua.Newstate__1()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ func main() {
|
|||||||
printStack(L, c.Str("L1"))
|
printStack(L, c.Str("L1"))
|
||||||
|
|
||||||
// Create a second Lua state
|
// Create a second Lua state
|
||||||
L1 := lua.Newstate()
|
L1 := lua.Newstate__1()
|
||||||
defer L1.Close()
|
defer L1.Close()
|
||||||
|
|
||||||
// Move two elements to the new state
|
// Move two elements to the new state
|
||||||
|
|||||||
36
c/lua/_demo/state-alloc/alloc.go
Normal file
36
c/lua/_demo/state-alloc/alloc.go
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/lua"
|
||||||
|
)
|
||||||
|
|
||||||
|
func alloc(ud c.Pointer, ptr c.Pointer, osize c.Ulong, nsize c.Ulong) c.Pointer {
|
||||||
|
if nsize == 0 {
|
||||||
|
c.Free(ptr)
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
return c.Realloc(ptr, uintptr(nsize))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
L := lua.Newstate__0(alloc, nil)
|
||||||
|
defer L.Close()
|
||||||
|
L.Openlibs()
|
||||||
|
if res := L.Dostring(c.Str("print('new state success')")); res != lua.OK {
|
||||||
|
println("newstate error")
|
||||||
|
}
|
||||||
|
|
||||||
|
allocf := L.Getallocf(nil)
|
||||||
|
L.Setallocf(allocf, nil)
|
||||||
|
|
||||||
|
if res := L.Dostring(c.Str("print('set newstate success')")); res != lua.OK {
|
||||||
|
println("set newstate error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expected output:
|
||||||
|
new state success
|
||||||
|
set newstate success
|
||||||
|
*/
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
"github.com/goplus/llgo/c"
|
||||||
"github.com/goplus/llgo/c/lua"
|
"github.com/goplus/llgo/c/lua"
|
||||||
)
|
)
|
||||||
@@ -8,53 +10,91 @@ import (
|
|||||||
func printTable(L *lua.State) {
|
func printTable(L *lua.State) {
|
||||||
L.Pushnil()
|
L.Pushnil()
|
||||||
for L.Next(-2) != 0 {
|
for L.Next(-2) != 0 {
|
||||||
key := L.Tostring(-2)
|
|
||||||
value := L.Tostring(-1)
|
value := L.Tostring(-1)
|
||||||
c.Printf(c.Str("%s - %s\n"), key, value)
|
switch L.Type(-2) {
|
||||||
|
case lua.STRING:
|
||||||
|
key := L.Tostring(-2)
|
||||||
|
c.Printf(c.Str("%s - %s\n"), key, value)
|
||||||
|
case lua.NUMBER:
|
||||||
|
key := L.Tonumber(-2)
|
||||||
|
c.Printf(c.Str("[%.0f] - %s\n"), key, value)
|
||||||
|
case lua.LIGHTUSERDATA:
|
||||||
|
c.Printf(c.Str("[pointer] - %s\n"), value)
|
||||||
|
default:
|
||||||
|
c.Printf(c.Str("unknown key type %s %d\n"), L.Typename(-2), L.Type(-2))
|
||||||
|
}
|
||||||
L.Pop(1)
|
L.Pop(1)
|
||||||
}
|
}
|
||||||
L.Pop(1)
|
L.Pop(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
L := lua.Newstate()
|
L := lua.Newstate__1()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
|
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
|
|
||||||
L.Newtable()
|
L.Newtable()
|
||||||
|
|
||||||
|
// set table name:John
|
||||||
L.Pushstring(c.Str("name"))
|
L.Pushstring(c.Str("name"))
|
||||||
L.Pushstring(c.Str("John"))
|
L.Pushstring(c.Str("John"))
|
||||||
L.Settable(-3)
|
L.Settable(-3)
|
||||||
|
|
||||||
|
// set table age:30
|
||||||
L.Pushstring(c.Str("age"))
|
L.Pushstring(c.Str("age"))
|
||||||
L.Pushnumber(30)
|
L.Pushnumber(30)
|
||||||
L.Settable(-3)
|
L.Settable(-3)
|
||||||
|
|
||||||
|
// set table field fullname:John Doe
|
||||||
L.Pushstring(c.Str("John Doe"))
|
L.Pushstring(c.Str("John Doe"))
|
||||||
L.Setfield(-2, c.Str("fullname"))
|
L.Setfield(-2, c.Str("fullname"))
|
||||||
|
|
||||||
|
// set index field
|
||||||
|
L.Pushinteger(123)
|
||||||
|
L.Seti(-2, c.Int(1))
|
||||||
|
|
||||||
|
// set pointer key field
|
||||||
|
pointerKey := c.AllocaCStr("pointer key")
|
||||||
|
L.Pushstring(c.Str("pointer value"))
|
||||||
|
L.Rawsetp(-2, unsafe.Pointer(pointerKey))
|
||||||
|
|
||||||
|
// get field by Getfield
|
||||||
L.Getfield(-1, c.Str("name"))
|
L.Getfield(-1, c.Str("name"))
|
||||||
c.Printf(c.Str("%s\n"), L.Tostring(-1))
|
c.Printf(c.Str("name: %s\n"), L.Tostring(-1))
|
||||||
L.Pop(1)
|
L.Pop(1)
|
||||||
|
|
||||||
|
// get field by Rawget
|
||||||
|
L.Pushstring(c.Str("fullname"))
|
||||||
|
L.Rawget(-2)
|
||||||
|
c.Printf(c.Str("fullname: %s\n"), L.Tostring(-1))
|
||||||
|
L.Pop(1)
|
||||||
|
|
||||||
|
// get field by Gettable
|
||||||
L.Pushstring(c.Str("age"))
|
L.Pushstring(c.Str("age"))
|
||||||
L.Gettable(-2)
|
L.Gettable(-2)
|
||||||
age := int(L.Tonumber(-1))
|
age := int(L.Tonumber(-1))
|
||||||
c.Printf(c.Str("Age: %d\n"), age)
|
c.Printf(c.Str("Age: %d\n"), age)
|
||||||
L.Pop(1)
|
L.Pop(1)
|
||||||
|
|
||||||
|
// get index field
|
||||||
|
L.Geti(-1, c.Int(1))
|
||||||
|
c.Printf(c.Str("Index[%d] value: %d\n"), 1, L.Tointeger(-1))
|
||||||
|
L.Pop(1)
|
||||||
|
|
||||||
c.Printf(c.Str("All entries in the table:\n"))
|
c.Printf(c.Str("All entries in the table:\n"))
|
||||||
printTable(L)
|
printTable(L)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expected output:
|
/* Expected output:
|
||||||
John
|
name: John
|
||||||
|
fullname: John Doe
|
||||||
Age: 30
|
Age: 30
|
||||||
|
Index[1] value: 123
|
||||||
All entries in the table:
|
All entries in the table:
|
||||||
age - 30.0
|
[1] - 123
|
||||||
fullname - John Doe
|
|
||||||
name - John
|
name - John
|
||||||
|
[pointer] - pointer value
|
||||||
|
fullname - John Doe
|
||||||
|
age - 30.0
|
||||||
*/
|
*/
|
||||||
|
|||||||
44
c/lua/_demo/thread/thread.go
Normal file
44
c/lua/_demo/thread/thread.go
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/lua"
|
||||||
|
)
|
||||||
|
|
||||||
|
func pushThread(state *lua.State, name string) {
|
||||||
|
isMain := state.Pushthread()
|
||||||
|
if isMain != 0 {
|
||||||
|
c.Printf(c.Str("%s Thread is main\n"), c.AllocaCStr(name))
|
||||||
|
} else {
|
||||||
|
c.Printf(c.Str("%s Thread is not main\n"), c.AllocaCStr(name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
L := lua.Newstate__1()
|
||||||
|
defer L.Close()
|
||||||
|
|
||||||
|
L.Openlibs()
|
||||||
|
pushThread(L, "main")
|
||||||
|
L.Pop(1)
|
||||||
|
newThread := L.Newthread()
|
||||||
|
pushThread(newThread, "newthread")
|
||||||
|
|
||||||
|
state := newThread.Tothread(-1)
|
||||||
|
if newThread == state {
|
||||||
|
c.Printf(c.Str("Successfully retrieved thread from stack\n"))
|
||||||
|
}
|
||||||
|
status := state.Status()
|
||||||
|
c.Printf(c.Str("New thread status: %d"), status)
|
||||||
|
|
||||||
|
if L.Closethread(newThread) != lua.OK {
|
||||||
|
println("Failed to close thread status %d", state.Status())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expected output:
|
||||||
|
main Thread is main
|
||||||
|
newthread Thread is not main
|
||||||
|
Successfully retrieved thread from stack
|
||||||
|
New thread status: 0
|
||||||
|
*/
|
||||||
43
c/lua/_demo/userdata/userdata.go
Normal file
43
c/lua/_demo/userdata/userdata.go
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/lua"
|
||||||
|
)
|
||||||
|
|
||||||
|
type lightdata struct {
|
||||||
|
value int
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
L := lua.Newstate__1()
|
||||||
|
defer L.Close()
|
||||||
|
L.Openlibs()
|
||||||
|
|
||||||
|
data := L.Newuserdata(unsafe.Sizeof(0))
|
||||||
|
*((*int)(data)) = 42
|
||||||
|
L.Setglobal(c.Str("data"))
|
||||||
|
|
||||||
|
light := &lightdata{value: 24}
|
||||||
|
L.Pushlightuserdata(unsafe.Pointer(light))
|
||||||
|
L.Setglobal(c.Str("lightdata"))
|
||||||
|
|
||||||
|
L.Getglobal(c.Str("data"))
|
||||||
|
if L.Isuserdata(-1) != 0 {
|
||||||
|
data := L.Touserdata(-1)
|
||||||
|
c.Printf(c.Str("userdata %d\n"), *(*int)(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
L.Getglobal(c.Str("lightdata"))
|
||||||
|
if L.Islightuserdata(-1) {
|
||||||
|
light := (*lightdata)(L.Touserdata(-1))
|
||||||
|
c.Printf(c.Str("lightdata %d\n"), light.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expected output:
|
||||||
|
userdata 42
|
||||||
|
lightdata 24
|
||||||
|
*/
|
||||||
@@ -14,6 +14,15 @@ import (
|
|||||||
|
|
||||||
// /* key, in the registry, for table of preloaded loaders */
|
// /* key, in the registry, for table of preloaded loaders */
|
||||||
|
|
||||||
|
// llgo:link (*State).Checkinteger C.luaL_checkinteger
|
||||||
|
func (L *State) Checkinteger(arg c.Int) Integer { return 0 }
|
||||||
|
|
||||||
|
// llgo:link (*State).Checknumber C.luaL_checknumber
|
||||||
|
func (L *State) Checknumber(arg c.Int) Number { return 0 }
|
||||||
|
|
||||||
|
// llgo:link (*State).LError C.luaL_error
|
||||||
|
func (L *State) LError(format *c.Char, __llgo_va_list ...any) c.Int { return 0 }
|
||||||
|
|
||||||
// /* predefined references */
|
// /* predefined references */
|
||||||
|
|
||||||
// llgo:link (*State).Loadfilex C.luaL_loadfilex
|
// llgo:link (*State).Loadfilex C.luaL_loadfilex
|
||||||
@@ -24,8 +33,8 @@ func (L *State) Loadfile(filename *c.Char) c.Int { return L.Loadfilex(filename,
|
|||||||
// llgo:link (*State).Loadstring C.luaL_loadstring
|
// llgo:link (*State).Loadstring C.luaL_loadstring
|
||||||
func (L *State) Loadstring(s *c.Char) c.Int { return 0 }
|
func (L *State) Loadstring(s *c.Char) c.Int { return 0 }
|
||||||
|
|
||||||
//go:linkname Newstate C.luaL_newstate
|
//go:linkname Newstate__1 C.luaL_newstate
|
||||||
func Newstate() *State
|
func Newstate__1() *State
|
||||||
|
|
||||||
// /*
|
// /*
|
||||||
// ** ===============================================================
|
// ** ===============================================================
|
||||||
|
|||||||
491
c/lua/lua.go
491
c/lua/lua.go
@@ -10,20 +10,28 @@ const (
|
|||||||
LLGoPackage = "link: $(pkg-config --libs lua); -llua -lm"
|
LLGoPackage = "link: $(pkg-config --libs lua); -llua -lm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// /* mark for precompiled code ('<esc>Lua') */
|
/* mark for precompiled code ('<esc>Lua') */
|
||||||
|
|
||||||
// /* option for multiple returns in 'lua_pcall' and 'lua_call' */
|
/* option for multiple returns in 'lua_pcall' and 'lua_call' */
|
||||||
const (
|
const (
|
||||||
MULTRET = -1
|
MULTRET = -1
|
||||||
)
|
)
|
||||||
|
|
||||||
// /*
|
/*
|
||||||
// ** Pseudo-indices
|
* Pseudo-indices
|
||||||
// ** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty
|
* (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty
|
||||||
// ** space after that to help overflow detection)
|
* space after that to help overflow detection)
|
||||||
// */
|
*/
|
||||||
|
|
||||||
// /* thread status */
|
const (
|
||||||
|
REGISTRYINDEX = -MAXSTACK - 1000
|
||||||
|
)
|
||||||
|
|
||||||
|
func Upvalueindex(i c.Int) c.Int {
|
||||||
|
return c.Int(REGISTRYINDEX) - i
|
||||||
|
}
|
||||||
|
|
||||||
|
/* thread status */
|
||||||
const (
|
const (
|
||||||
OK = 0
|
OK = 0
|
||||||
YIELD = 1
|
YIELD = 1
|
||||||
@@ -37,9 +45,9 @@ type State struct {
|
|||||||
Unused [8]byte
|
Unused [8]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// /*
|
/*
|
||||||
// ** basic types
|
* basic types
|
||||||
// */
|
*/
|
||||||
const (
|
const (
|
||||||
NONE c.Int = -1
|
NONE c.Int = -1
|
||||||
NIL c.Int = 0
|
NIL c.Int = 0
|
||||||
@@ -51,113 +59,112 @@ const (
|
|||||||
FUNCTION c.Int = 6
|
FUNCTION c.Int = 6
|
||||||
USERDATA c.Int = 7
|
USERDATA c.Int = 7
|
||||||
THREAD c.Int = 8
|
THREAD c.Int = 8
|
||||||
UMTYPES c.Int = 9
|
NUMTYPES c.Int = 9
|
||||||
)
|
)
|
||||||
|
|
||||||
// /* minimum Lua stack available to a C function */
|
/* minimum Lua stack available to a C function */
|
||||||
const (
|
const (
|
||||||
MINSTACK = 20
|
MINSTACK = 20
|
||||||
)
|
)
|
||||||
|
|
||||||
// /* predefined values in the registry */
|
/* predefined values in the registry */
|
||||||
const (
|
const (
|
||||||
RIDX_MAINTHREAD = 1
|
RIDX_MAINTHREAD = 1
|
||||||
RIDX_GLOBALS = 2
|
RIDX_GLOBALS = 2
|
||||||
RIDX_LAST = RIDX_GLOBALS
|
RIDX_LAST = RIDX_GLOBALS
|
||||||
)
|
)
|
||||||
|
|
||||||
// /* type of numbers in Lua */
|
/* type of numbers in Lua */
|
||||||
type Number = c.Double
|
type Number = c.Double
|
||||||
|
|
||||||
// /* type for integer functions */
|
/* type for integer functions */
|
||||||
// TODO(zzy):consider dynamic size
|
|
||||||
|
|
||||||
type Integer = c.Int
|
type Integer = c.Int
|
||||||
|
|
||||||
// /* unsigned integer type */
|
/* unsigned integer type */
|
||||||
type Unsigned = c.Uint
|
type Unsigned = c.Uint
|
||||||
|
|
||||||
// /* type for continuation-function contexts */
|
/* type for continuation-function contexts */
|
||||||
type KContext = c.Pointer
|
type KContext = c.Pointer
|
||||||
|
|
||||||
// /*
|
/*
|
||||||
// ** Type for C functions registered with Lua
|
* Type for C functions registered with Lua
|
||||||
// */
|
*/
|
||||||
|
|
||||||
// llgo:type C
|
// llgo:type C
|
||||||
type CFunction func(L *State) c.Int
|
type CFunction func(L *State) c.Int
|
||||||
|
|
||||||
// /*
|
/*
|
||||||
// ** Type for continuation functions
|
* Type for continuation functions
|
||||||
// */
|
*/
|
||||||
|
|
||||||
// TODO(zzy): KFunction does not currently support
|
// llgo:type C
|
||||||
type KFunction func(L *State, status c.Int, ctx KContext) c.Int
|
type KFunction func(L *State, status c.Int, ctx KContext) c.Int
|
||||||
|
|
||||||
// /*
|
/*
|
||||||
// ** Type for functions that read/write blocks when loading/dumping Lua chunks
|
* Type for functions that read/write blocks when loading/dumping Lua chunks
|
||||||
// */
|
*/
|
||||||
|
|
||||||
// typedef const char * (*lua_Reader) (State *L, void *ud, size_t *sz);
|
// llgo:type C
|
||||||
// typedef int (*lua_Writer) (State *L, const void *p, size_t sz, void *ud);
|
type Reader func(L *State, ud c.Pointer, sz *c.Ulong) *c.Char
|
||||||
|
|
||||||
// /*
|
// llgo:type C
|
||||||
// ** Type for memory-allocation functions
|
type Writer func(L *State, p c.Pointer, sz c.Ulong, ud c.Pointer) c.Int
|
||||||
// */
|
|
||||||
|
|
||||||
// typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
|
/*
|
||||||
|
* Type for memory-allocation functions
|
||||||
|
*/
|
||||||
|
|
||||||
// /*
|
// llgo:type C
|
||||||
// ** Type for warning functions
|
type Alloc func(ud c.Pointer, ptr c.Pointer, osize c.Ulong, nsize c.Ulong) c.Pointer
|
||||||
// */
|
|
||||||
|
|
||||||
// typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont);
|
/*
|
||||||
|
* Type for warning functions
|
||||||
|
*/
|
||||||
|
|
||||||
// /*
|
// llgo:type C
|
||||||
// ** Type used by the debug API to collect debug information
|
type WarnFunction func(ud c.Pointer, msg c.Char, tocont c.Int)
|
||||||
// */
|
|
||||||
|
|
||||||
// typedef struct lua_Debug lua_Debug;
|
/*
|
||||||
|
* Functions to be called by the debugger in specific events
|
||||||
|
*/
|
||||||
|
|
||||||
// /*
|
// llgo:type C
|
||||||
// ** Functions to be called by the debugger in specific events
|
type Hook func(L *State, ar *Debug)
|
||||||
// */
|
|
||||||
|
|
||||||
// typedef void (*lua_Hook) (State *L, lua_Debug *ar);
|
/*
|
||||||
|
* RCS ident string
|
||||||
// /*
|
*/
|
||||||
// ** generic extra include file
|
|
||||||
// */
|
|
||||||
|
|
||||||
// #if defined(LUA_USER_H)
|
|
||||||
// #include LUA_USER_H
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// /*
|
|
||||||
// ** RCS ident string
|
|
||||||
// */
|
|
||||||
|
|
||||||
// extern const char lua_ident[];
|
// extern const char lua_ident[];
|
||||||
|
|
||||||
// /*
|
/*
|
||||||
// ** state manipulation
|
** state manipulation
|
||||||
// */
|
*/
|
||||||
|
|
||||||
// llgo:link (*State).Close C.lua_close
|
// llgo:link (*State).Close C.lua_close
|
||||||
func (L *State) Close() {}
|
func (L *State) Close() {}
|
||||||
|
|
||||||
// State *(lua_newstate) (lua_Alloc f, void *ud);
|
// llgo:link Newstate__0 C.lua_newstate
|
||||||
|
func Newstate__0(f Alloc, ud c.Pointer) *State { return nil }
|
||||||
|
|
||||||
// llgo:link (*State).Newthread C.lua_newthread
|
// llgo:link (*State).Newthread C.lua_newthread
|
||||||
func (L *State) Newthread() *State { return nil }
|
func (L *State) Newthread() *State { return nil }
|
||||||
|
|
||||||
// int (lua_closethread) (State *L, State *from);
|
// llgo:link (*State).Closethread C.lua_closethread
|
||||||
// int (lua_resetthread) (State *L); /* Deprecated! */
|
func (L *State) Closethread(from *State) c.Int { return 0 }
|
||||||
// lua_CFunction (lua_atpanic) (State *L, lua_CFunction panicf);
|
|
||||||
// lua_Number (lua_version) (State *L);
|
|
||||||
|
|
||||||
// /*
|
// llgo:link (*State).Resetthread C.lua_resetthread
|
||||||
// ** basic stack manipulation
|
func (L *State) Resetthread(from *State) c.Int { return 0 }
|
||||||
// */
|
|
||||||
|
// llgo:link (*State).Atpanic C.lua_atpanic
|
||||||
|
func (L *State) Atpanic(panicf CFunction) CFunction { return nil }
|
||||||
|
|
||||||
|
// llgo:link (*State).Version C.lua_version
|
||||||
|
func (L *State) Version() Number { return 0 }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* basic stack manipulation
|
||||||
|
*/
|
||||||
|
|
||||||
// llgo:link (*State).Absindex C.lua_absindex
|
// llgo:link (*State).Absindex C.lua_absindex
|
||||||
func (L *State) Absindex(idx c.Int) c.Int { return 0 }
|
func (L *State) Absindex(idx c.Int) c.Int { return 0 }
|
||||||
@@ -183,9 +190,9 @@ func (L *State) Checkstack(n c.Int) c.Int { return 0 }
|
|||||||
// llgo:link (*State).Xmove C.lua_xmove
|
// llgo:link (*State).Xmove C.lua_xmove
|
||||||
func (L *State) Xmove(to *State, n c.Int) {}
|
func (L *State) Xmove(to *State, n c.Int) {}
|
||||||
|
|
||||||
// /*
|
/*
|
||||||
// ** access functions (stack -> C)
|
* access functions (stack -> C)
|
||||||
// */
|
*/
|
||||||
|
|
||||||
// llgo:link (*State).Isnumber C.lua_isnumber
|
// llgo:link (*State).Isnumber C.lua_isnumber
|
||||||
func (L *State) Isnumber(idx c.Int) c.Int { return 0 }
|
func (L *State) Isnumber(idx c.Int) c.Int { return 0 }
|
||||||
@@ -199,7 +206,8 @@ func (L *State) Iscfunction(idx c.Int) c.Int { return 0 }
|
|||||||
// llgo:link (*State).Isinteger C.lua_isinteger
|
// llgo:link (*State).Isinteger C.lua_isinteger
|
||||||
func (L *State) Isinteger(idx c.Int) c.Int { return 0 }
|
func (L *State) Isinteger(idx c.Int) c.Int { return 0 }
|
||||||
|
|
||||||
// LUA_API int (lua_isuserdata) (State *L, int idx);
|
// llgo:link (*State).Isuserdata C.lua_isuserdata
|
||||||
|
func (L *State) Isuserdata(idx c.Int) c.Int { return 0 }
|
||||||
|
|
||||||
// llgo:link (*State).Type C.lua_type
|
// llgo:link (*State).Type C.lua_type
|
||||||
func (L *State) Type(idx c.Int) c.Int { return 0 }
|
func (L *State) Type(idx c.Int) c.Int { return 0 }
|
||||||
@@ -224,17 +232,23 @@ func (L *State) Tolstring(idx c.Int, len *c.Ulong) *c.Char { return nil }
|
|||||||
// llgo:link (*State).Tocfunction C.lua_tocfunction
|
// llgo:link (*State).Tocfunction C.lua_tocfunction
|
||||||
func (L *State) Tocfunction(idx c.Int) CFunction { return nil }
|
func (L *State) Tocfunction(idx c.Int) CFunction { return nil }
|
||||||
|
|
||||||
// LUA_API void *(lua_touserdata) (State *L, int idx);
|
// llgo:link (*State).Touserdata C.lua_touserdata
|
||||||
// LUA_API State *(lua_tothread) (State *L, int idx);
|
func (L *State) Touserdata(idx c.Int) c.Pointer { return nil }
|
||||||
// LUA_API const void *(lua_topointer) (State *L, int idx);
|
|
||||||
|
|
||||||
// /*
|
// llgo:link (*State).Tothread C.lua_tothread
|
||||||
// ** Comparison and arithmetic functions
|
func (L *State) Tothread(idx c.Int) *State { return nil }
|
||||||
// */
|
|
||||||
|
// llgo:link (*State).Topointer C.lua_topointer
|
||||||
|
func (L *State) Topointer(idx c.Int) c.Pointer { return nil }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Comparison and arithmetic functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* push functions (C -> stack)
|
||||||
|
*/
|
||||||
|
|
||||||
// /*
|
|
||||||
// ** push functions (C -> stack)
|
|
||||||
// */
|
|
||||||
// llgo:link (*State).Pushnil C.lua_pushnil
|
// llgo:link (*State).Pushnil C.lua_pushnil
|
||||||
func (L *State) Pushnil() {}
|
func (L *State) Pushnil() {}
|
||||||
|
|
||||||
@@ -259,12 +273,15 @@ func (L *State) Pushcclosure(fn CFunction, n c.Int) {}
|
|||||||
// llgo:link (*State).Pushboolean C.lua_pushboolean
|
// llgo:link (*State).Pushboolean C.lua_pushboolean
|
||||||
func (L *State) Pushboolean(b c.Int) {}
|
func (L *State) Pushboolean(b c.Int) {}
|
||||||
|
|
||||||
//void (lua_pushlightuserdata) (State *L, void *p);
|
// llgo:link (*State).Pushlightuserdata C.lua_pushlightuserdata
|
||||||
//int (lua_pushthread) (State *L);
|
func (L *State) Pushlightuserdata(p c.Pointer) {}
|
||||||
|
|
||||||
// /*
|
// llgo:link (*State).Pushthread C.lua_pushthread
|
||||||
// ** get functions (Lua -> stack)
|
func (L *State) Pushthread() c.Int { return 0 }
|
||||||
// */
|
|
||||||
|
/*
|
||||||
|
* get functions (Lua -> stack)
|
||||||
|
*/
|
||||||
|
|
||||||
// llgo:link (*State).Getglobal C.lua_getglobal
|
// llgo:link (*State).Getglobal C.lua_getglobal
|
||||||
func (L *State) Getglobal(name *c.Char) c.Int { return 0 }
|
func (L *State) Getglobal(name *c.Char) c.Int { return 0 }
|
||||||
@@ -275,24 +292,33 @@ func (L *State) Gettable(idx c.Int) c.Int { return 0 }
|
|||||||
// llgo:link (*State).Getfield C.lua_getfield
|
// llgo:link (*State).Getfield C.lua_getfield
|
||||||
func (L *State) Getfield(idx c.Int, k *c.Char) c.Int { return 0 }
|
func (L *State) Getfield(idx c.Int, k *c.Char) c.Int { return 0 }
|
||||||
|
|
||||||
// LUA_API int (lua_geti) (State *L, int idx, lua_Integer n);
|
// llgo:link (*State).Geti C.lua_geti
|
||||||
// LUA_API int (lua_rawget) (State *L, int idx);
|
func (L *State) Geti(idx c.Int, n Integer) c.Int { return 0 }
|
||||||
// LUA_API int (lua_rawgeti) (State *L, int idx, lua_Integer n);
|
|
||||||
// LUA_API int (lua_rawgetp) (State *L, int idx, const void *p);
|
// llgo:link (*State).Rawget C.lua_rawget
|
||||||
|
func (L *State) Rawget(idx c.Int) c.Int { return 0 }
|
||||||
|
|
||||||
|
// llgo:link (*State).Rawgeti C.lua_rawgeti
|
||||||
|
func (L *State) Rawgeti(idx c.Int, n Integer) c.Int { return 0 }
|
||||||
|
|
||||||
|
// llgo:link (*State).Rawgetp C.lua_rawgetp
|
||||||
|
func (L *State) Rawgetp(idx c.Int, p c.Pointer) c.Int { return 0 }
|
||||||
|
|
||||||
// llgo:link (*State).Createtable C.lua_createtable
|
// llgo:link (*State).Createtable C.lua_createtable
|
||||||
func (L *State) Createtable(narr c.Int, nrec c.Int) {}
|
func (L *State) Createtable(narr c.Int, nrec c.Int) {}
|
||||||
|
|
||||||
// LUA_API void *(lua_newuserdatauv) (State *L, size_t sz, int nuvalue);
|
// llgo:link (*State).Newuserdatauv C.lua_newuserdatauv
|
||||||
|
func (L *State) Newuserdatauv(sz uintptr, nuvalue c.Int) c.Pointer { return nil }
|
||||||
|
|
||||||
// llgo:link (*State).Getmetatable C.lua_getmetatable
|
// llgo:link (*State).Getmetatable C.lua_getmetatable
|
||||||
func (L *State) Getmetatable(objindex c.Int) c.Int { return 0 }
|
func (L *State) Getmetatable(objindex c.Int) c.Int { return 0 }
|
||||||
|
|
||||||
// LUA_API int (lua_getiuservalue) (State *L, int idx, int n);
|
// llgo:link (*State).Getiuservalue C.lua_getiuservalue
|
||||||
|
func (L *State) Getiuservalue(idx c.Int, n c.Int) c.Int { return 0 }
|
||||||
|
|
||||||
// /*
|
/*
|
||||||
// ** set functions (stack -> Lua)
|
* set functions (stack -> Lua)
|
||||||
// */
|
*/
|
||||||
|
|
||||||
// llgo:link (*State).Setglobal C.lua_setglobal
|
// llgo:link (*State).Setglobal C.lua_setglobal
|
||||||
func (L *State) Setglobal(name *c.Char) {}
|
func (L *State) Setglobal(name *c.Char) {}
|
||||||
@@ -303,19 +329,27 @@ func (L *State) Settable(idx c.Int) {}
|
|||||||
// llgo:link (*State).Setfield C.lua_setfield
|
// llgo:link (*State).Setfield C.lua_setfield
|
||||||
func (L *State) Setfield(idx c.Int, k *c.Char) {}
|
func (L *State) Setfield(idx c.Int, k *c.Char) {}
|
||||||
|
|
||||||
//void (lua_seti) (State *L, int idx, lua_Integer n);
|
// llgo:link (*State).Seti C.lua_seti
|
||||||
//void (lua_rawset) (State *L, int idx);
|
func (L *State) Seti(idx c.Int, n Integer) {}
|
||||||
//void (lua_rawseti) (State *L, int idx, lua_Integer n);
|
|
||||||
//void (lua_rawsetp) (State *L, int idx, const void *p);
|
// llgo:link (*State).Rawset C.lua_rawset
|
||||||
|
func (L *State) Rawset(idx c.Int) {}
|
||||||
|
|
||||||
|
// llgo:link (*State).Rawseti C.lua_rawseti
|
||||||
|
func (L *State) Rawseti(idx c.Int, n Integer) {}
|
||||||
|
|
||||||
|
// llgo:link (*State).Rawsetp C.lua_rawsetp
|
||||||
|
func (L *State) Rawsetp(idx c.Int, p c.Pointer) {}
|
||||||
|
|
||||||
// llgo:link (*State).Setmetatable C.lua_setmetatable
|
// llgo:link (*State).Setmetatable C.lua_setmetatable
|
||||||
func (L *State) Setmetatable(objindex c.Int) c.Int { return 0 }
|
func (L *State) Setmetatable(objindex c.Int) c.Int { return 0 }
|
||||||
|
|
||||||
//int (lua_setiuservalue) (State *L, int idx, int n);
|
// llgo:link (*State).Setiuservalue C.lua_setiuservalue
|
||||||
|
func (L *State) Setiuservalue(idx c.Int, n c.Int) c.Int { return 0 }
|
||||||
|
|
||||||
// /*
|
/*
|
||||||
// ** 'load' and 'call' functions (load and run Lua code)
|
* 'load' and 'call' functions (load and run Lua code)
|
||||||
// */
|
*/
|
||||||
|
|
||||||
// llgo:link (*State).Callk C.lua_callk
|
// llgo:link (*State).Callk C.lua_callk
|
||||||
func (L *State) Callk(nargs c.Int, nresults c.Int, ctx KContext, k KFunction) c.Int {
|
func (L *State) Callk(nargs c.Int, nresults c.Int, ctx KContext, k KFunction) c.Int {
|
||||||
@@ -335,13 +369,15 @@ func (L *State) Pcall(nargs c.Int, nresults c.Int, errfunc c.Int) c.Int {
|
|||||||
return L.Pcallk(nargs, nresults, errfunc, nil, nil)
|
return L.Pcallk(nargs, nresults, errfunc, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// int (lua_load) (State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode);
|
// llgo:link (*State).Load C.lua_load
|
||||||
|
func (L *State) Load(reader Reader, dt c.Pointer, chunkname *c.Char, mode *c.Char) c.Int { return 0 }
|
||||||
|
|
||||||
// int (lua_dump) (State *L, lua_Writer writer, void *data, int strip);
|
// llgo:link (*State).Dump C.lua_dump
|
||||||
|
func (L *State) Dump(writer Writer, data c.Pointer, strip c.Int) c.Int { return 0 }
|
||||||
|
|
||||||
// /*
|
/*
|
||||||
// ** coroutine functions
|
* coroutine functions
|
||||||
// */
|
*/
|
||||||
|
|
||||||
// llgo:link (*State).Resume C.lua_resume
|
// llgo:link (*State).Resume C.lua_resume
|
||||||
func (L *State) Resume(from *State, narg c.Int, nres *c.Int) c.Int { return 0 }
|
func (L *State) Resume(from *State, narg c.Int, nres *c.Int) c.Int { return 0 }
|
||||||
@@ -356,16 +392,19 @@ func (L *State) Isyieldable() c.Int { return 0 }
|
|||||||
func (L *State) Yieldk(nresults c.Int, ctx KContext, k KFunction) c.Int { return 0 }
|
func (L *State) Yieldk(nresults c.Int, ctx KContext, k KFunction) c.Int { return 0 }
|
||||||
func (L *State) Yield(nresults c.Int) c.Int { return L.Yieldk(nresults, nil, nil) }
|
func (L *State) Yield(nresults c.Int) c.Int { return L.Yieldk(nresults, nil, nil) }
|
||||||
|
|
||||||
// /*
|
/*
|
||||||
// ** Warning-related functions
|
* Warning-related functions
|
||||||
// */
|
*/
|
||||||
|
|
||||||
//void (lua_setwarnf) (State *L, lua_WarnFunction f, void *ud);
|
// llgo:link (*State).Setwarnf C.lua_setwarnf
|
||||||
//void (lua_warning) (State *L, const char *msg, int tocont);
|
func (L *State) Setwarnf(f WarnFunction, ud c.Pointer) {}
|
||||||
|
|
||||||
// /*
|
// llgo:link (*State).Warning C.lua_warning
|
||||||
// ** garbage-collection function and options
|
func (L *State) Warning(msg *c.Char, tocont c.Int) {}
|
||||||
// */
|
|
||||||
|
/*
|
||||||
|
* garbage-collection function and options
|
||||||
|
*/
|
||||||
|
|
||||||
const (
|
const (
|
||||||
GCSTOP = 0
|
GCSTOP = 0
|
||||||
@@ -381,42 +420,59 @@ const (
|
|||||||
GCINC = 11
|
GCINC = 11
|
||||||
)
|
)
|
||||||
|
|
||||||
// LUA_API int (lua_gc) (State *L, int what, ...);
|
// llgo:link (*State).Gc C.lua_gc
|
||||||
|
func (L *State) Gc(what c.Int, __llgo_va_list ...any) c.Int { return 0 }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* miscellaneous functions
|
||||||
|
*/
|
||||||
|
|
||||||
// /*
|
|
||||||
// ** miscellaneous functions
|
|
||||||
// */
|
|
||||||
// llgo:link (*State).Next C.lua_next
|
// llgo:link (*State).Next C.lua_next
|
||||||
func (L *State) Next(idx c.Int) c.Int { return 0 }
|
func (L *State) Next(idx c.Int) c.Int { return 0 }
|
||||||
|
|
||||||
// LUA_API int (lua_error) (State *L);
|
// llgo:link (*State).Error C.lua_error
|
||||||
|
func (L *State) Error() c.Int { return 0 }
|
||||||
|
|
||||||
// LUA_API void (lua_concat) (State *L, int n);
|
// llgo:link (*State).Concat C.lua_concat
|
||||||
// LUA_API void (lua_len) (State *L, int idx);
|
func (L *State) Concat(n c.Int) {}
|
||||||
|
|
||||||
// LUA_API size_t (lua_stringtonumber) (State *L, const char *s);
|
// llgo:link (*State).Len C.lua_len
|
||||||
|
func (L *State) Len(idx c.Int) {}
|
||||||
|
|
||||||
// LUA_API lua_Alloc (lua_getallocf) (State *L, void **ud);
|
// llgo:link (*State).Stringtonumber C.lua_stringtonumber
|
||||||
// LUA_API void (lua_setallocf) (State *L, lua_Alloc f, void *ud);
|
func (L *State) Stringtonumber(s *c.Char) c.Ulong { return 0 }
|
||||||
|
|
||||||
// LUA_API void (lua_toclose) (State *L, int idx);
|
// llgo:link (*State).Getallocf C.lua_getallocf
|
||||||
// LUA_API void (lua_closeslot) (State *L, int idx);
|
func (L *State) Getallocf(ud *c.Pointer) Alloc { return nil }
|
||||||
|
|
||||||
// /*
|
// llgo:link (*State).Setallocf C.lua_setallocf
|
||||||
// ** {==============================================================
|
func (L *State) Setallocf(f Alloc, ud c.Pointer) Alloc { return nil }
|
||||||
// ** some useful macros
|
|
||||||
// ** ===============================================================
|
|
||||||
// */
|
|
||||||
|
|
||||||
// #define lua_getextraspace(L) ((void *)((char *)(L) - LUA_EXTRASPACE))
|
// llgo:link (*State).Toclose C.lua_toclose
|
||||||
|
func (L *State) Toclose(idx c.Int) {}
|
||||||
|
|
||||||
|
// llgo:link (*State).Closeslot C.lua_closeslot
|
||||||
|
func (L *State) Closeslot(idx c.Int) {}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** {==============================================================
|
||||||
|
** some useful macros
|
||||||
|
** ===============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
func (L *State) Getextraspace() c.Pointer {
|
||||||
|
return c.Pointer(uintptr(c.Pointer(L)) - EXTRASPACE)
|
||||||
|
}
|
||||||
func (L *State) Tonumber(idx c.Int) Number { return L.Tonumberx(idx, nil) }
|
func (L *State) Tonumber(idx c.Int) Number { return L.Tonumberx(idx, nil) }
|
||||||
func (L *State) Tostring(idx c.Int) *c.Char { return L.Tolstring(idx, nil) }
|
func (L *State) Tostring(idx c.Int) *c.Char { return L.Tolstring(idx, nil) }
|
||||||
func (L *State) Tointeger(idx c.Int) Integer { return L.Tointegerx(idx, nil) }
|
func (L *State) Tointeger(idx c.Int) Integer { return L.Tointegerx(idx, nil) }
|
||||||
func (L *State) Pop(n c.Int) { L.Settop(-(n) - 1) }
|
func (L *State) Pop(n c.Int) { L.Settop(-(n) - 1) }
|
||||||
func (L *State) Newtable() { L.Createtable(0, 0) }
|
func (L *State) Newtable() { L.Createtable(0, 0) }
|
||||||
|
|
||||||
// #define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
|
func (L *State) Register(name *c.Char, f CFunction) {
|
||||||
|
L.Pushcfunction(f)
|
||||||
|
L.Setglobal(name)
|
||||||
|
}
|
||||||
func (L *State) Pushcfunction(f CFunction) { L.Pushcclosure(f, 0) }
|
func (L *State) Pushcfunction(f CFunction) { L.Pushcclosure(f, 0) }
|
||||||
|
|
||||||
func (L *State) Isfunction(n c.Int) bool { return L.Type(n) == c.Int(FUNCTION) }
|
func (L *State) Isfunction(n c.Int) bool { return L.Type(n) == c.Int(FUNCTION) }
|
||||||
@@ -427,38 +483,63 @@ func (L *State) Isboolean(n c.Int) bool { return L.Type(n) == c.Int(BOOLEA
|
|||||||
func (L *State) Isthread(n c.Int) bool { return L.Type(n) == c.Int(THREAD) }
|
func (L *State) Isthread(n c.Int) bool { return L.Type(n) == c.Int(THREAD) }
|
||||||
func (L *State) Isnone(n c.Int) bool { return L.Type(n) == c.Int(NONE) }
|
func (L *State) Isnone(n c.Int) bool { return L.Type(n) == c.Int(NONE) }
|
||||||
func (L *State) Isnoneornil(n c.Int) bool { return L.Type(n) <= 0 }
|
func (L *State) Isnoneornil(n c.Int) bool { return L.Type(n) <= 0 }
|
||||||
|
func (L *State) Pushliteral(s *c.Char) *c.Char {
|
||||||
|
return L.Pushstring(s)
|
||||||
|
}
|
||||||
|
|
||||||
// #define lua_pushliteral(L, s) lua_pushstring(L, "" s)
|
func (L *State) Pushglobaltable() c.Int {
|
||||||
// #define lua_pushglobaltable(L) ((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS))
|
return L.Rawgeti(REGISTRYINDEX, RIDX_GLOBALS)
|
||||||
|
}
|
||||||
|
|
||||||
// #define lua_insert(L,idx) lua_rotate(L, (idx), 1)
|
func (L *State) Insert(idx c.Int) {
|
||||||
// #define lua_remove(L,idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1))
|
L.Rotate(idx, 1)
|
||||||
// #define lua_replace(L,idx) (lua_copy(L, -1, (idx)), lua_pop(L, 1))
|
}
|
||||||
|
|
||||||
// /* }============================================================== */
|
func (L *State) Remove(idx c.Int) {
|
||||||
|
L.Rotate(idx, -1)
|
||||||
|
L.Pop(1)
|
||||||
|
}
|
||||||
|
|
||||||
// /*
|
func (L *State) Replace(idx c.Int) {
|
||||||
// ** {==============================================================
|
L.Copy(-1, idx)
|
||||||
// ** compatibility macros
|
L.Pop(1)
|
||||||
// ** ===============================================================
|
}
|
||||||
// */
|
|
||||||
|
|
||||||
// #define lua_newuserdata(L,s) lua_newuserdatauv(L,s,1)
|
/* }============================================================== */
|
||||||
// #define lua_getuservalue(L,idx) lua_getiuservalue(L,idx,1)
|
|
||||||
// #define lua_setuservalue(L,idx) lua_setiuservalue(L,idx,1)
|
|
||||||
|
|
||||||
// #define LUA_NUMTAGS LUA_NUMTYPES
|
/*
|
||||||
|
** {==============================================================
|
||||||
|
** compatibility macros
|
||||||
|
** ===============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
// /* }============================================================== */
|
func (L *State) Newuserdata(sz uintptr) c.Pointer {
|
||||||
|
return L.Newuserdatauv(sz, 1)
|
||||||
|
}
|
||||||
|
|
||||||
// /*
|
func (L *State) Getuservalue(idx c.Int) c.Int {
|
||||||
// ** {======================================================================
|
return L.Getiuservalue(idx, 1)
|
||||||
// ** Debug API
|
}
|
||||||
// ** =======================================================================
|
|
||||||
// */
|
func (L *State) Setuservalue(idx c.Int) c.Int {
|
||||||
// /*
|
return L.Setiuservalue(idx, 1)
|
||||||
// ** Event codes
|
}
|
||||||
// */
|
|
||||||
|
const (
|
||||||
|
NUMTAGS = NUMTYPES
|
||||||
|
)
|
||||||
|
|
||||||
|
/* }============================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
** {======================================================================
|
||||||
|
** Debug API
|
||||||
|
** =======================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Event codes
|
||||||
|
*/
|
||||||
|
|
||||||
const (
|
const (
|
||||||
HOOKCALL = 0
|
HOOKCALL = 0
|
||||||
@@ -468,13 +549,9 @@ const (
|
|||||||
HOOKTAILCALL = 4
|
HOOKTAILCALL = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
// /*
|
/*
|
||||||
// ** Event masks
|
* Event masks
|
||||||
// */
|
*/
|
||||||
// #define LUA_MASKCALL (1 << LUA_HOOKCALL)
|
|
||||||
// #define LUA_MASKRET (1 << LUA_HOOKRET)
|
|
||||||
// #define LUA_MASKLINE (1 << LUA_HOOKLINE)
|
|
||||||
// #define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MASKCALL = 1 << HOOKCOUNT
|
MASKCALL = 1 << HOOKCOUNT
|
||||||
@@ -483,22 +560,68 @@ const (
|
|||||||
MASKCOUNT = 1 << HOOKCOUNT
|
MASKCOUNT = 1 << HOOKCOUNT
|
||||||
)
|
)
|
||||||
|
|
||||||
// LUA_API int (lua_getstack) (State *L, int level, lua_Debug *ar);
|
// llgo:link (*State).Getstack C.lua_getstack
|
||||||
// LUA_API int (lua_getinfo) (State *L, const char *what, lua_Debug *ar);
|
func (L *State) Getstack(level c.Int, ar *Debug) c.Int { return 0 }
|
||||||
// LUA_API const char *(lua_getlocal) (State *L, const lua_Debug *ar, int n);
|
|
||||||
// LUA_API const char *(lua_setlocal) (State *L, const lua_Debug *ar, int n);
|
|
||||||
// LUA_API const char *(lua_getupvalue) (State *L, int funcindex, int n);
|
|
||||||
// LUA_API const char *(lua_setupvalue) (State *L, int funcindex, int n);
|
|
||||||
|
|
||||||
// LUA_API void *(lua_upvalueid) (State *L, int fidx, int n);
|
// llgo:link (*State).Getinfo C.lua_getinfo
|
||||||
// LUA_API void (lua_upvaluejoin) (State *L, int fidx1, int n1, int fidx2, int n2);
|
func (L *State) Getinfo(what *c.Char, ar *Debug) c.Int { return 0 }
|
||||||
|
|
||||||
// LUA_API void (lua_sethook) (State *L, lua_Hook func, int mask, int count);
|
// llgo:link (*State).Getlocal C.lua_getlocal
|
||||||
// LUA_API lua_Hook (lua_gethook) (State *L);
|
func (L *State) Getlocal(ar *Debug, n c.Int) *c.Char { return nil }
|
||||||
// LUA_API int (lua_gethookmask) (State *L);
|
|
||||||
// LUA_API int (lua_gethookcount) (State *L);
|
|
||||||
|
|
||||||
// LUA_API int (lua_setcstacklimit) (State *L, unsigned int limit);
|
// llgo:link (*State).Setlocal C.lua_setlocal
|
||||||
|
func (L *State) Setlocal(ar *Debug, n c.Int) *c.Char { return nil }
|
||||||
|
|
||||||
// struct lua_Debug
|
// llgo:link (*State).Getupvalue C.lua_getupvalue
|
||||||
// /* }====================================================================== */
|
func (L *State) Getupvalue(funcindex c.Int, n c.Int) *c.Char { return nil }
|
||||||
|
|
||||||
|
// llgo:link (*State).Setupvalue C.lua_setupvalue
|
||||||
|
func (L *State) Setupvalue(funcindex c.Int, n c.Int) *c.Char { return nil }
|
||||||
|
|
||||||
|
// llgo:link (*State).Upvalueid C.lua_upvalueid
|
||||||
|
func (L *State) Upvalueid(fidx c.Int, n c.Int) c.Pointer { return nil }
|
||||||
|
|
||||||
|
// llgo:link (*State).Upvaluejoin C.lua_upvaluejoin
|
||||||
|
func (L *State) Upvaluejoin(fidx1 c.Int, n1 c.Int, fidx2 c.Int, n2 c.Int) {}
|
||||||
|
|
||||||
|
// llgo:link (*State).Sethook C.lua_sethook
|
||||||
|
func (L *State) Sethook(fn Hook, mask c.Int, count c.Int) {}
|
||||||
|
|
||||||
|
// llgo:link (*State).Gethook C.lua_gethook
|
||||||
|
func (L *State) Gethook() Hook { return nil }
|
||||||
|
|
||||||
|
// llgo:link (*State).Gethookmask C.lua_gethookmask
|
||||||
|
func (L *State) Gethookmask() c.Int { return 0 }
|
||||||
|
|
||||||
|
// llgo:link (*State).Gethookcount C.lua_gethookcount
|
||||||
|
func (L *State) Gethookcount() c.Int { return 0 }
|
||||||
|
|
||||||
|
// llgo:link (*State).Setcstacklimit C.lua_setcstacklimit
|
||||||
|
func (L *State) Setcstacklimit(limit c.Uint) c.Int { return 0 }
|
||||||
|
|
||||||
|
type CallInfo struct {
|
||||||
|
Unused [8]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type Debug struct {
|
||||||
|
Event c.Int
|
||||||
|
Name *c.Char /* (n) */
|
||||||
|
Namewhat *c.Char /* (n) 'global', 'local', 'field', 'method' */
|
||||||
|
What *c.Char /* (S) 'Lua', 'C', 'main', 'tail' */
|
||||||
|
Source *c.Char /* (S) */
|
||||||
|
Srclen uintptr /* (S) */
|
||||||
|
Currentline c.Int /* (l) */
|
||||||
|
Linedefined c.Int /* (S) */
|
||||||
|
Lastlinedefined c.Int /* (S) */
|
||||||
|
Nups byte /* (u) number of upvalues */
|
||||||
|
Nparams byte /* (u) number of parameters */
|
||||||
|
Isvararg c.Char /* (u) */
|
||||||
|
Istailcall c.Char /* (t) */
|
||||||
|
Ftransfer uint16 /* (r) index of first value transferred */
|
||||||
|
Ntransfer uint16 /* (r) number of transferred values */
|
||||||
|
ShortSrc [IDSIZE]c.Char /* (S) */
|
||||||
|
/* private part */
|
||||||
|
ICi *CallInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
/* }====================================================================== */
|
||||||
|
|||||||
41
c/lua/luaconf.go
Normal file
41
c/lua/luaconf.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package lua
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** {==================================================================
|
||||||
|
** Macros that affect the API and must be stable (that is, must be the
|
||||||
|
** same when you compile Lua and when you compile code that links to
|
||||||
|
** Lua).
|
||||||
|
** =====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ LUAI_MAXSTACK limits the size of the Lua stack.
|
||||||
|
** CHANGE it if you need a different limit. This limit is arbitrary;
|
||||||
|
** its only purpose is to stop Lua from consuming unlimited stack
|
||||||
|
** space (and to reserve some numbers for pseudo-indices).
|
||||||
|
** (It must fit into max(size_t)/32 and max(int)/2.)
|
||||||
|
*/
|
||||||
|
|
||||||
|
const (
|
||||||
|
MAXSTACK = 1000000
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ LUA_EXTRASPACE defines the size of a raw memory area associated with
|
||||||
|
** a Lua state with very fast access.
|
||||||
|
** CHANGE it if you need a different size.
|
||||||
|
*/
|
||||||
|
const (
|
||||||
|
EXTRASPACE = unsafe.Sizeof(uintptr(0))
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ LUA_IDSIZE gives the maximum size for the description of the source
|
||||||
|
** of a function in debug information.
|
||||||
|
** CHANGE it if you want a different size.
|
||||||
|
*/
|
||||||
|
const (
|
||||||
|
IDSIZE = 60
|
||||||
|
)
|
||||||
41
c/net/net.go
41
c/net/net.go
@@ -189,6 +189,18 @@ func Recv(c.Int, c.Pointer, uintptr, c.Int) c.Long
|
|||||||
//go:linkname SetSockOpt C.setsockopt
|
//go:linkname SetSockOpt C.setsockopt
|
||||||
func SetSockOpt(socket c.Int, level c.Int, optionName c.Int, optionValue c.Pointer, sockLen c.Uint) c.Int
|
func SetSockOpt(socket c.Int, level c.Int, optionName c.Int, optionValue c.Pointer, sockLen c.Uint) c.Int
|
||||||
|
|
||||||
|
//go:linkname Ntohs C.ntohs
|
||||||
|
func Ntohs(x uint16) uint16
|
||||||
|
|
||||||
|
//go:linkname Htons C.htons
|
||||||
|
func Htons(x uint16) uint16
|
||||||
|
|
||||||
|
//go:linkname Ntohl C.ntohl
|
||||||
|
func Ntohl(x c.Uint) c.Uint
|
||||||
|
|
||||||
|
//go:linkname Htonl C.htonl
|
||||||
|
func Htonl(x c.Uint) c.Uint
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
type AddrInfo struct {
|
type AddrInfo struct {
|
||||||
@@ -209,32 +221,3 @@ func Getaddrinfo(host *c.Char, port *c.Char, addrInfo *AddrInfo, result **AddrIn
|
|||||||
func Freeaddrinfo(addrInfo *AddrInfo) c.Int
|
func Freeaddrinfo(addrInfo *AddrInfo) c.Int
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
func swapInt16(data uint16) uint16 {
|
|
||||||
return (data << 8) | (data >> 8)
|
|
||||||
}
|
|
||||||
|
|
||||||
func swapInt32(data c.Uint) c.Uint {
|
|
||||||
return ((data & 0xff) << 24) |
|
|
||||||
((data & 0xff00) << 8) |
|
|
||||||
((data & 0xff0000) >> 8) |
|
|
||||||
((data & 0xff000000) >> 24)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Htons(x uint16) uint16 {
|
|
||||||
return swapInt16(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Ntohs(x uint16) uint16 {
|
|
||||||
return swapInt16(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Htonl(x c.Uint) c.Uint {
|
|
||||||
return swapInt32(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Ntohl(x c.Uint) c.Uint {
|
|
||||||
return swapInt32(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
int llgoClearenv() {
|
int llgoClearenv() {
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
@@ -7,3 +8,5 @@ int llgoClearenv() {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int llgoErrno() { return errno; }
|
||||||
|
|||||||
10
c/os/os.go
10
c/os/os.go
@@ -70,8 +70,8 @@ type (
|
|||||||
StatT = syscall.Stat_t
|
StatT = syscall.Stat_t
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:linkname Errno errno
|
//go:linkname Errno C.llgoErrno
|
||||||
var Errno c.Int
|
func Errno() c.Int
|
||||||
|
|
||||||
//go:linkname Umask C.umask
|
//go:linkname Umask C.umask
|
||||||
func Umask(cmask ModeT) ModeT
|
func Umask(cmask ModeT) ModeT
|
||||||
@@ -236,12 +236,12 @@ func Isatty(fd c.Int) c.Int
|
|||||||
// Execl requires the full path of the program to be provided.
|
// Execl requires the full path of the program to be provided.
|
||||||
//
|
//
|
||||||
//go:linkname Execl C.execl
|
//go:linkname Execl C.execl
|
||||||
func Execl(path *c.Char, __llgo_va_list ...any) c.Int
|
func Execl(path *c.Char, arg0 *c.Char, __llgo_va_list ...any) c.Int
|
||||||
|
|
||||||
// Execle(const char *path, const char *arg0, ..., /* (char *)0, char *const envp[] */)
|
// Execle(const char *path, const char *arg0, ..., /* (char *)0, char *const envp[] */)
|
||||||
//
|
//
|
||||||
//go:linkname Execle C.execle
|
//go:linkname Execle C.execle
|
||||||
func Execle(path *c.Char, __llgo_va_list ...any) c.Int
|
func Execle(path *c.Char, arg0 *c.Char, __llgo_va_list ...any) c.Int
|
||||||
|
|
||||||
// Execlp(const char *file, const char *arg0, ..., /*, (char *)0, */)
|
// Execlp(const char *file, const char *arg0, ..., /*, (char *)0, */)
|
||||||
//
|
//
|
||||||
@@ -249,7 +249,7 @@ func Execle(path *c.Char, __llgo_va_list ...any) c.Int
|
|||||||
// paths specified in the PATH environment variable.
|
// paths specified in the PATH environment variable.
|
||||||
//
|
//
|
||||||
//go:linkname Execlp C.execlp
|
//go:linkname Execlp C.execlp
|
||||||
func Execlp(file *c.Char, __llgo_va_list ...any) c.Int
|
func Execlp(file *c.Char, arg0 *c.Char, __llgo_va_list ...any) c.Int
|
||||||
|
|
||||||
//go:linkname Execv C.execv
|
//go:linkname Execv C.execv
|
||||||
func Execv(path *c.Char, argv **c.Char) c.Int
|
func Execv(path *c.Char, argv **c.Char) c.Int
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ package os
|
|||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LLGoPackage = "decl"
|
LLGoFiles = "_os/os.c"
|
||||||
|
LLGoPackage = "link"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:linkname Clearenv C.clearenv
|
//go:linkname Clearenv C.clearenv
|
||||||
|
|||||||
@@ -22,10 +22,6 @@ import (
|
|||||||
"github.com/goplus/llgo/c"
|
"github.com/goplus/llgo/c"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
LLGoPackage = "decl"
|
|
||||||
)
|
|
||||||
|
|
||||||
func __noop__() c.Int {
|
func __noop__() c.Int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@@ -36,59 +32,12 @@ type aThread struct {
|
|||||||
Unused [8]byte
|
Unused [8]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//llgo:type C
|
||||||
|
type RoutineFunc func(c.Pointer) c.Pointer
|
||||||
|
|
||||||
// Thread represents a POSIX thread.
|
// Thread represents a POSIX thread.
|
||||||
type Thread = *aThread
|
type Thread = *aThread
|
||||||
|
|
||||||
// The pthread_create() function starts a new thread in the calling
|
|
||||||
// process. The new thread starts execution by invoking
|
|
||||||
// start_routine(); arg is passed as the sole argument of
|
|
||||||
// start_routine().
|
|
||||||
//
|
|
||||||
// The new thread terminates in one of the following ways:
|
|
||||||
//
|
|
||||||
// - It calls pthread_exit(3), specifying an exit status value that
|
|
||||||
// is available to another thread in the same process that calls
|
|
||||||
// pthread_join(3).
|
|
||||||
//
|
|
||||||
// - It returns from start_routine(). This is equivalent to
|
|
||||||
// calling pthread_exit(3) with the value supplied in the return
|
|
||||||
// statement.
|
|
||||||
//
|
|
||||||
// - It is canceled (see pthread_cancel(3)).
|
|
||||||
//
|
|
||||||
// - Any of the threads in the process calls exit(3), or the main
|
|
||||||
// thread performs a return from main(). This causes the
|
|
||||||
// termination of all threads in the process.
|
|
||||||
//
|
|
||||||
// On success, pthread_create() returns 0; on error, it returns an
|
|
||||||
// error number, and the contents of *thread are undefined.
|
|
||||||
//
|
|
||||||
// See https://man7.org/linux/man-pages/man3/pthread_create.3.html
|
|
||||||
//
|
|
||||||
//go:linkname Create C.pthread_create
|
|
||||||
func Create(pthread *Thread, attr *Attr, routine func(c.Pointer) c.Pointer, arg c.Pointer) c.Int
|
|
||||||
|
|
||||||
// The pthread_join() function waits for the thread specified by
|
|
||||||
// thread to terminate. If that thread has already terminated, then
|
|
||||||
// pthread_join() returns immediately. The thread specified by
|
|
||||||
// thread must be joinable.
|
|
||||||
//
|
|
||||||
// If retval is not NULL, then pthread_join() copies the exit status
|
|
||||||
// of the target thread (i.e., the value that the target thread
|
|
||||||
// supplied to pthread_exit(3)) into the location pointed to by
|
|
||||||
// retval. If the target thread was canceled, then PTHREAD_CANCELED
|
|
||||||
// is placed in the location pointed to by retval.
|
|
||||||
//
|
|
||||||
// If multiple threads simultaneously try to join with the same
|
|
||||||
// thread, the results are undefined. If the thread calling
|
|
||||||
// pthread_join() is canceled, then the target thread will remain
|
|
||||||
// joinable (i.e., it will not be detached).
|
|
||||||
//
|
|
||||||
// See https://man7.org/linux/man-pages/man3/pthread_join.3.html
|
|
||||||
//
|
|
||||||
//go:linkname Join C.pthread_join
|
|
||||||
func Join(thread Thread, retval *c.Pointer) c.Int
|
|
||||||
|
|
||||||
// The pthread_exit() function terminates the calling thread and
|
// The pthread_exit() function terminates the calling thread and
|
||||||
// returns a value via retval that (if the thread is joinable) is
|
// returns a value via retval that (if the thread is joinable) is
|
||||||
// available to another thread in the same process that calls
|
// available to another thread in the same process that calls
|
||||||
|
|||||||
80
c/pthread/pthread_gc.go
Normal file
80
c/pthread/pthread_gc.go
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
//go:build !nogc
|
||||||
|
// +build !nogc
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pthread
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LLGoPackage = "link: $(pkg-config --libs bdw-gc); -lgc"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The pthread_create() function starts a new thread in the calling
|
||||||
|
// process. The new thread starts execution by invoking
|
||||||
|
// start_routine(); arg is passed as the sole argument of
|
||||||
|
// start_routine().
|
||||||
|
//
|
||||||
|
// The new thread terminates in one of the following ways:
|
||||||
|
//
|
||||||
|
// - It calls pthread_exit(3), specifying an exit status value that
|
||||||
|
// is available to another thread in the same process that calls
|
||||||
|
// pthread_join(3).
|
||||||
|
//
|
||||||
|
// - It returns from start_routine(). This is equivalent to
|
||||||
|
// calling pthread_exit(3) with the value supplied in the return
|
||||||
|
// statement.
|
||||||
|
//
|
||||||
|
// - It is canceled (see pthread_cancel(3)).
|
||||||
|
//
|
||||||
|
// - Any of the threads in the process calls exit(3), or the main
|
||||||
|
// thread performs a return from main(). This causes the
|
||||||
|
// termination of all threads in the process.
|
||||||
|
//
|
||||||
|
// On success, pthread_create() returns 0; on error, it returns an
|
||||||
|
// error number, and the contents of *thread are undefined.
|
||||||
|
//
|
||||||
|
// See https://man7.org/linux/man-pages/man3/pthread_create.3.html
|
||||||
|
//
|
||||||
|
//go:linkname Create C.GC_pthread_create
|
||||||
|
func Create(pthread *Thread, attr *Attr, routine RoutineFunc, arg c.Pointer) c.Int
|
||||||
|
|
||||||
|
// The pthread_join() function waits for the thread specified by
|
||||||
|
// thread to terminate. If that thread has already terminated, then
|
||||||
|
// pthread_join() returns immediately. The thread specified by
|
||||||
|
// thread must be joinable.
|
||||||
|
//
|
||||||
|
// If retval is not NULL, then pthread_join() copies the exit status
|
||||||
|
// of the target thread (i.e., the value that the target thread
|
||||||
|
// supplied to pthread_exit(3)) into the location pointed to by
|
||||||
|
// retval. If the target thread was canceled, then PTHREAD_CANCELED
|
||||||
|
// is placed in the location pointed to by retval.
|
||||||
|
//
|
||||||
|
// If multiple threads simultaneously try to join with the same
|
||||||
|
// thread, the results are undefined. If the thread calling
|
||||||
|
// pthread_join() is canceled, then the target thread will remain
|
||||||
|
// joinable (i.e., it will not be detached).
|
||||||
|
//
|
||||||
|
// See https://man7.org/linux/man-pages/man3/pthread_join.3.html
|
||||||
|
//
|
||||||
|
//go:linkname Join C.GC_pthread_join
|
||||||
|
func Join(thread Thread, retval *c.Pointer) c.Int
|
||||||
80
c/pthread/pthread_nogc.go
Normal file
80
c/pthread/pthread_nogc.go
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
//go:build nogc
|
||||||
|
// +build nogc
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pthread
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LLGoPackage = "decl"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The pthread_create() function starts a new thread in the calling
|
||||||
|
// process. The new thread starts execution by invoking
|
||||||
|
// start_routine(); arg is passed as the sole argument of
|
||||||
|
// start_routine().
|
||||||
|
//
|
||||||
|
// The new thread terminates in one of the following ways:
|
||||||
|
//
|
||||||
|
// - It calls pthread_exit(3), specifying an exit status value that
|
||||||
|
// is available to another thread in the same process that calls
|
||||||
|
// pthread_join(3).
|
||||||
|
//
|
||||||
|
// - It returns from start_routine(). This is equivalent to
|
||||||
|
// calling pthread_exit(3) with the value supplied in the return
|
||||||
|
// statement.
|
||||||
|
//
|
||||||
|
// - It is canceled (see pthread_cancel(3)).
|
||||||
|
//
|
||||||
|
// - Any of the threads in the process calls exit(3), or the main
|
||||||
|
// thread performs a return from main(). This causes the
|
||||||
|
// termination of all threads in the process.
|
||||||
|
//
|
||||||
|
// On success, pthread_create() returns 0; on error, it returns an
|
||||||
|
// error number, and the contents of *thread are undefined.
|
||||||
|
//
|
||||||
|
// See https://man7.org/linux/man-pages/man3/pthread_create.3.html
|
||||||
|
//
|
||||||
|
//go:linkname Create C.pthread_create
|
||||||
|
func Create(pthread *Thread, attr *Attr, routine RoutineFunc, arg c.Pointer) c.Int
|
||||||
|
|
||||||
|
// The pthread_join() function waits for the thread specified by
|
||||||
|
// thread to terminate. If that thread has already terminated, then
|
||||||
|
// pthread_join() returns immediately. The thread specified by
|
||||||
|
// thread must be joinable.
|
||||||
|
//
|
||||||
|
// If retval is not NULL, then pthread_join() copies the exit status
|
||||||
|
// of the target thread (i.e., the value that the target thread
|
||||||
|
// supplied to pthread_exit(3)) into the location pointed to by
|
||||||
|
// retval. If the target thread was canceled, then PTHREAD_CANCELED
|
||||||
|
// is placed in the location pointed to by retval.
|
||||||
|
//
|
||||||
|
// If multiple threads simultaneously try to join with the same
|
||||||
|
// thread, the results are undefined. If the thread calling
|
||||||
|
// pthread_join() is canceled, then the target thread will remain
|
||||||
|
// joinable (i.e., it will not be detached).
|
||||||
|
//
|
||||||
|
// See https://man7.org/linux/man-pages/man3/pthread_join.3.html
|
||||||
|
//
|
||||||
|
//go:linkname Join C.pthread_join
|
||||||
|
func Join(thread Thread, retval *c.Pointer) c.Int
|
||||||
@@ -27,7 +27,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LLGoFiles = "_pthd/pthd.c"
|
LLGoFiles = "_wrap/pthd.c"
|
||||||
LLGoPackage = "link"
|
LLGoPackage = "link"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
32
c/signal/signal.go
Normal file
32
c/signal/signal.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package signal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
)
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
const (
|
||||||
|
LLGoPackage = "link"
|
||||||
|
)
|
||||||
|
|
||||||
|
//llgo:type C
|
||||||
|
type SignalHandler func(c.Int)
|
||||||
|
|
||||||
|
//llgo:type C
|
||||||
|
type sigactiont struct {
|
||||||
|
handler SignalHandler
|
||||||
|
tramp unsafe.Pointer
|
||||||
|
mask c.Int
|
||||||
|
flags c.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:linkname sigaction C.sigaction
|
||||||
|
func sigaction(sig c.Int, act, old *sigactiont) c.Int
|
||||||
|
|
||||||
|
func Signal(sig c.Int, hanlder SignalHandler) c.Int {
|
||||||
|
var act sigactiont
|
||||||
|
act.handler = hanlder
|
||||||
|
return sigaction(sig, &act, nil)
|
||||||
|
}
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/c/cjson"
|
|
||||||
"github.com/goplus/llgo/chore/llcppg/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Conf struct {
|
|
||||||
*cjson.JSON
|
|
||||||
*types.Config
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetConf(data []byte) (Conf, error) {
|
|
||||||
parsedConf := cjson.ParseBytes(data)
|
|
||||||
if parsedConf == nil {
|
|
||||||
return Conf{}, errors.New("failed to parse config")
|
|
||||||
}
|
|
||||||
|
|
||||||
config := &types.Config{
|
|
||||||
Name: GetStringItem(parsedConf, "name", ""),
|
|
||||||
CFlags: GetStringItem(parsedConf, "cflags", ""),
|
|
||||||
Libs: GetStringItem(parsedConf, "libs", ""),
|
|
||||||
Include: GetStringArrayItem(parsedConf, "include"),
|
|
||||||
TrimPrefixes: GetStringArrayItem(parsedConf, "trimPrefixes"),
|
|
||||||
}
|
|
||||||
|
|
||||||
return Conf{
|
|
||||||
JSON: parsedConf,
|
|
||||||
Config: config,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetString(obj *cjson.JSON) (value string) {
|
|
||||||
str := obj.GetStringValue()
|
|
||||||
return unsafe.String((*byte)(unsafe.Pointer(str)), c.Strlen(str))
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetStringItem(obj *cjson.JSON, key string, defval string) (value string) {
|
|
||||||
item := obj.GetObjectItemCaseSensitive(c.AllocaCStr(key))
|
|
||||||
if item == nil {
|
|
||||||
return defval
|
|
||||||
}
|
|
||||||
return GetString(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetStringArrayItem(obj *cjson.JSON, key string) (value []string) {
|
|
||||||
item := obj.GetObjectItemCaseSensitive(c.AllocaCStr(key))
|
|
||||||
if item == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
value = make([]string, item.GetArraySize())
|
|
||||||
for i := range value {
|
|
||||||
value[i] = GetString(item.GetArrayItem(c.Int(i)))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@@ -1,233 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/c/cjson"
|
|
||||||
"github.com/goplus/llgo/chore/_xtool/llcppsymg/config"
|
|
||||||
"github.com/goplus/llgo/chore/_xtool/llcppsymg/parse"
|
|
||||||
"github.com/goplus/llgo/chore/llcppg/types"
|
|
||||||
"github.com/goplus/llgo/cpp/llvm"
|
|
||||||
"github.com/goplus/llgo/xtool/nm"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
cfgFile := "llcppg.cfg"
|
|
||||||
if len(os.Args) > 1 {
|
|
||||||
cfgFile = os.Args[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
var data []byte
|
|
||||||
var err error
|
|
||||||
if cfgFile == "-" {
|
|
||||||
data, err = io.ReadAll(os.Stdin)
|
|
||||||
} else {
|
|
||||||
data, err = os.ReadFile(cfgFile)
|
|
||||||
}
|
|
||||||
check(err)
|
|
||||||
|
|
||||||
conf, err := config.GetConf(data)
|
|
||||||
check(err)
|
|
||||||
defer conf.Delete()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, "Failed to parse config file:", cfgFile)
|
|
||||||
}
|
|
||||||
symbols, err := parseDylibSymbols(conf.Libs)
|
|
||||||
|
|
||||||
check(err)
|
|
||||||
|
|
||||||
filepaths := genHeaderFilePath(conf.CFlags, conf.Include)
|
|
||||||
headerInfos, err := parse.ParseHeaderFile(filepaths, conf.TrimPrefixes)
|
|
||||||
check(err)
|
|
||||||
|
|
||||||
symbolInfo := getCommonSymbols(symbols, headerInfos, conf.TrimPrefixes)
|
|
||||||
|
|
||||||
err = genSymbolTableFile(symbolInfo)
|
|
||||||
check(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func check(err error) {
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseDylibSymbols(lib string) ([]*nm.Symbol, error) {
|
|
||||||
dylibPath, err := genDylibPath(lib)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.New("failed to generate dylib path")
|
|
||||||
}
|
|
||||||
|
|
||||||
files, err := nm.New("").List(dylibPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.New("failed to list symbols in dylib")
|
|
||||||
}
|
|
||||||
|
|
||||||
var symbols []*nm.Symbol
|
|
||||||
for _, file := range files {
|
|
||||||
symbols = append(symbols, file.Symbols...)
|
|
||||||
}
|
|
||||||
|
|
||||||
return symbols, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func genDylibPath(lib string) (string, error) {
|
|
||||||
output := lib
|
|
||||||
libPath := ""
|
|
||||||
libName := ""
|
|
||||||
for _, part := range strings.Fields(string(output)) {
|
|
||||||
if strings.HasPrefix(part, "-L") {
|
|
||||||
libPath = part[2:]
|
|
||||||
} else if strings.HasPrefix(part, "-l") {
|
|
||||||
libName = part[2:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if libPath == "" || libName == "" {
|
|
||||||
return "", fmt.Errorf("failed to parse pkg-config output: %s", output)
|
|
||||||
}
|
|
||||||
|
|
||||||
dylibPath := filepath.Join(libPath, "lib"+libName+".dylib")
|
|
||||||
return dylibPath, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func decodeSymbol(symbolName string) string {
|
|
||||||
if symbolName == "" {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
demangled := llvm.ItaniumDemangle(symbolName, true)
|
|
||||||
if demangled == nil {
|
|
||||||
return symbolName
|
|
||||||
}
|
|
||||||
defer c.Free(unsafe.Pointer(demangled))
|
|
||||||
demangleName := c.GoString(demangled)
|
|
||||||
return strings.TrimSpace(demangleName)
|
|
||||||
}
|
|
||||||
|
|
||||||
func genHeaderFilePath(cflags string, files []string) []string {
|
|
||||||
prefixPath := cflags
|
|
||||||
prefixPath = strings.TrimPrefix(prefixPath, "-I")
|
|
||||||
var includePaths []string
|
|
||||||
for _, file := range files {
|
|
||||||
includePaths = append(includePaths, filepath.Join(prefixPath, "/"+file))
|
|
||||||
}
|
|
||||||
return includePaths
|
|
||||||
}
|
|
||||||
|
|
||||||
func getCommonSymbols(dylibSymbols []*nm.Symbol, symbolMap map[string]string, prefix []string) []*types.SymbolInfo {
|
|
||||||
var commonSymbols []*types.SymbolInfo
|
|
||||||
for _, dylibSym := range dylibSymbols {
|
|
||||||
symName := strings.TrimPrefix(dylibSym.Name, "_")
|
|
||||||
if goName, ok := symbolMap[symName]; ok {
|
|
||||||
symbolInfo := &types.SymbolInfo{
|
|
||||||
Mangle: symName,
|
|
||||||
CPP: decodeSymbol(dylibSym.Name),
|
|
||||||
Go: goName,
|
|
||||||
}
|
|
||||||
commonSymbols = append(commonSymbols, symbolInfo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return commonSymbols
|
|
||||||
}
|
|
||||||
|
|
||||||
func genSymbolTableFile(symbolInfos []*types.SymbolInfo) error {
|
|
||||||
// keep open follow code block can run successfully
|
|
||||||
for i := range symbolInfos {
|
|
||||||
println("symbol", symbolInfos[i].Go)
|
|
||||||
}
|
|
||||||
|
|
||||||
fileName := "llcppg.symb.json"
|
|
||||||
existingSymbols, err := readExistingSymbolTable(fileName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := range symbolInfos {
|
|
||||||
if existingSymbol, exists := existingSymbols[symbolInfos[i].Mangle]; exists {
|
|
||||||
symbolInfos[i].Go = existingSymbol.Go
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
root := cjson.Array()
|
|
||||||
defer root.Delete()
|
|
||||||
|
|
||||||
for _, symbol := range symbolInfos {
|
|
||||||
item := cjson.Object()
|
|
||||||
item.SetItem(c.Str("mangle"), cjson.String(c.AllocaCStr(symbol.Mangle)))
|
|
||||||
item.SetItem(c.Str("c++"), cjson.String(c.AllocaCStr(symbol.CPP)))
|
|
||||||
item.SetItem(c.Str("go"), cjson.String(c.AllocaCStr(symbol.Go)))
|
|
||||||
root.AddItem(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
cStr := root.Print()
|
|
||||||
if cStr == nil {
|
|
||||||
return errors.New("symbol table is empty")
|
|
||||||
}
|
|
||||||
defer c.Free(unsafe.Pointer(cStr))
|
|
||||||
|
|
||||||
data := unsafe.Slice((*byte)(unsafe.Pointer(cStr)), c.Strlen(cStr))
|
|
||||||
|
|
||||||
if err := os.WriteFile(fileName, data, 0644); err != nil {
|
|
||||||
return errors.New("failed to write symbol table file")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func readExistingSymbolTable(fileName string) (map[string]types.SymbolInfo, error) {
|
|
||||||
existingSymbols := make(map[string]types.SymbolInfo)
|
|
||||||
|
|
||||||
if _, err := os.Stat(fileName); err != nil {
|
|
||||||
return existingSymbols, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := os.ReadFile(fileName)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.New("failed to read symbol table file")
|
|
||||||
}
|
|
||||||
|
|
||||||
parsedJSON := cjson.ParseBytes(data)
|
|
||||||
if parsedJSON == nil {
|
|
||||||
return nil, errors.New("failed to parse JSON")
|
|
||||||
}
|
|
||||||
|
|
||||||
arraySize := parsedJSON.GetArraySize()
|
|
||||||
|
|
||||||
for i := 0; i < int(arraySize); i++ {
|
|
||||||
item := parsedJSON.GetArrayItem(c.Int(i))
|
|
||||||
if item == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
symbol := types.SymbolInfo{
|
|
||||||
Mangle: config.GetStringItem(item, "mangle", ""),
|
|
||||||
CPP: config.GetStringItem(item, "c++", ""),
|
|
||||||
Go: config.GetStringItem(item, "go", ""),
|
|
||||||
}
|
|
||||||
existingSymbols[symbol.Mangle] = symbol
|
|
||||||
}
|
|
||||||
|
|
||||||
return existingSymbols, nil
|
|
||||||
}
|
|
||||||
@@ -1,167 +0,0 @@
|
|||||||
package parse
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/c/clang"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Context struct {
|
|
||||||
namespaceName string
|
|
||||||
className string
|
|
||||||
prefixes []string
|
|
||||||
symbolMap map[string]string
|
|
||||||
currentFile string
|
|
||||||
nameCounts map[string]int
|
|
||||||
}
|
|
||||||
|
|
||||||
func newContext(prefixes []string) *Context {
|
|
||||||
return &Context{
|
|
||||||
prefixes: prefixes,
|
|
||||||
symbolMap: make(map[string]string),
|
|
||||||
nameCounts: make(map[string]int),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Context) setNamespaceName(name string) {
|
|
||||||
c.namespaceName = name
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Context) setClassName(name string) {
|
|
||||||
c.className = name
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Context) setCurrentFile(filename string) {
|
|
||||||
c.currentFile = filename
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Context) removePrefix(str string) string {
|
|
||||||
for _, prefix := range c.prefixes {
|
|
||||||
if strings.HasPrefix(str, prefix) {
|
|
||||||
return strings.TrimPrefix(str, prefix)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Context) genGoName(name string) string {
|
|
||||||
class := c.removePrefix(c.className)
|
|
||||||
name = c.removePrefix(name)
|
|
||||||
|
|
||||||
var baseName string
|
|
||||||
if class == "" {
|
|
||||||
baseName = name
|
|
||||||
} else {
|
|
||||||
baseName = c.genMethodName(class, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.addSuffix(baseName)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Context) genMethodName(class, name string) string {
|
|
||||||
prefix := "(*" + class + ")."
|
|
||||||
if class == name {
|
|
||||||
return prefix + "Init"
|
|
||||||
}
|
|
||||||
if name == "~"+class {
|
|
||||||
return prefix + "Dispose"
|
|
||||||
}
|
|
||||||
return prefix + name
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Context) addSuffix(name string) string {
|
|
||||||
c.nameCounts[name]++
|
|
||||||
count := c.nameCounts[name]
|
|
||||||
if count > 1 {
|
|
||||||
return name + "__" + strconv.Itoa(count-1)
|
|
||||||
}
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
var context = newContext([]string{})
|
|
||||||
|
|
||||||
func collectFuncInfo(cursor clang.Cursor) {
|
|
||||||
cursorStr := cursor.String()
|
|
||||||
symbol := cursor.Mangling()
|
|
||||||
|
|
||||||
name := c.GoString(cursorStr.CStr())
|
|
||||||
symbolName := c.GoString(symbol.CStr())
|
|
||||||
if len(symbolName) >= 1 && symbolName[0] == '_' {
|
|
||||||
symbolName = symbolName[1:]
|
|
||||||
}
|
|
||||||
defer symbol.Dispose()
|
|
||||||
defer cursorStr.Dispose()
|
|
||||||
|
|
||||||
goName := context.genGoName(name)
|
|
||||||
context.symbolMap[symbolName] = goName
|
|
||||||
}
|
|
||||||
|
|
||||||
func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitResult {
|
|
||||||
if cursor.Kind == clang.CursorNamespace {
|
|
||||||
nameStr := cursor.String()
|
|
||||||
defer nameStr.Dispose()
|
|
||||||
|
|
||||||
context.setNamespaceName(c.GoString(nameStr.CStr()))
|
|
||||||
clang.VisitChildren(cursor, visit, nil)
|
|
||||||
context.setNamespaceName("")
|
|
||||||
} else if cursor.Kind == clang.CursorClassDecl {
|
|
||||||
nameStr := cursor.String()
|
|
||||||
defer nameStr.Dispose()
|
|
||||||
|
|
||||||
context.setClassName(c.GoString(nameStr.CStr()))
|
|
||||||
clang.VisitChildren(cursor, visit, nil)
|
|
||||||
context.setClassName("")
|
|
||||||
} else if cursor.Kind == clang.CursorCXXMethod || cursor.Kind == clang.CursorFunctionDecl || cursor.Kind == clang.CursorConstructor || cursor.Kind == clang.CursorDestructor {
|
|
||||||
loc := cursor.Location()
|
|
||||||
var file clang.File
|
|
||||||
var line, column c.Uint
|
|
||||||
|
|
||||||
loc.SpellingLocation(&file, &line, &column, nil)
|
|
||||||
filename := file.FileName()
|
|
||||||
|
|
||||||
if c.Strcmp(filename.CStr(), c.AllocaCStr(context.currentFile)) == 0 {
|
|
||||||
collectFuncInfo(cursor)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer filename.Dispose()
|
|
||||||
}
|
|
||||||
|
|
||||||
return clang.ChildVisit_Continue
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseHeaderFile(filepaths []string, prefixes []string) (map[string]string, error) {
|
|
||||||
index := clang.CreateIndex(0, 0)
|
|
||||||
args := make([]*c.Char, 3)
|
|
||||||
args[0] = c.Str("-x")
|
|
||||||
args[1] = c.Str("c++")
|
|
||||||
args[2] = c.Str("-std=c++11")
|
|
||||||
context = newContext(prefixes)
|
|
||||||
|
|
||||||
for _, filename := range filepaths {
|
|
||||||
unit := index.ParseTranslationUnit(
|
|
||||||
c.AllocaCStr(filename),
|
|
||||||
unsafe.SliceData(args), 3,
|
|
||||||
nil, 0,
|
|
||||||
clang.TranslationUnit_None,
|
|
||||||
)
|
|
||||||
|
|
||||||
if unit == nil {
|
|
||||||
return nil, errors.New("Unable to parse translation unit for file " + filename)
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor := unit.Cursor()
|
|
||||||
context.setCurrentFile(filename)
|
|
||||||
|
|
||||||
clang.VisitChildren(cursor, visit, nil)
|
|
||||||
|
|
||||||
unit.Dispose()
|
|
||||||
}
|
|
||||||
|
|
||||||
index.Dispose()
|
|
||||||
|
|
||||||
return context.symbolMap, nil
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
llcppg - Autogen tool for C/C++ libraries
|
|
||||||
====
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```sh
|
|
||||||
llcppg [config-file]
|
|
||||||
```
|
|
||||||
|
|
||||||
If `config-file` is not specified, a `llcppg.cfg` file is used in current directory. The configuration file format is as follows:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"name": "inireader",
|
|
||||||
"cflags": "$(pkg-config --cflags inireader)",
|
|
||||||
"include": [
|
|
||||||
"INIReader.h",
|
|
||||||
"AnotherHeaderFile.h"
|
|
||||||
],
|
|
||||||
"libs": "$(pkg-config --libs inireader)",
|
|
||||||
"trimPrefixes": ["Ini", "INI"]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Design
|
|
||||||
|
|
||||||
See [llcppg Design](design.md).
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user