Compare commits

...

254 Commits

Author SHA1 Message Date
xushiwei
210c483635 Merge pull request #687 from xushiwei/q
library syscall: linux fix
2024-08-09 00:33:09 +08:00
xushiwei
8ca4212650 library syscall: linux fix 2024-08-09 00:22:29 +08:00
xushiwei
c91dba5ed6 Merge pull request #686 from xushiwei/q
rollback golang.org/x/tools v0.22.0 => v0.19.0
2024-08-08 23:58:31 +08:00
xushiwei
c8de05f101 rollback golang.org/x/tools v0.22.0 => v0.19.0 2024-08-08 23:52:29 +08:00
xushiwei
0ac7cde498 Merge pull request #684 from visualfc/initafter
cl: build initAfter
2024-08-08 23:05:02 +08:00
visualfc
108829ad9c cl: build initAfter 2024-08-08 21:36:18 +08:00
xushiwei
c5b96f4e9c Merge pull request #681 from luoliwoshang/llcppsymg/refine
llcppsymg:improve parse symbol
2024-08-08 16:26:24 +08:00
luoliwoshang
4c2099d33e llcppg:remove unuse types 2024-08-08 15:18:16 +08:00
luoliwoshang
fe5de95008 llcppsymg:improve parsing process 2024-08-08 15:17:10 +08:00
xushiwei
4b0cfc0751 Merge pull request #677 from tsingbx/bigInt
llgo support big.Int
2024-08-08 14:23:32 +08:00
tsingbx
c2bf05942e add openssl BIGNUM support 2024-08-08 13:34:04 +08:00
tsingbx
df37f80c8e add big.Int Lsh and Rsh and test it 2024-08-08 13:33:14 +08:00
xushiwei
2c19d7218d Merge pull request #680 from xushiwei/q
llcppg design
2024-08-08 11:57:20 +08:00
xushiwei
34899e8d36 llcppg design 2024-08-08 11:49:55 +08:00
xushiwei
bf8c10ed25 Merge pull request #678 from spongehah/refactor/c-libuv-remove-go-wrapper
fix(c/libuv): Adjust comment errors and demo code
2024-08-08 11:33:10 +08:00
xushiwei
93c33e08c2 Merge pull request #679 from xushiwei/hmac
llcppg/ast: ppdNode
2024-08-08 11:31:01 +08:00
xushiwei
3992dd1dd0 Merge pull request #675 from hackerchai/feature/c-net-add-missing-funcs
feat(c/net): Add SockaddrStorage func, Ntohs func & SetSockOpt func
2024-08-08 11:30:48 +08:00
xushiwei
cab29c2be7 llcppg/ast: ppdNode 2024-08-08 11:21:56 +08:00
hackerchai
f582657ffd fix(c/net): Remove unused implicit import
Signed-off-by: hackerchai <i@hackerchai.com>
2024-08-08 10:12:47 +08:00
赵英杰
2823ac1aee fix(c/libuv): Adjust comment errors and demo code 2024-08-08 10:04:20 +08:00
tsingbx
289caa7cc2 add BN_CTX Start, Get, End and Add big.Int Mul and test it 2024-08-08 09:10:31 +08:00
tsingbx
0a8bad46b5 add big.Int Set, Abs, Neg and add test it 2024-08-08 08:31:03 +08:00
xushiwei
aa4f518262 Merge pull request #673 from cpunion/libuv-async
Add libuv async
2024-08-07 21:43:50 +08:00
xushiwei
f76fa879fc Merge pull request #676 from luoliwoshang/xtool/ast/funcproto
castdump:funcproto type & computed enum value
2024-08-07 21:42:47 +08:00
luoliwoshang
8d70aba1f5 castdump:funcproto type & enum value 2024-08-07 20:33:35 +08:00
Li Jie
a44bb35aec libuv: add async 2024-08-07 20:24:43 +08:00
xushiwei
4fda2b656f Merge pull request #672 from luoliwoshang/c/clang/type-tree
castdump:array,typedef,pointer,funcproto,enum & builtin type
2024-08-07 19:15:37 +08:00
xushiwei
e626d00fdf Merge pull request #674 from hackerchai/feature/c-calloc
feat(c): Add Calloc func
2024-08-07 18:39:35 +08:00
hackerchai
bf09e3c3ae feat(c/net): Add SockaddrStorage func, Ntohs func & SetSockOpt func 2024-08-07 18:04:04 +08:00
hackerchai
753dcd3301 feat(c): Add Calloc func 2024-08-07 16:45:17 +08:00
Li Jie
8b5dee510e libuv: add uv_stop 2024-08-07 16:21:12 +08:00
luoliwoshang
9cb73fbf78 castdump:array,typedef,pointer & builtin type 2024-08-07 15:52:26 +08:00
xushiwei
e6b4deb5c4 Merge pull request #657 from hackerchai/fix/c-libuv-missing-func
feat(c/libuv): Add libuv missing funcs & refactor go func style
2024-08-07 15:04:52 +08:00
hackerchai
8848222728 feat(c/libuv): Add GetIoWatcherFd func using LLGoFiles 2024-08-07 14:49:21 +08:00
hackerchai
3cd62994c7 Revert "refactor(c/libuv): Use cgo alias replace struct assertion in fs"
This reverts commit 45ba5b8dc50a13223e05ad673f4e57d7277d3f24.

# Conflicts:
#	c/libuv/net.go
2024-08-07 14:49:20 +08:00
hackerchai
dd93a97790 Revert "feat(c/libuv): Add GetIoWatcherFd func"
This reverts commit 1ce16727b1195a65c8f2c9de07a864ed5e3902ef.

Signed-off-by: hackerchai <i@hackerchai.com>
2024-08-07 14:49:19 +08:00
hackerchai
e40e2d2d14 style(c/libuv): Use go type funcs & update demo(syanc_fs, echo_server) 2024-08-07 14:49:18 +08:00
hackerchai
26f8ce7b5a refactor(c/libuv): Use cgo alias replace struct assertion in fs
refactro(c/libuv): Use cgo alias avoid implicit struct member declaration
2024-08-07 14:49:17 +08:00
hackerchai
9a61e374b5 refactor(c/libuv): Move some func due to libuv doc
doc: https://docs.libuv.org/en/v1.x/
2024-08-07 14:49:16 +08:00
hackerchai
9b12e9819c fix(c/libuv/demo): Fix echo_server stream convert 2024-08-07 14:49:15 +08:00
hackerchai
5d0a91239c feat(c/libuv): Add GetIoWatcherFd func 2024-08-07 14:49:14 +08:00
hackerchai
c848278690 feat(c/libuv): Add uv_close & uv_signal func
Signed-off-by: hackerchai <i@hackerchai.com>

feat(c/libuv): Add uv_signal_stop func

Signed-off-by: hackerchai <i@hackerchai.com>

feat(c/libuv): Add GetIoWatcher, GetFd func & add Io srtuct

Signed-off-by: hackerchai <i@hackerchai.com>

refactor(c/libuv):  Rename some func

refactor(c/libuv): Remove net go wrapper

refactor(c/libuv):  Add GetIoWatcherFd func
2024-08-07 14:49:13 +08:00
luoliwoshang
2ebb929e2c castdump:accessMap 2024-08-07 10:59:27 +08:00
xushiwei
b34334ba93 Merge pull request #669 from visualfc/abimap
ssa: fix abi map init
2024-08-07 07:54:27 +08:00
visualfc
05a01cd803 ssa: fix abi map init 2024-08-06 22:24:21 +08:00
xushiwei
9ac0c06f26 Merge pull request #667 from luoliwoshang/c/clang/type
c/clang:cursor enum & type kind
2024-08-06 22:00:27 +08:00
xushiwei
52af22b0e8 Merge pull request #660 from luoliwoshang/c/clang/fullast
c/clang:full ast dump
2024-08-06 21:56:06 +08:00
luoliwoshang
81cfc73b48 castdump:full ast dump 2024-08-06 21:37:00 +08:00
xushiwei
f892bfccdf Merge pull request #665 from xushiwei/hmac
library: crypto/hmac, internal/fmtsort
2024-08-06 18:56:37 +08:00
xushiwei
dbed8fefac library: crypto/hmac 2024-08-06 18:49:24 +08:00
luoliwoshang
ca14637909 c/clang:type kind 2024-08-06 18:23:31 +08:00
luoliwoshang
7db618fba5 c/clang:cursor enum & access pecifier 2024-08-06 18:23:19 +08:00
xushiwei
29c74c09ce library/README: crypto/hmac, crypto/subtle 2024-08-06 17:19:31 +08:00
xushiwei
a2b5b9f97e library (todo): crypto/hmac, internal/fmtsort 2024-08-06 17:03:22 +08:00
tsingbx
6a05aa4e53 llgo support crypto hmac (#663)
* llgo support crypto/hmac
2024-08-06 16:47:51 +08:00
xushiwei
43fd5d233a Merge pull request #662 from xushiwei/cast
TypedefDecl
2024-08-06 15:10:15 +08:00
xushiwei
0bd39ed035 TypedefDecl 2024-08-06 15:09:39 +08:00
xushiwei
1db8aad039 Merge pull request #661 from xushiwei/cast
llcppg: c/c++ ast
2024-08-06 11:00:51 +08:00
xushiwei
fb2d4267f5 llcppg: c/c++ ast 2024-08-06 11:00:13 +08:00
xushiwei
d7b203ae08 Merge pull request #655 from tsingbx/hmac2
add openssl hmac
2024-08-05 23:21:19 +08:00
xushiwei
3e07f2e3bc Merge pull request #656 from spongehah/golib/net-url
library: net/url
2024-08-05 20:11:31 +08:00
xushiwei
94cf6f6640 Merge pull request #658 from luoliwoshang/c/clang/marco
c/clang:marco content
2024-08-05 20:10:10 +08:00
luoliwoshang
6da5fe4317 c/clang:marco content 2024-08-05 19:38:29 +08:00
赵英杰
3a68dee850 library: net/url 2024-08-05 18:00:27 +08:00
tsingbx
2ccfa6a2e8 add EVP_sha1, EVP_sha224.... 2024-08-05 17:38:01 +08:00
tsingbx
f7bf671050 add openssl hmac
delete GetMD and HMAC function

delete macro

tidy code

add hmac
2024-08-05 16:57:47 +08:00
xushiwei
4bff9cc3df Merge pull request #653 from luoliwoshang/c/clang/marco
[wip] c/clang:marco info
2024-08-05 12:53:23 +08:00
xushiwei
13c68a0184 Merge pull request #654 from visualfc/fixstd
cpp/std: fix std::string def
2024-08-05 12:48:33 +08:00
visualfc
6d92949715 cpp/std: fix std::string def 2024-08-05 11:17:42 +08:00
luoliwoshang
5cf31bd3f3 c/clang:marco info 2024-08-04 17:35:15 +08:00
xushiwei
929d4c8d61 Merge pull request #647 from aofei/ssa-llgolink
ssa: add `llgo:link` support to `Builder.abiMthd`
2024-08-04 12:08:52 +08:00
Aofei Sheng
482f796bad ssa: add llgo:link support to Builder.abiMthd 2024-08-04 11:00:31 +08:00
xushiwei
d85f532ab1 Merge pull request #652 from xushiwei/q
c/os: llgoClearenv
2024-08-04 10:55:03 +08:00
xushiwei
b1654f7807 c/os: llgoClearenv 2024-08-04 10:54:41 +08:00
xushiwei
4f8526e527 Merge pull request #649 from aofei/clearenv
fix(c/os): add missing `clearenv` for macOS
2024-08-04 10:50:18 +08:00
Aofei Sheng
4b568fc469 fix(c/os): add missing clearenv for macOS 2024-08-04 09:58:01 +08:00
xushiwei
d06146ed97 Merge pull request #645 from spongehah/refactor/c-libuv-remove-go-wrapper
refactor(c-libuv): Added TODO(uid) comment & adjusted the position of Handle, Stream, Req, Write, Connect
2024-08-04 07:35:21 +08:00
xushiwei
8e0e809733 Merge pull request #648 from aofei/sync
perf(lib/sync): avoid using `defer`
2024-08-04 07:31:49 +08:00
Aofei Sheng
d1f33a6c4c perf(lib/sync): avoid using defer 2024-08-03 09:05:43 +08:00
赵英杰
b3e1b6fdbf refactor(c-libuv): Added TODO(uid) comment & adjusted the position of Handle, Stream, Req, Write, Connect 2024-08-03 00:25:14 +08:00
xushiwei
0bd259403c Merge pull request #644 from xushiwei/q
library: io/ioutil
2024-08-02 14:35:23 +08:00
xushiwei
c186846463 README: io/ioutil 2024-08-02 14:27:10 +08:00
xushiwei
5f92c3b3fc library: io/ioutil 2024-08-02 14:26:13 +08:00
xushiwei
0665091cef Merge pull request #641 from xushiwei/q
c/openssl: bio, pem, rsa
2024-08-01 23:03:48 +08:00
xushiwei
688d153427 c/openssl: bio, pem, rsa 2024-08-01 22:55:17 +08:00
xushiwei
bec5ba7a73 Merge pull request #638 from luoliwoshang/doc/c/visibile
doc/c:refine symbol visibility desc
2024-08-01 17:17:39 +08:00
xushiwei
acedf4d6a3 Merge pull request #613 from hackerchai/fix/c-libuv-struct
fix(c/libuv): Add libuv fs struct new func & fix async_fs demo
2024-08-01 17:13:51 +08:00
hackerchai
5dd5494f93 refactor(c/libuv): Adapt libuv.Fs struct 2024-08-01 10:57:59 +08:00
hackerchai
f253e4fabe Revert "fix(c/libuv): Add libuv fs struct new func"
This reverts commit 5fdb0a9634b5ecc29ddd50b6e5cce9938bcb7934.

# Conflicts:
#	c/libuv/_wrap/fs.c
#	c/libuv/fs.go
2024-08-01 10:57:58 +08:00
hackerchai
acd09d24d5 fix(c/libuv): Fix async_fs demo return 255 error & pointer not allocated error
Signed-off-by: hackerchai <i@hackerchai.com>

fix(c/libuv): Mv LLGoFiles declaration

Signed-off-by: hackerchai <i@hackerchai.com>

fix(c/libuv/demo): Fix return 255 error & pointer not allocated error

Signed-off-by: hackerchai <i@hackerchai.com>

refactor(c/libuv): Rewrite FsNew() logic

Signed-off-by: hackerchai <i@hackerchai.com>
2024-08-01 10:57:57 +08:00
hackerchai
ceac95c81a fix(c/libuv): Add libuv fs struct new func
Signed-off-by: hackerchai <i@hackerchai.com>
2024-08-01 10:54:01 +08:00
luoliwoshang
47a05d0ea2 doc/c:refine symbol visibility description 2024-08-01 09:54:48 +08:00
xushiwei
d2975479f2 Merge pull request #637 from xushiwei/q
README: math/big
2024-08-01 08:52:27 +08:00
xushiwei
3c238ffae7 Merge pull request #629 from luoliwoshang/doc/c
doc/c: fix incorrect Constructor and Destructor usage in bindings
2024-08-01 08:51:38 +08:00
xushiwei
69f8d1b717 README: math/big 2024-08-01 08:46:37 +08:00
xushiwei
45cd9e65d3 Merge pull request #634 from xushiwei/q
library: math/big.Int (mini-impl for _cmptest/bigintdemo)
2024-08-01 00:38:24 +08:00
xushiwei
2e4b1d8c2b library: math/big.Int (mini-impl for _cmptest/bigintdemo) 2024-08-01 00:32:21 +08:00
luoliwoshang
4e3b65188d doc/c:update implicit destructors description 2024-08-01 00:10:03 +08:00
xushiwei
0ab32e066b Merge pull request #633 from xushiwei/q
c/openssl: bignum, rsa
2024-07-31 23:21:25 +08:00
xushiwei
79d8b00b27 c/openssl: bignum, rsa 2024-07-31 22:34:13 +08:00
xushiwei
eb02c5a451 Merge pull request #631 from xushiwei/q
library: crypto, crypto/{sha1, sha256, sha512}
2024-07-31 19:04:24 +08:00
xushiwei
85509c777d library: crypto 2024-07-31 18:59:25 +08:00
xushiwei
27677f86e4 library: crypto/{sha1, sha256, sha512} 2024-07-31 18:55:46 +08:00
xushiwei
16174ca874 Merge pull request #627 from tsingbx/main
add crypto sha1,sha256,sha512
2024-07-31 18:39:54 +08:00
luoliwoshang
a4e9233231 doc/c:fix incorrect usage in construtors 2024-07-31 15:24:31 +08:00
luoliwoshang
4fdfafa17f doc/c:update destructor usage 2024-07-31 15:10:50 +08:00
tsingbx
c9a7dab419 delete sum 2024-07-31 14:56:03 +08:00
tsingbx
8882d75132 fix test error 2024-07-31 14:36:42 +08:00
tsingbx
f67b15b926 fix test fail 2024-07-31 14:28:15 +08:00
tsingbx
2d7958f726 add crypto sha1, sha256, sha512 2024-07-31 13:56:42 +08:00
xushiwei
36072584d0 Merge pull request #626 from aofei/goreleaser
fix(.goreleaser.yaml): correct ldflags for build version and time
2024-07-31 13:38:40 +08:00
Aofei Sheng
2119e52f55 fix(.goreleaser.yaml): correct ldflags for build version and time 2024-07-31 13:27:54 +08:00
xushiwei
ca1aa6b663 Merge pull request #625 from aofei/opt-deps
ci: install further optional dependencies for demos
2024-07-31 13:00:34 +08:00
xushiwei
10af671b76 Merge pull request #624 from xushiwei/q
library: go/parser (todo)
2024-07-31 13:00:09 +08:00
Aofei Sheng
a4ec6cce96 ci: install further optional dependencies for demos
Achieved 100% pass rate for demo tests, at least on macOS.
2024-07-31 12:34:51 +08:00
xushiwei
5082ba7102 library: go/parser (todo) 2024-07-31 12:29:09 +08:00
xushiwei
7405e7001b Merge pull request #623 from xushiwei/q
library: encoding, go/{token, scanner}
2024-07-31 11:56:09 +08:00
xushiwei
4c70651b81 library: go/{token, scanner} 2024-07-31 11:33:15 +08:00
xushiwei
21b5b60278 Merge pull request #622 from xushiwei/q
library: crypto/rand
2024-07-31 10:30:20 +08:00
xushiwei
0abc5ec452 README: crypto/rand 2024-07-31 10:30:04 +08:00
xushiwei
b1d2d620fa Merge pull request #621 from aofei/deps
deps: require zlib 1.2+
2024-07-31 10:27:47 +08:00
xushiwei
af6e4abe84 library: crypto/rand 2024-07-31 10:26:18 +08:00
Aofei Sheng
45b4315842 deps: require zlib 1.2+ 2024-07-31 09:52:48 +08:00
xushiwei
d2cb96a9e5 Merge pull request #620 from xushiwei/q
c/openssl: rand
2024-07-31 01:33:10 +08:00
xushiwei
a3ff845a14 c/openssl: rand 2024-07-31 01:27:08 +08:00
xushiwei
621f05c687 Merge pull request #566 from luoliwoshang/llcppg/symg/header
[wip] llcppg/symg
2024-07-30 22:11:31 +08:00
xushiwei
daf97eabab Merge pull request #618 from xushiwei/q
README: c/openssl
2024-07-30 22:01:20 +08:00
xushiwei
ee3d11cb53 README: c/openssl 2024-07-30 21:56:19 +08:00
xushiwei
1bc7e5e0a5 Merge pull request #617 from xushiwei/q
library: math/rand
2024-07-30 21:50:22 +08:00
xushiwei
9280d23b1a Merge pull request #616 from tsingbx/main
add openssl sha1,sha256,sha512
2024-07-30 21:46:21 +08:00
xushiwei
cacd52f81d library: math/rand 2024-07-30 21:41:26 +08:00
tsingbx
95f64761ca add SHA224_CTX, SHA384_CTX 2024-07-30 21:24:03 +08:00
tsingbx
6e24792b9b Remove redundant code and add examples 2024-07-30 21:06:17 +08:00
luoliwoshang
9afe26f1d6 c/clang/symg:keep user edit symbol 2024-07-30 20:50:22 +08:00
xushiwei
e7d959da90 Merge pull request #614 from aofei/min-max
ssa: add support for `min` and `max` built-in functions
2024-07-30 19:59:33 +08:00
xushiwei
c3f0867d2c Merge pull request #615 from xushiwei/q
library: hash, hash/{adler32, crc32, crc64}; c/zlib: crc32/adler32
2024-07-30 19:44:17 +08:00
xushiwei
1eaf124d4e library: hash/{crc32, adler32} 2024-07-30 19:36:36 +08:00
tsingbx
03076bdc76 Merge branch 'main' of https://github.com/tsingbx/tsingbx-llgo 2024-07-30 19:20:54 +08:00
tsingbx
cd32d6debe add openssl sha1,sha256,sha512 2024-07-30 19:20:15 +08:00
xushiwei
3212f059ff c/zlib: crc32/adler32 2024-07-30 18:53:55 +08:00
tsingbx
9ae4b93083 add openssl sha1,sha256,sha512 2024-07-30 18:32:27 +08:00
xushiwei
aae7af2194 library: hash, hash/crc64 2024-07-30 18:26:33 +08:00
luoliwoshang
63f4c73ef0 c/clang/symg:remove example config file 2024-07-30 17:25:33 +08:00
luoliwoshang
f93d3381e0 c/clang/symg:move get conf func 2024-07-30 17:25:33 +08:00
luoliwoshang
099c80e04b c/clang/symg: use xtool/nm to parse symbol 2024-07-30 17:25:33 +08:00
luoliwoshang
14face336e c/clang/symg:remove JSONPath 2024-07-30 17:25:33 +08:00
luoliwoshang
67b10d8d38 c/clang/symg:refine config usage 2024-07-30 17:25:33 +08:00
luoliwoshang
1219230168 c/clang/symg:genSymbolTableFile 2024-07-30 17:25:33 +08:00
luoliwoshang
8d840e694d c/clang/symg:remove unuse comment 2024-07-30 17:25:33 +08:00
luoliwoshang
87382aad4d c/clang/symg:use unsafe.String to avoid memory copy 2024-07-30 17:25:33 +08:00
luoliwoshang
aca3a05222 c/clang/symg:abstract json item fetch 2024-07-30 17:25:33 +08:00
luoliwoshang
84ca145663 c/clang/symg:merge llcppinfofetch to llcppsymg 2024-07-30 17:25:33 +08:00
luoliwoshang
01d0338851 c/clang/symg:use llvm to demangle name 2024-07-30 17:25:33 +08:00
luoliwoshang
f427c0532d c/clang/symg:use cjson get conf 2024-07-30 17:25:33 +08:00
luoliwoshang
c8532a548c c/clang/symg:abstract common type 2024-07-30 17:25:33 +08:00
luoliwoshang
1e3aef5b94 c/clang/symg:remove chinese 2024-07-30 17:25:33 +08:00
morpingsss
0d3180271b feat(llgo/chore/llcppg): add JSONPath 2024-07-30 17:25:33 +08:00
luoliwoshang
f0d17b13f2 c/clang/symg:multiple header file 2024-07-30 17:25:33 +08:00
morpingsss
9a46301d46 feat(llgo/xtools): delete chinese 2024-07-30 17:25:33 +08:00
luoliwoshang
3bd609ee41 c/clang/symg:filter unuse file 2024-07-30 17:25:33 +08:00
luoliwoshang
2c7f0e8583 c/clang/symg:get constructor & destructor 2024-07-30 17:25:33 +08:00
morpingsss
ce36a25ba3 feat(llgo/xtools): add TrimPrefix 2024-07-30 17:25:33 +08:00
luoliwoshang
c53484f92e c/clang/symg:normal gen json 2024-07-30 17:25:33 +08:00
luoliwoshang
f391ccb8e8 c/clang/symg/header:get func info 2024-07-30 17:25:33 +08:00
morpingsss
a96d6a8148 feat(llgo/xtools): add llcppsymg.go 2024-07-30 17:25:33 +08:00
xushiwei
bdca09007d Merge pull request #612 from xushiwei/q
library: os.ReadFile
2024-07-30 17:18:28 +08:00
xushiwei
c0e84043c9 library: os.ReadFile 2024-07-30 17:14:59 +08:00
Aofei Sheng
0a884df74f ssa: add support for min and max built-in functions 2024-07-30 17:09:41 +08:00
xushiwei
519b14d506 Merge pull request #611 from aofei/openssl
deps: require OpenSSL 3.0+
2024-07-30 15:35:08 +08:00
Aofei Sheng
f008a65d91 deps: require OpenSSL 3.0+ 2024-07-30 14:17:45 +08:00
xushiwei
61bb70cd30 Merge pull request #610 from aofei/build
build: replicate macOS `-dead_strip` optimization on Linux
2024-07-30 10:18:27 +08:00
Aofei Sheng
68fa3dadb0 build: replicate macOS -dead_strip optimization on Linux
Added `-fdata-sections` and `-ffunction-sections` compiler flags to work
with `--gc-sections` on Linux. This combination achieves similar dead
code elimination as macOS's `-dead_strip`, reducing binary size and
resolving undefined symbol issues. Ensures consistent optimization
across macOS and Linux builds.
2024-07-30 08:52:29 +08:00
xushiwei
eb38d03976 Merge pull request #608 from xushiwei/q
library: crypto/md5
2024-07-30 02:11:38 +08:00
xushiwei
d480bb3ecd library: crypto/md5 2024-07-30 02:07:19 +08:00
xushiwei
dfdb6fa1a6 Merge pull request #607 from xushiwei/q
library: c/openssl
2024-07-30 01:40:46 +08:00
xushiwei
42352d9f57 library: c/openssl 2024-07-30 01:35:49 +08:00
xushiwei
eae1c5db70 Merge pull request #606 from xushiwei/q
library: bufio, encoding/csv
2024-07-30 00:48:05 +08:00
xushiwei
cc37097164 library: bufio, encoding/csv 2024-07-30 00:44:03 +08:00
xushiwei
6597cc9ce8 Merge pull request #605 from aisk/py-dict
feat(py): add some basic dict methods
2024-07-30 00:40:06 +08:00
xushiwei
b3f752d46c Merge pull request #604 from xushiwei/q
library: encoding/{binary, hex, base32, base64}
2024-07-30 00:38:12 +08:00
xushiwei
679e2d0f6b library: encoding/hex 2024-07-30 00:33:44 +08:00
AN Long
4607079ca9 feat(python): Add some basic dict methods 2024-07-30 00:33:21 +08:00
xushiwei
ad1a42d6a5 library: encoding/base32 2024-07-30 00:30:58 +08:00
xushiwei
afdf31a66c library: encoding/{binary, base64} 2024-07-30 00:28:04 +08:00
xushiwei
37956e2f05 Merge pull request #600 from visualfc/closureconv
ssa: closure changeType check convert
2024-07-30 00:17:35 +08:00
visualfc
dc6aa66f9a ssa: closure changeType check convert 2024-07-29 20:53:13 +08:00
xushiwei
f16f16c15e Update How-to-support-a-C&C++-Library.md 2024-07-29 19:50:23 +08:00
xushiwei
3b95cbd960 Merge pull request #599 from aofei/sigsetjmp
ssa: fix `Builder.Sigsetjmp` for Linux
2024-07-29 17:54:19 +08:00
Aofei Sheng
3b5e8edd37 ssa: fix Builder.Sigsetjmp for Linux
This follows up on #597.
2024-07-29 16:52:24 +08:00
xushiwei
5f4571e895 Merge pull request #602 from xushiwei/q
library: bytes, regexp, regexp/syntax
2024-07-29 16:37:42 +08:00
xushiwei
2d5e991eaf library: bytes, regexp, regexp/syntax 2024-07-29 16:31:59 +08:00
xushiwei
7ba8bb4405 Merge pull request #601 from aofei/python3.12
installation: require Python 3.12
2024-07-29 15:22:34 +08:00
Aofei Sheng
82aa181540 installation: require Python 3.12 2024-07-29 14:34:40 +08:00
xushiwei
1a3e17bae8 Merge pull request #598 from xushiwei/q
cmptest: regexdemo (todo)
2024-07-29 11:49:47 +08:00
xushiwei
e0e3664fdb cmptest: regexdemo (todo) 2024-07-29 11:44:49 +08:00
xushiwei
23bfaf1ba2 Merge pull request #597 from aofei/build
build: fix `sigsetjmp` issues and ensure required libs on Linux
2024-07-29 11:26:03 +08:00
Aofei Sheng
e7d72b6f53 build: fix sigsetjmp issues and ensure required libs on Linux
1. Handle `sigsetjmp` platform differences:
   - Separate `sigsetjmp` linkage to platform-specific files.
   - Use `__sigsetjmp` on Linux to handle `sigsetjmp` being a macro.
   - Maintain original implementation for Darwin.

2. Ensure linking of required libs:
   - Explicitly link against fundamental libs (e.g., libm, libatomic).
   - Address the fact that typical Linux linkers don't link these by
     default.
2024-07-29 11:16:04 +08:00
xushiwei
eab26deab9 Merge pull request #572 from hackerchai/fix/general-fix-libuv
fix(c/libuv): Fix return type FsType & struct rename
2024-07-29 11:12:49 +08:00
xushiwei
49540dbe5e Merge pull request #596 from xushiwei/q
library: os.Expand
2024-07-29 11:10:16 +08:00
xushiwei
cbd891785e library: os.Expand 2024-07-29 11:06:33 +08:00
hackerchai
b1cc732cb2 refactor(c/libuv): Rename UvPipe & remove unused structs
Signed-off-by: hackerchai <i@hackerchai.com>
2024-07-29 09:59:46 +08:00
xushiwei
b3b4f55c68 Merge pull request #594 from xushiwei/q
cpp/std: support nogc
2024-07-29 09:01:30 +08:00
xushiwei
8b6b039c13 cpp/std: support nogc 2024-07-29 08:55:27 +08:00
xushiwei
9dca62ff8b Merge pull request #593 from xushiwei/q
library: path, path/filepath
2024-07-29 08:39:28 +08:00
xushiwei
e0892fcebb library: path, path/filepath 2024-07-29 08:38:56 +08:00
xushiwei
adf1443105 Merge pull request #592 from xushiwei/q
cmptest: jsondemo (todo)
2024-07-29 02:04:43 +08:00
xushiwei
53c2558d26 cmptest: jsondemo (todo) 2024-07-29 01:56:39 +08:00
xushiwei
a5ea240793 Merge pull request #591 from xushiwei/q
reflect.Value: Uint fix
2024-07-29 01:31:28 +08:00
xushiwei
4cd1629118 reflect.Value: Uint fix 2024-07-29 01:26:56 +08:00
xushiwei
ce32a73e86 Merge pull request #590 from xushiwei/q
osexec: llvm bindir
2024-07-29 00:23:43 +08:00
xushiwei
8a13fc7cd9 osexec: llvm bindir 2024-07-29 00:17:53 +08:00
xushiwei
708de50887 syscall.forkAndExecInChild fix: os.Fcntl/Dup2 retval 2024-07-29 00:14:01 +08:00
xushiwei
4df478316c library: fmt.(*pp).doPrint; syscall.forkAndExecInChild 2024-07-29 00:02:30 +08:00
xushiwei
a5dff9fb15 library: os.ProcessState.String 2024-07-28 23:53:22 +08:00
xushiwei
b51f4d53b6 Merge pull request #589 from xushiwei/q
os.Pipe, syscall.CloseOnExec
2024-07-28 23:31:01 +08:00
xushiwei
7d045842dd library: syscall.CloseOnExec 2024-07-28 23:15:20 +08:00
xushiwei
a9ece9e49d library: os.Pipe 2024-07-28 23:09:21 +08:00
xushiwei
e6da067cf8 Merge pull request #588 from xushiwei/q
llgo/xtool/nm/nmindex
2024-07-28 22:55:38 +08:00
xushiwei
bae40c82b9 llgo/xtool/nm/nmindex 2024-07-28 22:51:35 +08:00
xushiwei
651edf5bc0 Merge pull request #587 from xushiwei/q
osexec demo
2024-07-28 22:32:05 +08:00
xushiwei
3a8642b1e0 syscall: forkAndExecInChild 2024-07-28 22:27:26 +08:00
xushiwei
09b6b9259c library: exec.Cmd.environ 2024-07-28 22:22:28 +08:00
xushiwei
907f326788 library: os.File.Close 2024-07-28 22:19:40 +08:00
xushiwei
4a350d8ad9 Merge pull request #586 from xushiwei/q
compileFuncDecl todo: change ssa.If to ssa.Jump for func init
2024-07-28 21:58:07 +08:00
xushiwei
3881db0b4e compileFuncDecl todo: change ssa.If to ssa.Jump for func init 2024-07-28 21:57:32 +08:00
xushiwei
9edae3e877 Merge pull request #582 from visualfc/init.patch
fix pkg init hasPatch && patch io.pipe
2024-07-28 21:13:50 +08:00
xushiwei
236208e393 Merge pull request #585 from xushiwei/q
runtime.Panic: mv error/Stringer to printany
2024-07-28 20:41:20 +08:00
xushiwei
4ff98de707 Merge pull request #584 from luoliwoshang/c/lua
c/lua:metatable & coroutine
2024-07-28 20:40:23 +08:00
xushiwei
54964629fe runtime.Panic: mv error/Stringer to printany 2024-07-28 20:31:48 +08:00
luoliwoshang
072f606784 c/lua:coroutine 2024-07-28 20:28:28 +08:00
xushiwei
21d2338ec1 Merge pull request #583 from xushiwei/q
fix panic in defer
2024-07-28 20:07:30 +08:00
xushiwei
0d468e0df4 cl/_testgo: defer5 2024-07-28 20:00:53 +08:00
xushiwei
5007d49c83 ssa: endDefer 2024-07-28 19:53:04 +08:00
luoliwoshang
35ba69a175 c/lua:metatable 2024-07-28 19:32:19 +08:00
xushiwei
fa0ce2a14c ssa: panicBlk use IndirectJump 2024-07-28 18:57:46 +08:00
xushiwei
389750d7d8 ssa: panicBlk (todo) 2024-07-28 18:51:07 +08:00
visualfc
6c7db7ad23 build: patch io.pipe 2024-07-28 17:01:34 +08:00
visualfc
2986426251 cl: fix pkg init hasPatch 2024-07-28 16:52:03 +08:00
xushiwei
56444ebcaf Merge pull request #581 from visualfc/init
cl: afterInit skip pkgHasPatch
2024-07-28 11:33:57 +08:00
visualfc
c63a1978cb cl: afterInit skip pkgHasPatch 2024-07-28 11:29:22 +08:00
xushiwei
9d9e998d49 Update README.md 2024-07-28 09:29:08 +08:00
xushiwei
f7c991fa9a Merge pull request #580 from visualfc/afterinit
cl: after init check hasPatch
2024-07-28 09:17:59 +08:00
visualfc
4d14fbb1e7 cl: after init check hasPatch 2024-07-27 21:20:06 +08:00
xushiwei
5428730e7a Merge pull request #579 from xushiwei/q
_cmptest: pipedemo
2024-07-27 16:03:58 +08:00
xushiwei
bf773df099 _cmptest: pipedemo 2024-07-27 16:03:22 +08:00
xushiwei
6dea5100b1 Merge pull request #578 from visualfc/overlay
internal/build: add io.pipe for overlay
2024-07-27 15:56:57 +08:00
visualfc
aa55f4dceb internal/build: add io.pipe for overlay 2024-07-27 12:32:33 +08:00
xushiwei
516e92926a Merge pull request #576 from xushiwei/q
c/pthread/sync: use go:linkname for internal func
2024-07-27 09:32:31 +08:00
xushiwei
2cd9994321 C.wrap_pthread_mutex_lock 2024-07-27 09:28:09 +08:00
xushiwei
e69306a2ba c/pthread/sync: use go:linkname for internal func 2024-07-27 09:11:38 +08:00
xushiwei
93ecd031bd Merge pull request #573 from visualfc/selectop
internal/runtime: fix endSelect
2024-07-27 08:20:52 +08:00
visualfc
4eaf69dfa7 internal/runtime: fix endSelect 2024-07-27 07:19:45 +08:00
hackerchai
bc93bda1b7 fix(c/libuv): rename UvFile into File & remove unused File struct
Signed-off-by: hackerchai <i@hackerchai.com>
2024-07-26 19:04:49 +08:00
hackerchai
6923f0df2a fix(c/libuv): fix return type FsType
Signed-off-by: hackerchai <i@hackerchai.com>
2024-07-26 19:01:53 +08:00
170 changed files with 11943 additions and 2902 deletions

View File

@@ -14,30 +14,58 @@ jobs:
test: test:
strategy: strategy:
matrix: matrix:
os: [macos-latest, ubuntu-latest] os:
# os: [macos-latest] - macos-latest
- ubuntu-24.04
llvm: [18] llvm: [18]
runs-on: ${{ matrix.os }} runs-on: ${{matrix.os}}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Update Homebrew - name: Install dependencies
# needed as long as LLVM 18 is still fresh
if: matrix.llvm == 18 && startsWith(matrix.os, 'macos')
run: brew update
- name: Install LLVM ${{ matrix.llvm }} and bdw-gc
if: startsWith(matrix.os, 'macos') if: startsWith(matrix.os, 'macos')
run: | run: |
HOMEBREW_NO_AUTO_UPDATE=1 brew install llvm@${{ matrix.llvm }} bdw-gc brew update
echo `brew --prefix llvm@${{ matrix.llvm }}`/bin >> $GITHUB_PATH brew install llvm@${{matrix.llvm}} pkg-config bdw-gc openssl
- name: Install LLVM ${{ matrix.llvm }} and libgc-dev 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') if: startsWith(matrix.os, 'ubuntu')
run: | 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 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 - 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-${{ matrix.llvm }}-dev clang-${{ matrix.llvm }} lld-${{ matrix.llvm }} pkg-config libgc-dev libcjson-dev libsqlite3-dev python3.11-dev 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 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: |
@@ -54,27 +82,25 @@ jobs:
run: go build -v ./... run: go build -v ./...
- name: Test - name: Test
if: matrix.os != 'macos-latest' if: ${{!startsWith(matrix.os, 'macos')}}
run: go test -v ./... run: go test -v ./...
- name: Test with coverage - name: Test with coverage
if: matrix.os == 'macos-latest' 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 - name: Install
run: go install ./... run: go install ./...
- name: LLGO tests - name: LLGO tests
if: matrix.os != 'ubuntu-latest' if: ${{!startsWith(matrix.os, 'ubuntu')}}
run: | run: |
echo "Test result on ${{ matrix.os }} with LLVM ${{ matrix.llvm }}" > result.md echo "Test result on ${{matrix.os}} with LLVM ${{matrix.llvm}}" > result.md
LLGOROOT=$PWD bash .github/workflows/test_llgo.sh bash .github/workflows/test_llgo.sh
- name: Test _demo and _pydemo - name: Test demos
run: | continue-on-error: true
set +e run: bash .github/workflows/test_demo.sh
LLGOROOT=$PWD bash .github/workflows/test_demo.sh
exit 0
- name: Show test result - name: Show test result
run: cat result.md run: cat result.md
@@ -84,10 +110,10 @@ jobs:
if: false if: false
with: with:
filePath: result.md filePath: result.md
comment_tag: test-result-on-${{ matrix.os }}-with-llvm-${{ matrix.llvm }} 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@v4
with: with:
token: ${{ secrets.CODECOV_TOKEN }} token: ${{secrets.CODECOV_TOKEN}}
slug: goplus/llgo slug: goplus/llgo

View File

@@ -1,4 +1,5 @@
#!/bin/bash #!/bin/bash
set -e
# llgo run subdirectories under _demo and _pydemo # llgo run subdirectories under _demo and _pydemo
total=0 total=0
@@ -8,7 +9,7 @@ for d in ./_demo/* ./_pydemo/*; do
total=$((total+1)) total=$((total+1))
if [ -d "$d" ]; then if [ -d "$d" ]; then
echo "Testing $d" echo "Testing $d"
if ! llgo run "$d"; then if ! (cd "$d" && llgo run .); then
echo "FAIL" echo "FAIL"
failed=$((failed+1)) failed=$((failed+1))
failed_cases="$failed_cases\n* :x: $d" failed_cases="$failed_cases\n* :x: $d"

View File

@@ -1,8 +1,6 @@
#!/bin/bash #!/bin/bash
set -e set -e
export LLGOROOT=$PWD
testcmd=/tmp/test testcmd=/tmp/test
llgo build -o $testcmd ./c/bdwgc/_test llgo build -o $testcmd ./c/bdwgc/_test
cases=$($testcmd) cases=$($testcmd)

View File

@@ -20,8 +20,8 @@ builds:
flags: flags:
- -tags=darwin,amd64,byollvm - -tags=darwin,amd64,byollvm
ldflags: ldflags:
- -X github.com/goplus/llgo/xtool/env.buildVersion=v{{.Version}} - -X github.com/goplus/llgo/x/env.buildVersion=v{{.Version}}
- -X github.com/goplus/llgo/xtool/env.buildDate={{.Date}} - -X github.com/goplus/llgo/x/env.buildTime={{.Date}}
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/local/opt/llvm@18/bin/llvm-config - -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/local/opt/llvm@18/bin/llvm-config
env: env:
- CC=o64-clang - CC=o64-clang
@@ -36,8 +36,8 @@ builds:
flags: flags:
- -tags=darwin,arm64,byollvm - -tags=darwin,arm64,byollvm
ldflags: ldflags:
- -X github.com/goplus/llgo/xtool/env.buildVersion=v{{.Version}} - -X github.com/goplus/llgo/x/env.buildVersion=v{{.Version}}
- -X github.com/goplus/llgo/xtool/env.buildDate={{.Date}} - -X github.com/goplus/llgo/x/env.buildTime={{.Date}}
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/opt/homebrew/opt/llvm@18/bin/llvm-config - -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/opt/homebrew/opt/llvm@18/bin/llvm-config
env: env:
- CC=oa64-clang - CC=oa64-clang
@@ -52,8 +52,8 @@ builds:
flags: flags:
- -tags=linux,amd64,byollvm - -tags=linux,amd64,byollvm
ldflags: ldflags:
- -X github.com/goplus/llgo/xtool/env.buildVersion=v{{.Version}} - -X github.com/goplus/llgo/x/env.buildVersion=v{{.Version}}
- -X github.com/goplus/llgo/xtool/env.buildDate={{.Date}} - -X github.com/goplus/llgo/x/env.buildTime={{.Date}}
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/lib/llvm-18/bin/llvm-config - -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/lib/llvm-18/bin/llvm-config
env: env:
- CC=x86_64-linux-gnu-gcc - CC=x86_64-linux-gnu-gcc
@@ -68,8 +68,8 @@ builds:
flags: flags:
- -tags=linux,arm64,byollvm - -tags=linux,arm64,byollvm
ldflags: ldflags:
- -X github.com/goplus/llgo/xtool/env.buildVersion=v{{.Version}} - -X github.com/goplus/llgo/x/env.buildVersion=v{{.Version}}
- -X github.com/goplus/llgo/xtool/env.buildDate={{.Date}} - -X github.com/goplus/llgo/x/env.buildTime={{.Date}}
- -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/lib/llvm-18/bin/llvm-config - -X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=/usr/lib/llvm-18/bin/llvm-config
env: env:
- CC=aarch64-linux-gnu-gcc - CC=aarch64-linux-gnu-gcc

View File

@@ -218,6 +218,7 @@ The currently supported libraries include:
* [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)
* [c/neco](https://pkg.go.dev/github.com/goplus/llgo/c/neco) * [c/neco](https://pkg.go.dev/github.com/goplus/llgo/c/neco)
* [c/openssl](https://pkg.go.dev/github.com/goplus/llgo/c/openssl)
* [c/raylib](https://pkg.go.dev/github.com/goplus/llgo/c/raylib) * [c/raylib](https://pkg.go.dev/github.com/goplus/llgo/c/raylib)
* [c/sqlite](https://pkg.go.dev/github.com/goplus/llgo/c/sqlite) * [c/sqlite](https://pkg.go.dev/github.com/goplus/llgo/c/sqlite)
* [c/zlib](https://pkg.go.dev/github.com/goplus/llgo/c/zlib) * [c/zlib](https://pkg.go.dev/github.com/goplus/llgo/c/zlib)
@@ -243,7 +244,7 @@ All Go syntax (not including `cgo`) is already supported. Here are some examples
* [goroutine](_demo/goroutine/goroutine.go): goroutine demo * [goroutine](_demo/goroutine/goroutine.go): goroutine demo
## Defer ### Defer
LLGo `defer` does not support usage in loops. This is not a bug but a feature, because we think that using `defer` in a loop is a very unrecommended practice. LLGo `defer` does not support usage in loops. This is not a bug but a feature, because we think that using `defer` in a loop is a very unrecommended practice.
@@ -268,17 +269,25 @@ Here are the Go packages that can be imported correctly:
* [unicode/utf8](https://pkg.go.dev/unicode/utf8) * [unicode/utf8](https://pkg.go.dev/unicode/utf8)
* [unicode/utf16](https://pkg.go.dev/unicode/utf16) * [unicode/utf16](https://pkg.go.dev/unicode/utf16)
* [math](https://pkg.go.dev/math) * [math](https://pkg.go.dev/math)
* [math/big](https://pkg.go.dev/math/big) (partially)
* [math/bits](https://pkg.go.dev/math/bits) * [math/bits](https://pkg.go.dev/math/bits)
* [math/cmplx](https://pkg.go.dev/math/cmplx) * [math/cmplx](https://pkg.go.dev/math/cmplx)
* [math/rand](https://pkg.go.dev/math/rand)
* [net/url](https://pkg.go.dev/net/url)
* [errors](https://pkg.go.dev/errors) * [errors](https://pkg.go.dev/errors)
* [context](https://pkg.go.dev/context) * [context](https://pkg.go.dev/context)
* [io](https://pkg.go.dev/io) * [io](https://pkg.go.dev/io)
* [io/fs](https://pkg.go.dev/io/fs) * [io/fs](https://pkg.go.dev/io/fs)
* [io/ioutil](https://pkg.go.dev/io/ioutil)
* [log](https://pkg.go.dev/log) * [log](https://pkg.go.dev/log)
* [flag](https://pkg.go.dev/flag) * [flag](https://pkg.go.dev/flag)
* [sort](https://pkg.go.dev/sort) * [sort](https://pkg.go.dev/sort)
* [strconv](https://pkg.go.dev/strconv) * [bytes](https://pkg.go.dev/bytes)
* [bufio](https://pkg.go.dev/bufio)
* [strings](https://pkg.go.dev/strings) * [strings](https://pkg.go.dev/strings)
* [strconv](https://pkg.go.dev/strconv)
* [path](https://pkg.go.dev/path)
* [path/filepath](https://pkg.go.dev/path/filepath)
* [sync/atomic](https://pkg.go.dev/sync/atomic) * [sync/atomic](https://pkg.go.dev/sync/atomic)
* [sync](https://pkg.go.dev/sync) (partially) * [sync](https://pkg.go.dev/sync) (partially)
* [syscall](https://pkg.go.dev/syscall) (partially) * [syscall](https://pkg.go.dev/syscall) (partially)
@@ -288,19 +297,41 @@ Here are the Go packages that can be imported correctly:
* [fmt](https://pkg.go.dev/fmt) (partially) * [fmt](https://pkg.go.dev/fmt) (partially)
* [reflect](https://pkg.go.dev/reflect) (partially) * [reflect](https://pkg.go.dev/reflect) (partially)
* [time](https://pkg.go.dev/time) (partially) * [time](https://pkg.go.dev/time) (partially)
* [encoding](https://pkg.go.dev/encoding)
* [encoding/binary](https://pkg.go.dev/encoding/binary)
* [encoding/hex](https://pkg.go.dev/encoding/hex)
* [encoding/base32](https://pkg.go.dev/encoding/base32)
* [encoding/base64](https://pkg.go.dev/encoding/base64)
* [encoding/csv](https://pkg.go.dev/encoding/csv)
* [hash](https://pkg.go.dev/hash)
* [hash/adler32](https://pkg.go.dev/hash/adler32)
* [hash/crc32](https://pkg.go.dev/hash/crc32) (partially)
* [hash/crc64](https://pkg.go.dev/hash/crc64)
* [crypto](https://pkg.go.dev/crypto)
* [crypto/md5](https://pkg.go.dev/crypto/md5)
* [crypto/sha1](https://pkg.go.dev/crypto/sha1)
* [crypto/sha256](https://pkg.go.dev/crypto/sha256)
* [crypto/sha512](https://pkg.go.dev/crypto/sha512) (partially)
* [crypto/hmac](https://pkg.go.dev/crypto/hmac) (partially)
* [crypto/rand](https://pkg.go.dev/crypto/rand) (partially)
* [crypto/subtle](https://pkg.go.dev/crypto/subtle) (partially)
* [regexp](https://pkg.go.dev/regexp)
* [regexp/syntax](https://pkg.go.dev/regexp/syntax)
* [go/token](https://pkg.go.dev/go/token)
* [go/scanner](https://pkg.go.dev/go/scanner)
## Dependencies ## Dependencies
- [Go 1.20+](https://go.dev) (build only) - [Go 1.20+](https://go.dev)
- [LLVM 18](https://llvm.org) - [LLVM 18](https://llvm.org)
- [LLD 18](https://lld.llvm.org) - [LLD 18](https://lld.llvm.org)
- [Clang 18](https://clang.llvm.org) - [Clang 18](https://clang.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/)
- [cJSON 1.7+](https://github.com/DaveGamble/cJSON) (optional, for [github.com/goplus/llgo/c/cjson](https://pkg.go.dev/github.com/goplus/llgo/c/cjson)) - [OpenSSL 3.0+](https://www.openssl.org/)
- [SQLite 3](https://www.sqlite.org) (optional, for [github.com/goplus/llgo/c/sqlite](https://pkg.go.dev/github.com/goplus/llgo/c/sqlite)) - [zlib 1.2+](https://www.zlib.net)
- [Python 3.11+](https://www.python.org) (optional, for [github.com/goplus/llgo/py](https://pkg.go.dev/github.com/goplus/llgo/py)) - [Python 3.12+](https://www.python.org) (optional, for [github.com/goplus/llgo/py](https://pkg.go.dev/github.com/goplus/llgo/py))
## How to install ## How to install
@@ -309,10 +340,9 @@ Follow these steps to generate the `llgo` command (its usage is the same as the
### on macOS ### on macOS
```sh ```sh
brew update # execute if needed brew update
brew install llvm@18 pkg-config libgc brew install llvm@18 pkg-config bdw-gc openssl
brew install cjson sqlite python@3.12 # optional brew install python@3.12 # optional
export PATH=$(brew --prefix llvm@18)/bin:$PATH # you may want to add this to your shell RC file, e.g. ~/.zshrc
go install -v github.com/goplus/llgo/cmd/llgo@latest go install -v github.com/goplus/llgo/cmd/llgo@latest
``` ```
@@ -321,10 +351,9 @@ go install -v github.com/goplus/llgo/cmd/llgo@latest
```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 # execute if needed sudo apt-get update
sudo apt-get install -y llvm-18-dev clang-18 lld-18 pkg-config libgc-dev 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 libcjson-dev libsqlite3-dev python3.12-dev # optional sudo apt-get install -y python3.12-dev # optional
export PATH=/usr/lib/llvm-18/bin:$PATH # you may want to add this to your shell RC file, e.g. ~/.bashrc
go install -v github.com/goplus/llgo/cmd/llgo@latest go install -v github.com/goplus/llgo/cmd/llgo@latest
``` ```

View File

@@ -0,0 +1,47 @@
package main
import (
"fmt"
"math"
"math/big"
)
func main() {
// We'll do computations with 200 bits of precision in the mantissa.
const prec = 200
// Compute the square root of 2 using Newton's Method. We start with
// an initial estimate for sqrt(2), and then iterate:
// x_{n+1} = 1/2 * ( x_n + (2.0 / x_n) )
// Since Newton's Method doubles the number of correct digits at each
// iteration, we need at least log_2(prec) steps.
steps := int(math.Log2(prec))
// Initialize values we need for the computation.
two := new(big.Float).SetPrec(prec).SetInt64(2)
half := new(big.Float).SetPrec(prec).SetFloat64(0.5)
// Use 1 as the initial estimate.
x := new(big.Float).SetPrec(prec).SetInt64(1)
// We use t as a temporary variable. There's no need to set its precision
// since big.Float values with unset (== 0) precision automatically assume
// the largest precision of the arguments when used as the result (receiver)
// of a big.Float operation.
t := new(big.Float)
// Iterate.
for i := 0; i <= steps; i++ {
t.Quo(two, x) // t = 2.0 / x_n
t.Add(x, t) // t = x_n + (2.0 / x_n)
x.Mul(half, t) // x_{n+1} = 0.5 * t
}
// We can use the usual fmt.Printf verbs since big.Float implements fmt.Formatter
fmt.Printf("sqrt(2) = %.50f\n", x)
// Print the error between 2 and x*x.
t.Mul(x, x) // t = x*x
fmt.Printf("error = %e\n", t.Sub(two, t))
}

View File

@@ -0,0 +1,34 @@
package main
import (
"fmt"
"go/parser"
"go/token"
)
func main() {
fset := token.NewFileSet() // positions are relative to fset
src := `package foo
import (
"fmt"
"time"
)
func bar() {
fmt.Println(time.Now())
}`
// Parse src but stop after processing the imports.
f, err := parser.ParseFile(fset, "", src, parser.ImportsOnly)
if err != nil {
fmt.Println(err)
return
}
// Print the imports from the file's AST.
for _, s := range f.Imports {
fmt.Println(s.Path.Value)
}
}

View File

@@ -0,0 +1,16 @@
package main
import (
"encoding/json"
"fmt"
"unsafe"
)
func main() {
s := `{"name":"math","items":[{"name":"sqrt","sig":"(x, /)"},{"name":"pi"}]}`
data := unsafe.Slice(unsafe.StringData(s), len(s))
var v any
json.Unmarshal(data, &v)
b, _ := json.MarshalIndent(v, "", " ")
fmt.Println(string(b))
}

View File

@@ -13,7 +13,7 @@ func main() {
select { select {
case m := <-c: case m := <-c:
handle(m) handle(m)
case <-time.After(10 * time.Second): case <-time.After(time.Second / 10):
fmt.Println("timed out") fmt.Println("timed out")
} }
} }

View File

@@ -0,0 +1,48 @@
package main
import (
"encoding/base32"
"encoding/base64"
"encoding/hex"
"fmt"
"log"
)
func base64Demo() {
msg := "Hello, 世界"
encoded := base64.StdEncoding.EncodeToString([]byte(msg))
fmt.Println(encoded)
decoded, err := base64.StdEncoding.DecodeString(encoded)
if err != nil {
fmt.Println("decode error:", err)
return
}
fmt.Println(string(decoded))
}
func base32Demo() {
str := "JBSWY3DPFQQHO33SNRSCC==="
dst := make([]byte, base32.StdEncoding.DecodedLen(len(str)))
n, err := base32.StdEncoding.Decode(dst, []byte(str))
if err != nil {
fmt.Println("decode error:", err)
return
}
dst = dst[:n]
fmt.Printf("%q\n", dst)
}
func hexDemo() {
const s = "48656c6c6f20476f7068657221"
decoded, err := hex.DecodeString(s)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", decoded)
}
func main() {
base64Demo()
base32Demo()
hexDemo()
}

View File

@@ -0,0 +1,63 @@
package main
import (
"fmt"
"math/big"
)
func fib() {
// Initialize two big ints with the first two numbers in the sequence.
a := big.NewInt(0)
b := big.NewInt(1)
// Initialize limit as 10^99, the smallest integer with 100 digits.
var limit big.Int
limit.Exp(big.NewInt(10), big.NewInt(99), nil)
// Loop while a is smaller than 1e100.
for a.Cmp(&limit) < 0 {
// Compute the next Fibonacci number, storing it in a.
a.Add(a, b)
// Swap a and b so that b is the next number in the sequence.
a, b = b, a
}
fmt.Println(a) // 100-digit Fibonacci number
}
func abs() {
a := big.NewInt(64)
b := big.NewInt(-52)
a.Set(b)
a.Abs(a)
a.Set(big.NewInt(-164))
a.Abs(a)
fmt.Println("value: ", a.String())
}
func neg() {
fmt.Println("value: ", big.NewInt(-64).Neg(big.NewInt(-64)))
fmt.Println("value: ", big.NewInt(64).Neg(big.NewInt(64)))
fmt.Println("value: ", big.NewInt(0).Neg(big.NewInt(0)))
}
func calc() {
a := big.NewInt(64)
b := big.NewInt(-52)
c := big.NewInt(54)
fmt.Println("value:", a.Add(a, b))
fmt.Println("value:", a.Sub(b, c))
d := big.NewInt(10)
e := big.NewInt(4)
fmt.Println("value:", d.Mul(d, e))
}
func bitop() {
a := big.NewInt(4)
fmt.Println("value:", a.Lsh(a, 1))
b := big.NewInt(16)
fmt.Println("value:", b.Rsh(b, 2))
}
func main() {
bitop()
}

28
_cmptest/crcdemo/crc.go Normal file
View File

@@ -0,0 +1,28 @@
package main
import (
"fmt"
"hash/adler32"
"hash/crc32"
"hash/crc64"
)
func crc64Demo() {
crc := crc64.MakeTable(crc64.ECMA)
fmt.Printf("%016x\n", crc64.Checksum([]byte("Hello world"), crc))
}
func crc32Demo() {
crc32q := crc32.MakeTable(crc32.IEEE)
fmt.Printf("%08x\n", crc32.Checksum([]byte("Hello world"), crc32q))
}
func adler32Demo() {
fmt.Printf("%08x\n", adler32.Checksum([]byte("Hello world")))
}
func main() {
adler32Demo()
crc32Demo()
crc64Demo()
}

30
_cmptest/csvdemo/csv.go Normal file
View File

@@ -0,0 +1,30 @@
package main
import (
"encoding/csv"
"fmt"
"io"
"log"
"strings"
)
func main() {
in := `first_name,last_name,username
"Rob","Pike",rob
Ken,Thompson,ken
"Robert","Griesemer","gri"
`
r := csv.NewReader(strings.NewReader(in))
for {
record, err := r.Read()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
fmt.Println(record)
}
}

View File

@@ -0,0 +1,20 @@
package main
import (
"fmt"
"os"
)
func main() {
mapper := func(placeholderName string) string {
switch placeholderName {
case "DAY_PART":
return "morning"
case "NAME":
return "Gopher"
}
return ""
}
fmt.Println(os.Expand("Good ${DAY_PART}, $NAME!", mapper))
}

View File

@@ -0,0 +1,27 @@
package main
import (
"fmt"
"go/scanner"
"go/token"
)
func main() {
// src is the input that we want to tokenize.
src := []byte("cos(x) + 1i*sin(x) // Euler")
// Initialize the scanner.
var s scanner.Scanner
fset := token.NewFileSet() // positions are relative to fset
file := fset.AddFile("", fset.Base(), len(src)) // register input "file"
s.Init(file, src, nil /* no error handler */, scanner.ScanComments)
// Repeated calls to Scan yield the token sequence found in the input.
for {
pos, tok, lit := s.Scan()
if tok == token.EOF {
break
}
fmt.Printf("%s\t%s\t%q\n", fset.Position(pos), tok, lit)
}
}

15
_cmptest/hmacdemo/hmac.go Normal file
View File

@@ -0,0 +1,15 @@
package main
import (
"crypto/hmac"
"crypto/sha1"
"fmt"
"io"
)
func main() {
h := hmac.New(sha1.New, []byte("<key>"))
io.WriteString(h, "The fog is getting thicker!")
io.WriteString(h, "And Leon's getting laaarger!")
fmt.Printf("%x", h.Sum(nil))
}

View File

@@ -0,0 +1,19 @@
package main
import (
"fmt"
"io/ioutil"
"log"
"strings"
)
func main() {
r := strings.NewReader("Go is a general-purpose language designed with systems programming in mind.")
b, err := ioutil.ReadAll(r)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", b)
}

20
_cmptest/md5demo/md5.go Normal file
View File

@@ -0,0 +1,20 @@
package main
import (
"crypto"
"crypto/md5"
"fmt"
"io"
)
func main() {
h := md5.New()
io.WriteString(h, "The fog is getting thicker!")
io.WriteString(h, "And Leon's getting laaarger!")
fmt.Printf("%x\n", h.Sum(nil))
h = crypto.MD5.New()
io.WriteString(h, "The fog is getting thicker!")
io.WriteString(h, "And Leon's getting laaarger!")
fmt.Printf("%x\n", h.Sum(nil))
}

View File

@@ -1,9 +1,12 @@
package main package main
import ( import (
"fmt"
"os" "os"
"os/exec" "os/exec"
"runtime" "runtime"
"github.com/goplus/llgo/xtool/env/llvm"
) )
func main() { func main() {
@@ -15,4 +18,7 @@ func main() {
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
cmd.Run() cmd.Run()
dir := llvm.New("").BinDir()
fmt.Println(dir)
} }

View File

@@ -0,0 +1,12 @@
package main
import (
"fmt"
"github.com/goplus/llgo/xtool/nm"
)
func main() {
sym := nm.Symbol{Name: "abc", Type: nm.Text}
fmt.Printf("%016x %c %s\n", sym.Addr, sym.Type, sym.Name)
}

View File

@@ -0,0 +1,25 @@
package main
import (
"fmt"
"os"
)
func main() {
fileName := "err.log"
os.WriteFile(fileName, []byte("123"), 0644)
_, err := os.Stat(fileName)
if os.IsNotExist(err) {
fmt.Fprintf(os.Stderr, "File %s not found\n", fileName)
return
}
data, err := os.ReadFile(fileName)
if err != nil {
fmt.Fprintf(os.Stderr, "ReadFile: %v\n", err)
return
}
fmt.Printf("%s\n", data)
}

View File

@@ -0,0 +1,11 @@
package main
import (
"fmt"
"github.com/goplus/llgo/xtool/env"
)
func main() {
fmt.Println(env.ExpandEnv("$(pkg-config --libs bdw-gc)"))
}

14
_cmptest/sha1demo/sha1.go Normal file
View File

@@ -0,0 +1,14 @@
package main
import (
"crypto/sha1"
"fmt"
"io"
)
func main() {
h := sha1.New()
io.WriteString(h, "The fog is getting thicker!")
io.WriteString(h, "And Leon's getting laaarger!")
fmt.Printf("%x", h.Sum(nil))
}

View File

@@ -0,0 +1,14 @@
package main
import (
"crypto/sha256"
"fmt"
"io"
)
func main() {
h := sha256.New()
io.WriteString(h, "The fog is getting thicker!")
io.WriteString(h, "And Leon's getting laaarger!")
fmt.Printf("%x", h.Sum(nil))
}

View File

@@ -0,0 +1,14 @@
package main
import (
"crypto/sha512"
"fmt"
"io"
)
func main() {
h := sha512.New()
io.WriteString(h, "The fog is getting thicker!")
io.WriteString(h, "And Leon's getting laaarger!")
fmt.Printf("%x", h.Sum(nil))
}

20
_cmptest/urldemo/url.go Normal file
View File

@@ -0,0 +1,20 @@
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
u, err := url.Parse("http://foo.example.com/foo?bar=1")
if err != nil {
log.Fatal(err)
}
u.Scheme = "https"
u.Host = "bar.example.com"
q := u.Query()
q.Set("bar", "2")
u.RawQuery = q.Encode()
fmt.Println(u)
}

26
_demo/crand/rand.go Normal file
View File

@@ -0,0 +1,26 @@
package main
import (
"fmt"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/math/rand"
"github.com/goplus/llgo/c/time"
)
func fastrand64() uint64 {
v1 := uint64(rand.Random())
v2 := uint64(rand.Random())
return v1 ^ (v2 << 32)
}
func main() {
rand.Srand(c.Uint(time.Time(nil)))
fmt.Printf("%x\n", rand.Rand())
fmt.Printf("%x\n", rand.Rand())
rand.Srandom(c.Uint(time.Time(nil)))
fmt.Printf("%x\n", rand.Random())
fmt.Printf("%x\n", rand.Random())
fmt.Printf("%x\n", fastrand64())
}

View File

@@ -3,6 +3,7 @@ package main
import ( import (
"github.com/goplus/llgo/c" "github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/llama2" "github.com/goplus/llgo/c/llama2"
"github.com/goplus/llgo/c/time"
) )
func main() { func main() {
@@ -11,7 +12,7 @@ func main() {
var tokenizerPath *c.Char = c.Str("tokenizer.bin") var tokenizerPath *c.Char = c.Str("tokenizer.bin")
var temperature, topp c.Float = 1.0, 0.9 var temperature, topp c.Float = 1.0, 0.9
var steps c.Int = 256 var steps c.Int = 256
var rngSeed uint64 = uint64(c.Time(nil)) var rngSeed uint64 = uint64(time.Time(nil))
loop: // parse command line arguments loop: // parse command line arguments
for { for {

View File

@@ -1,15 +0,0 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/math/rand"
)
func main() {
var s c.Uint = 6
rand.Srand(s)
rr := rand.RandR(&s)
r := rand.Rand()
println("r:", r)
println("rr:", rr)
}

18
_demo/randcrypt/rand.go Normal file
View File

@@ -0,0 +1,18 @@
package main
import (
"crypto/rand"
"fmt"
)
func main() {
c := 10
b := make([]byte, c)
_, err := rand.Read(b)
if err != nil {
fmt.Println("error:", err)
return
}
// The slice should now contain random bytes instead of only zeroes.
fmt.Printf("%x\n", b)
}

12
_demo/randdemo/rand.go Normal file
View File

@@ -0,0 +1,12 @@
package main
import (
"fmt"
"math/rand"
)
func main() {
fmt.Println(rand.Intn(100))
fmt.Println(rand.Intn(100))
fmt.Println(rand.Intn(100))
}

6
c/c.go
View File

@@ -79,6 +79,9 @@ func AllocaNew[T any]() *T { return nil }
//go:linkname Malloc C.malloc //go:linkname Malloc C.malloc
func Malloc(size uintptr) Pointer func Malloc(size uintptr) Pointer
//go:linkname Calloc C.calloc
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)
@@ -227,9 +230,6 @@ func Perror(s *Char)
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
//go:linkname Time C.time
func Time(*int32) int32
//go:linkname Usleep C.usleep //go:linkname Usleep C.usleep
func Usleep(useconds Uint) Int func Usleep(useconds Uint) Int

View File

@@ -134,6 +134,18 @@ func (o *JSON) PrintUnformatted() *c.Char { return nil }
// 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 c.Int) *c.Char { return nil }
// llgo:link (*JSON).GetObjectItemCaseSensitive C.cJSON_GetObjectItemCaseSensitive
func (o *JSON) GetObjectItemCaseSensitive(key *c.Char) *JSON { return nil }
// llgo:link (*JSON).GetArraySize C.cJSON_GetArraySize
func (o *JSON) GetArraySize() c.Int { return 0 }
// llgo:link (*JSON).GetArrayItem C.cJSON_GetArrayItem
func (o *JSON) GetArrayItem(index c.Int) *JSON { return nil }
// llgo:link (*JSON).GetStringValue C.cJSON_GetStringValue
func (o *JSON) GetStringValue() *c.Char { return nil }
//go:linkname Free C.cJSON_free //go:linkname Free C.cJSON_free
func Free(ptr unsafe.Pointer) func Free(ptr unsafe.Pointer)

View File

@@ -1,61 +0,0 @@
package main
import (
"fmt"
"os"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/clang"
)
func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitResult {
depth := *(*c.Uint)(clientData)
printAST(cursor, depth+1)
return clang.ChildVisit_Continue
}
func printAST(cursor clang.Cursor, depth c.Uint) {
cursorKind := cursor.Kind.String()
cursorSpelling := cursor.String()
for i := c.Uint(0); i < depth; i++ {
c.Fputs(c.Str(" "), c.Stdout)
}
c.Printf(c.Str("%s: %s\n"), cursorKind.CStr(), cursorSpelling.CStr())
cursorKind.Dispose()
cursorSpelling.Dispose()
clang.VisitChildren(cursor, visit, c.Pointer(&depth))
}
func main() {
if c.Argc != 2 {
fmt.Fprintln(os.Stderr, "Usage: castdump <headerFile>")
return
}
sourceFile := *c.Advance(c.Argv, 1)
index := clang.CreateIndex(0, 0)
unit := index.ParseTranslationUnit(
sourceFile,
nil, 0,
nil, 0,
clang.TranslationUnit_None,
)
if unit == nil {
println("Unable to parse translation unit. Quitting.")
c.Exit(1)
}
cursor := unit.Cursor()
printAST(cursor, 0)
unit.Dispose()
index.Dispose()
}

View File

@@ -12,6 +12,7 @@ import (
type Context struct { type Context struct {
namespaceName string namespaceName string
className string className string
unit *clang.TranslationUnit
} }
func newContext() *Context { func newContext() *Context {
@@ -26,23 +27,51 @@ func (c *Context) setClassName(name string) {
c.className = name c.className = name
} }
func (c *Context) setUnit(unit *clang.TranslationUnit) {
c.unit = unit
}
var context = newContext() var context = newContext()
func print_cursor_info(cursor clang.Cursor) { func printCursorLocation(cursor clang.Cursor) {
loc := cursor.Location() loc := cursor.Location()
var file clang.File var file clang.File
var line, column c.Uint var line, column c.Uint
loc.SpellingLocation(&file, &line, &column, nil) loc.SpellingLocation(&file, &line, &column, nil)
filename := file.FileName() filename := file.FileName()
defer filename.Dispose()
c.Printf(c.Str("%s:%d:%d\n"), filename.CStr(), line, column) c.Printf(c.Str("%s:%d:%d\n"), filename.CStr(), line, column)
}
func printMarcoInfo(cursor clang.Cursor) {
printCursorLocation(cursor)
name := cursor.String()
c.Printf(c.Str("Marco Name: %s\n"), name.CStr())
ran := cursor.Extent()
var numTokens c.Uint
var tokens *clang.Token
context.unit.Tokenize(ran, &tokens, &numTokens)
c.Printf(c.Str("Content: "))
tokensSlice := unsafe.Slice(tokens, int(numTokens))
for _, tok := range tokensSlice {
tokStr := context.unit.Token(tok)
c.Printf(c.Str("%s "), tokStr.CStr())
tokStr.Dispose()
}
c.Printf(c.Str("\n"))
println("--------------------------------")
}
func printFuncInfo(cursor clang.Cursor) {
printCursorLocation(cursor)
cursorStr := cursor.String() cursorStr := cursor.String()
symbol := cursor.Mangling() symbol := cursor.Mangling()
defer symbol.Dispose() defer symbol.Dispose()
defer cursorStr.Dispose() defer cursorStr.Dispose()
defer filename.Dispose()
if context.namespaceName != "" && context.className != "" { if context.namespaceName != "" && context.className != "" {
fmt.Printf("%s:%s:", context.namespaceName, context.className) fmt.Printf("%s:%s:", context.namespaceName, context.className)
@@ -51,7 +80,7 @@ func print_cursor_info(cursor clang.Cursor) {
} }
c.Printf(c.Str("%s\n"), cursorStr.CStr()) c.Printf(c.Str("%s\n"), cursorStr.CStr())
if cursor.Kind == clang.CXXMethod || cursor.Kind == clang.FunctionDecl { if cursor.Kind == clang.CursorCXXMethod || cursor.Kind == clang.CursorFunctionDecl {
c.Printf(c.Str("symbol:%s\n"), symbol.CStr()) c.Printf(c.Str("symbol:%s\n"), symbol.CStr())
typeStr := cursor.ResultType().String() typeStr := cursor.ResultType().String()
@@ -78,18 +107,20 @@ func print_cursor_info(cursor clang.Cursor) {
} }
func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitResult { func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitResult {
if cursor.Kind == clang.Namespace { if cursor.Kind == clang.CursorMacroDefinition {
printMarcoInfo(cursor)
} else if cursor.Kind == clang.CursorNamespace {
nameStr := cursor.String() nameStr := cursor.String()
context.setNamespaceName(c.GoString(nameStr.CStr())) context.setNamespaceName(c.GoString(nameStr.CStr()))
clang.VisitChildren(cursor, visit, nil) clang.VisitChildren(cursor, visit, nil)
context.setNamespaceName("") context.setNamespaceName("")
} else if cursor.Kind == clang.ClassDecl { } else if cursor.Kind == clang.CursorClassDecl {
nameStr := cursor.String() nameStr := cursor.String()
context.setClassName(c.GoString(nameStr.CStr())) context.setClassName(c.GoString(nameStr.CStr()))
clang.VisitChildren(cursor, visit, nil) clang.VisitChildren(cursor, visit, nil)
context.setClassName("") context.setClassName("")
} else if cursor.Kind == clang.CXXMethod || cursor.Kind == clang.FunctionDecl { } else if cursor.Kind == clang.CursorCXXMethod || cursor.Kind == clang.CursorFunctionDecl {
print_cursor_info(cursor) printFuncInfo(cursor)
} }
return clang.ChildVisit_Continue return clang.ChildVisit_Continue
@@ -105,7 +136,7 @@ func parse(filename *c.Char) {
filename, filename,
unsafe.SliceData(args), 3, unsafe.SliceData(args), 3,
nil, 0, nil, 0,
clang.TranslationUnit_None, clang.DetailedPreprocessingRecord,
) )
if unit == nil { if unit == nil {
@@ -113,6 +144,7 @@ func parse(filename *c.Char) {
c.Exit(1) c.Exit(1)
} }
context.setUnit(unit)
cursor := unit.Cursor() cursor := unit.Cursor()
clang.VisitChildren(cursor, visit, nil) clang.VisitChildren(cursor, visit, nil)

View File

@@ -33,8 +33,30 @@ void wrap_clang_getCursorType(CXCursor *cur, CXType *typ) { *typ = clang_getCurs
void wrap_clang_getCursorResultType(CXCursor *cur, CXType *typ) { *typ = clang_getCursorResultType(*cur); } void wrap_clang_getCursorResultType(CXCursor *cur, CXType *typ) { *typ = clang_getCursorResultType(*cur); }
void wrap_clang_getResultType(CXType *typ, CXType *resultTyp) { *resultTyp = clang_getResultType(*typ); }
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); }
long long wrap_clang_getEnumConstantDeclValue(CXCursor *cur) { return clang_getEnumConstantDeclValue(*cur); }
void wrap_clang_getPointeeType(CXType *pointerTyp, CXType *pointeeTyp) {
*pointeeTyp = clang_getPointeeType(*pointerTyp);
}
void wrap_clang_getArrayElementType(CXType *arrayTyp, CXType *elemTyp) {
*elemTyp = clang_getArrayElementType(*arrayTyp);
}
void wrap_clang_getCanonicalType(CXType *typ, CXType *canonicalType) { *canonicalType = clang_getCanonicalType(*typ); }
CXString wrap_clang_getTypeSpelling(CXType *typ) { return clang_getTypeSpelling(*typ); } CXString wrap_clang_getTypeSpelling(CXType *typ) { return clang_getTypeSpelling(*typ); }
CXString wrap_clang_getTokenSpelling(CXTranslationUnit unit, CXToken *token) {
return clang_getTokenSpelling(unit, *token);
}
void wrap_clang_getCursorLocation(CXCursor *cur, CXSourceLocation *loc) { *loc = clang_getCursorLocation(*cur); } void wrap_clang_getCursorLocation(CXCursor *cur, CXSourceLocation *loc) { *loc = clang_getCursorLocation(*cur); }
void wrap_clang_getSpellingLocation(CXSourceLocation *loc, CXFile *file, unsigned *line, unsigned *column, void wrap_clang_getSpellingLocation(CXSourceLocation *loc, CXFile *file, unsigned *line, unsigned *column,
@@ -42,6 +64,16 @@ void wrap_clang_getSpellingLocation(CXSourceLocation *loc, CXFile *file, unsigne
clang_getSpellingLocation(*loc, file, line, column, offset); clang_getSpellingLocation(*loc, file, line, column, offset);
} }
enum CX_CXXAccessSpecifier wrap_clang_getCXXAccessSpecifier(CXCursor *cursor) {
return clang_getCXXAccessSpecifier(*cursor);
}
void wrap_clang_getCursorExtent(CXCursor *cur, CXSourceRange *range) { *range = clang_getCursorExtent(*cur); }
void wrap_clang_tokenize(CXTranslationUnit unit, CXSourceRange *Range, CXToken **Tokens, unsigned *NumTokens) {
clang_tokenize(unit, *Range, Tokens, NumTokens);
}
unsigned wrap_clang_visitChildren(CXCursor *parent, wrap_CXCursorVisitor visitor, CXClientData client_data) { unsigned wrap_clang_visitChildren(CXCursor *parent, wrap_CXCursorVisitor visitor, CXClientData client_data) {
wrap_data data = {client_data, visitor}; wrap_data data = {client_data, visitor};
return clang_visitChildren(*parent, wrap_visitor, CXClientData(&data)); return clang_visitChildren(*parent, wrap_visitor, CXClientData(&data));

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,41 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/libuv"
)
func ensure(b bool, msg string) {
if !b {
panic(msg)
}
}
func main() {
loop := libuv.LoopNew()
defer loop.Close()
a := &libuv.Async{}
r := loop.Async(a, func(a *libuv.Async) {
println("async callback")
a.Close(nil) // or loop.Stop()
})
ensure(r == 0, "Async failed")
go func() {
println("begin async task")
c.Usleep(100 * 1000)
println("send async event")
ensure(a.Send() == 0, "Send failed")
}()
loop.Run(libuv.RUN_DEFAULT)
println("done")
}
/*Expected Output:
begin async task
send async event
async callback
done
*/

View File

@@ -13,11 +13,11 @@ const BUFFER_SIZE = 1024
var ( var (
loop *libuv.Loop loop *libuv.Loop
openReq libuv.Fs openReq libuv.Fs
readReq libuv.Fs
closeReq libuv.Fs closeReq libuv.Fs
buffer [BUFFER_SIZE]c.Char buffer [BUFFER_SIZE]c.Char
iov libuv.Buf iov libuv.Buf
file libuv.File
) )
func main() { func main() {
@@ -31,7 +31,11 @@ func main() {
libuv.FsOpen(loop, &openReq, c.Str("example.txt"), os.O_RDONLY, 0, onOpen) libuv.FsOpen(loop, &openReq, c.Str("example.txt"), os.O_RDONLY, 0, onOpen)
// Run the loop // Run the loop
libuv.Run(loop, libuv.RUN_DEFAULT) result := loop.Run(libuv.RUN_DEFAULT)
if result != 0 {
c.Fprintf(c.Stderr, c.Str("Error in Run: %s\n"), libuv.Strerror(libuv.Errno(result)))
}
// Cleanup // Cleanup
defer cleanup() defer cleanup()
@@ -39,59 +43,74 @@ func main() {
func onOpen(req *libuv.Fs) { func onOpen(req *libuv.Fs) {
// Check for errors // Check for errors
if libuv.FsGetResult(req) < 0 { if req.GetResult() < 0 {
c.Fprintf(c.Stderr, c.Str("Error opening file: %s\n"), libuv.Strerror(libuv.Errno(libuv.LoopClose(loop)))) c.Fprintf(c.Stderr, c.Str("Error opening file: %s\n"), libuv.Strerror(libuv.Errno(req.GetResult())))
libuv.LoopClose(loop) loop.Close()
return return
} }
// Store the file descriptor
file = libuv.File(req.GetResult())
// Init buffer // Init buffer
iov = libuv.InitBuf((*c.Char)(unsafe.Pointer(&buffer[0])), c.Uint(unsafe.Sizeof(buffer))) iov = libuv.InitBuf((*c.Char)(unsafe.Pointer(&buffer[0])), c.Uint(unsafe.Sizeof(buffer)))
// Read the file // Read the file
readRes := libuv.FsRead(loop, &readReq, libuv.UvFile(libuv.FsGetResult(req)), &iov, 1, -1, onRead) readFile()
}
func readFile() {
// Initialize the request every time
var readReq libuv.Fs
// Read the file
readRes := libuv.FsRead(loop, &readReq, file, &iov, 1, -1, onRead)
if readRes != 0 { if readRes != 0 {
c.Printf(c.Str("Error in FsRead: %s (code: %d)\n"), libuv.Strerror(libuv.Errno(readRes)), readRes) c.Printf(c.Str("Error in FsRead: %s (code: %d)\n"), libuv.Strerror(libuv.Errno(readRes)), readRes)
libuv.LoopClose(loop) readReq.ReqCleanup()
return loop.Close()
} }
} }
func onRead(req *libuv.Fs) { func onRead(req *libuv.Fs) {
// Cleanup the request
defer req.ReqCleanup()
// Check for errors // Check for errors
if libuv.FsGetResult(req) < 0 { if req.GetResult() < 0 {
c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror(libuv.Errno(libuv.FsGetResult(req)))) c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror(libuv.Errno(req.GetResult())))
libuv.LoopClose(loop) } else if req.GetResult() == 0 {
} else if libuv.FsGetResult(req) == 0 {
c.Printf(c.Str("EOF\n"))
// Close the file // Close the file
closeRes := libuv.FsClose(loop, &closeReq, libuv.UvFile(libuv.FsGetResult(&openReq)), onClose) closeRes := libuv.FsClose(loop, &closeReq, libuv.File(openReq.GetResult()), onClose)
if closeRes != 0 { if closeRes != 0 {
// Print the content
c.Printf(c.Str("Error in FsClose: %s (code: %d)\n"), libuv.Strerror(libuv.Errno(closeRes)), closeRes) c.Printf(c.Str("Error in FsClose: %s (code: %d)\n"), libuv.Strerror(libuv.Errno(closeRes)), closeRes)
libuv.LoopClose(loop) loop.Close()
return return
} }
} else { } else {
c.Printf(c.Str("Read %d bytes\n"), libuv.FsGetResult(req)) c.Printf(c.Str("Read %d bytes\n"), req.GetResult())
c.Printf(c.Str("Read content: %.*s\n"), libuv.FsGetResult(req), (*c.Char)(unsafe.Pointer(&buffer[0]))) c.Printf(c.Str("Read content: %.*s\n"), req.GetResult(), (*c.Char)(unsafe.Pointer(&buffer[0])))
libuv.LoopClose(loop) // Read the file again
readFile()
} }
} }
func onClose(req *libuv.Fs) { func onClose(req *libuv.Fs) {
// Check for errors // Check for errors
if libuv.FsGetResult(req) < 0 { if req.GetResult() < 0 {
c.Fprintf(c.Stderr, c.Str("Error closing file: %s\n"), libuv.Strerror(libuv.Errno(libuv.FsGetResult(req)))) c.Fprintf(c.Stderr, c.Str("Error closing file: %s\n"), libuv.Strerror(libuv.Errno(req.GetResult())))
} else { } else {
c.Printf(c.Str("\nFile closed successfully.\n")) c.Printf(c.Str("\nFile closed successfully.\n"))
} }
libuv.LoopClose(loop)
} }
func cleanup() { func cleanup() {
// Cleanup the requests // Cleanup the requests
libuv.FsReqCleanup(&openReq) openReq.ReqCleanup()
libuv.FsReqCleanup(&readReq) closeReq.ReqCleanup()
libuv.FsReqCleanup(&closeReq)
// Close the loop // Close the loop
libuv.LoopClose(loop) result := loop.Close()
if result != 0 {
c.Fprintf(c.Stderr, c.Str("Error in LoopClose: %s\n"), libuv.Strerror(libuv.Errno(result)))
}
} }

View File

@@ -1,8 +1,6 @@
package main package main
import ( import (
"unsafe"
"github.com/goplus/llgo/c" "github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/libuv" "github.com/goplus/llgo/c/libuv"
"github.com/goplus/llgo/c/net" "github.com/goplus/llgo/c/net"
@@ -11,20 +9,18 @@ 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 loop *libuv.Loop var (
Req *libuv.Write
type WriteReq struct {
Req libuv.Write
Buf libuv.Buf Buf libuv.Buf
} )
func main() { func main() {
// Initialize the default event loop // Initialize the default event loop
loop = libuv.DefaultLoop() var loop = libuv.DefaultLoop()
// Initialize a TCP server // Initialize a TCP server
var server libuv.Tcp server := &libuv.Tcp{}
libuv.InitTcp(loop, &server) libuv.InitTcp(loop, server)
// Set up the address to bind the server to // Set up the address to bind the server to
var addr net.SockaddrIn var addr net.SockaddrIn
@@ -32,22 +28,20 @@ func main() {
c.Printf(c.Str("Listening on %s:%d\n"), c.Str("0.0.0.0"), DEFAULT_PORT) c.Printf(c.Str("Listening on %s:%d\n"), c.Str("0.0.0.0"), DEFAULT_PORT)
// Bind the server to the specified address and port // Bind the server to the specified address and port
(&server).Bind((*net.SockAddr)(c.Pointer(&addr)), 0) server.Bind((*net.SockAddr)(c.Pointer(&addr)), 0)
res := (*libuv.Stream)(&server).Listen(DEFAULT_BACKLOG, OnNewConnection) res := (*libuv.Stream)(server).Listen(DEFAULT_BACKLOG, OnNewConnection)
if res != 0 { if res != 0 {
c.Fprintf(c.Stderr, c.Str("Listen error: %s\n"), libuv.Strerror((libuv.Errno(res)))) c.Fprintf(c.Stderr, c.Str("Listen error: %s\n"), libuv.Strerror(libuv.Errno(res)))
return return
} }
// Start listening for incoming connections // Start listening for incoming connections
libuv.Run(loop, libuv.RUN_DEFAULT) loop.Run(libuv.RUN_DEFAULT)
} }
func FreeWriteReq(req *libuv.Write) { func FreeWriteReq() {
wr := (*WriteReq)(c.Pointer(req)) // Free the buffer base.
// Free the buffer base and the WriteReq itself. c.Free(c.Pointer(Buf.Base))
c.Free(c.Pointer(wr.Buf.Base))
c.Free(c.Pointer(wr))
} }
func AllocBuffer(handle *libuv.Handle, suggestedSize uintptr, buf *libuv.Buf) { func AllocBuffer(handle *libuv.Handle, suggestedSize uintptr, buf *libuv.Buf) {
@@ -58,29 +52,24 @@ func AllocBuffer(handle *libuv.Handle, suggestedSize uintptr, buf *libuv.Buf) {
func EchoWrite(req *libuv.Write, status c.Int) { 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(req) FreeWriteReq()
} }
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 := (*WriteReq)(c.Malloc(unsafe.Sizeof(WriteReq{})))
if req == nil {
c.Fprintf(c.Stderr, c.Str("Failed to allocate memory for write request\n"))
c.Free(c.Pointer(buf.Base))
return
}
// Initialize the buffer with the data read. // Initialize the buffer with the data read.
req.Buf = libuv.InitBuf(buf.Base, c.Uint(nread)) Buf = libuv.InitBuf(buf.Base, c.Uint(nread))
// Write the data back to the client. // Write the data back to the client.
(&req.Req).Write(client, &req.Buf, 1, EchoWrite) Req = &libuv.Write{}
Req.Write(client, &Buf, 1, EchoWrite)
return return
} }
if nread < 0 { if nread < 0 {
// Handle read errors and EOF. // Handle read errors and EOF.
if (libuv.Errno)(nread) != libuv.EOF { if (libuv.Errno)(nread) != libuv.EOF {
c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror((libuv.Errno)(nread))) c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror(libuv.Errno(nread)))
} }
(*libuv.Handle)(c.Pointer(client)).Close(nil) (*libuv.Handle)(c.Pointer(client)).Close(nil)
} }
@@ -97,7 +86,7 @@ func OnNewConnection(server *libuv.Stream, status c.Int) {
} }
// Allocate memory for a new client. // Allocate memory for a new client.
client := (*libuv.Tcp)(c.Malloc(unsafe.Sizeof(libuv.Tcp{}))) client := &libuv.Tcp{}
if client == nil { if client == nil {
c.Fprintf(c.Stderr, c.Str("Failed to allocate memory for client\n")) c.Fprintf(c.Stderr, c.Str("Failed to allocate memory for client\n"))
@@ -105,7 +94,7 @@ func OnNewConnection(server *libuv.Stream, status c.Int) {
} }
// Initialize the client TCP handle. // Initialize the client TCP handle.
if libuv.InitTcp(loop, 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)) c.Free(c.Pointer(client))
return return

5
c/libuv/_wrap/libuv.c Normal file
View File

@@ -0,0 +1,5 @@
#include <uv.h>
int uv_tcp_get_io_watcher_fd (uv_tcp_t* handle) {
return handle->io_watcher.fd;
}

50
c/libuv/async.go Normal file
View File

@@ -0,0 +1,50 @@
/*
* 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 libuv
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
// struct uv_async_t
type Async struct {
Handle
// On macOS arm64, sizeof uv_async_t is 128 bytes.
// Handle is 92 bytes, so we need 36 bytes to fill the gap.
// Maybe reserve more for future use.
Unused [36]byte
}
// typedef void (*uv_async_cb)(uv_async_t* handle);
// llgo:type C
type AsyncCb func(*Async)
// int uv_async_init(uv_loop_t*, uv_async_t* async, uv_async_cb async_cb);
//
// llgo:link (*Loop).Async C.uv_async_init
func (loop *Loop) Async(a *Async, cb AsyncCb) c.Int {
return 0
}
// int uv_async_send(uv_async_t* async);
//
// llgo:link (*Async).Send C.uv_async_send
func (a *Async) Send() c.Int {
return 0
}

View File

@@ -62,14 +62,14 @@ type FsType c.Int
type DirentType c.Int type DirentType c.Int
type UvFile c.Int type File c.Int
// ---------------------------------------------- // ----------------------------------------------
/* Handle types. */ /* Handle types. */
type Fs struct { type Fs struct {
Unused [0]byte Unused [440]byte
} }
type FsEvent struct { type FsEvent struct {
@@ -85,11 +85,6 @@ type Dirent struct {
Type DirentType Type DirentType
} }
type File struct {
Loop *Loop
Req *Fs
}
type Stat struct { type Stat struct {
Unused [0]byte Unused [0]byte
} }
@@ -111,41 +106,52 @@ type FsPollCb func(handle *FsPoll, status c.Int, events c.Int)
/* Fs related function and method */ /* Fs related function and method */
//go:linkname FsGetType C.uv_fs_get_type // llgo:link (*Fs).GetType C.uv_fs_get_type
func FsGetType(req *Fs) *FsType func (req *Fs) GetType() FsType {
return 0
}
//go:linkname FsGetPath C.uv_fs_get_path // llgo:link (*Fs).GetPath C.uv_fs_get_path
func FsGetPath(req *Fs) *c.Char func (req *Fs) GetPath() *c.Char {
return nil
}
//go:linkname FsGetResult C.uv_fs_get_result // llgo:link (*Fs).GetResult C.uv_fs_get_result
func FsGetResult(req *Fs) c.Int func (req *Fs) GetResult() c.Int {
return 0
}
//go:linkname FsGetPtr C.uv_fs_get_ptr // llgo:link (*Fs).GetPtr C.uv_fs_get_ptr
func FsGetPtr(req *Fs) c.Pointer func (req *Fs) GetPtr() c.Pointer {
return nil
}
//go:linkname FsGetSystemError C.uv_fs_get_system_error // llgo:link (*Fs).GetSystemError C.uv_fs_get_system_error
func FsGetSystemError(req *Fs) c.Int func (req *Fs) GetSystemError() c.Int {
return 0
}
//go:linkname FsGetStatBuf C.uv_fs_get_statbuf // llgo:link (*Fs).GetStatBuf C.uv_fs_get_statbuf
func FsGetStatBuf(req *Fs) *Stat func (req *Fs) GetStatBuf() *Stat {
return nil
}
//go:linkname FsReqCleanup C.uv_fs_req_cleanup // llgo:link (*Fs).ReqCleanup C.uv_fs_req_cleanup
func FsReqCleanup(req *Fs) func (req *Fs) ReqCleanup() {
// No return value needed for this method
//go:linkname DefaultLoop C.uv_default_loop }
func DefaultLoop() *Loop
//go:linkname FsOpen C.uv_fs_open //go:linkname FsOpen C.uv_fs_open
func FsOpen(loop *Loop, req *Fs, path *c.Char, flags c.Int, mode c.Int, cb FsCb) c.Int func FsOpen(loop *Loop, req *Fs, path *c.Char, flags c.Int, mode c.Int, cb FsCb) c.Int
//go:linkname FsClose C.uv_fs_close //go:linkname FsClose C.uv_fs_close
func FsClose(loop *Loop, req *Fs, file UvFile, cb FsCb) c.Int func FsClose(loop *Loop, req *Fs, file File, cb FsCb) c.Int
//go:linkname FsRead C.uv_fs_read //go:linkname FsRead C.uv_fs_read
func FsRead(loop *Loop, req *Fs, file UvFile, bufs *Buf, nbufs c.Uint, offset c.LongLong, cb FsCb) c.Int func FsRead(loop *Loop, req *Fs, file File, bufs *Buf, nbufs c.Uint, offset c.LongLong, cb FsCb) c.Int
//go:linkname FsWrite C.uv_fs_write //go:linkname FsWrite C.uv_fs_write
func FsWrite(loop *Loop, req *Fs, file UvFile, bufs *Buf, nbufs c.Uint, offset c.LongLong, cb FsCb) c.Int func FsWrite(loop *Loop, req *Fs, file File, bufs *Buf, nbufs c.Uint, offset c.LongLong, cb FsCb) c.Int
//go:linkname FsUnlink C.uv_fs_unlink //go:linkname FsUnlink C.uv_fs_unlink
func FsUnlink(loop *Loop, req *Fs, path *c.Char, cb FsCb) c.Int func FsUnlink(loop *Loop, req *Fs, path *c.Char, cb FsCb) c.Int
@@ -166,19 +172,19 @@ func FsRmdir(loop *Loop, req *Fs, path *c.Char, cb FsCb) c.Int
func FsStat(loop *Loop, req *Fs, path *c.Char, cb FsCb) c.Int func FsStat(loop *Loop, req *Fs, path *c.Char, cb FsCb) c.Int
//go:linkname FsFstat C.uv_fs_fstat //go:linkname FsFstat C.uv_fs_fstat
func FsFstat(loop *Loop, req *Fs, file UvFile, cb FsCb) c.Int func FsFstat(loop *Loop, req *Fs, file File, cb FsCb) c.Int
//go:linkname FsRename C.uv_fs_rename //go:linkname FsRename C.uv_fs_rename
func FsRename(loop *Loop, req *Fs, path *c.Char, newPath *c.Char, cb FsCb) c.Int func FsRename(loop *Loop, req *Fs, path *c.Char, newPath *c.Char, cb FsCb) c.Int
//go:linkname FsFsync C.uv_fs_fsync //go:linkname FsFsync C.uv_fs_fsync
func FsFsync(loop *Loop, req *Fs, file UvFile, cb FsCb) c.Int func FsFsync(loop *Loop, req *Fs, file File, cb FsCb) c.Int
//go:linkname FsFdatasync C.uv_fs_fdatasync //go:linkname FsFdatasync C.uv_fs_fdatasync
func FsFdatasync(loop *Loop, req *Fs, file UvFile, cb FsCb) c.Int func FsFdatasync(loop *Loop, req *Fs, file File, cb FsCb) c.Int
//go:linkname FsFtruncate C.uv_fs_ftruncate //go:linkname FsFtruncate C.uv_fs_ftruncate
func FsFtruncate(loop *Loop, req *Fs, file UvFile, offset c.LongLong, cb FsCb) c.Int func FsFtruncate(loop *Loop, req *Fs, file File, offset c.LongLong, cb FsCb) c.Int
//go:linkname FsSendfile C.uv_fs_sendfile //go:linkname FsSendfile C.uv_fs_sendfile
func FsSendfile(loop *Loop, req *Fs, outFd c.Int, inFd c.Int, inOffset c.LongLong, length c.Int, cb FsCb) c.Int func FsSendfile(loop *Loop, req *Fs, outFd c.Int, inFd c.Int, inOffset c.LongLong, length c.Int, cb FsCb) c.Int
@@ -190,13 +196,13 @@ func FsAccess(loop *Loop, req *Fs, path *c.Char, flags c.Int, cb FsCb) c.Int
func FsChmod(loop *Loop, req *Fs, path *c.Char, mode c.Int, cb FsCb) c.Int func FsChmod(loop *Loop, req *Fs, path *c.Char, mode c.Int, cb FsCb) c.Int
//go:linkname FsFchmod C.uv_fs_fchmod //go:linkname FsFchmod C.uv_fs_fchmod
func FsFchmod(loop *Loop, req *Fs, file UvFile, mode c.Int, cb FsCb) c.Int func FsFchmod(loop *Loop, req *Fs, file File, mode c.Int, cb FsCb) c.Int
//go:linkname FsUtime C.uv_fs_utime //go:linkname FsUtime C.uv_fs_utime
func FsUtime(loop *Loop, req *Fs, path *c.Char, atime c.Int, mtime c.Int, cb FsCb) c.Int func FsUtime(loop *Loop, req *Fs, path *c.Char, atime c.Int, mtime c.Int, cb FsCb) c.Int
//go:linkname FsFutime C.uv_fs_futime //go:linkname FsFutime C.uv_fs_futime
func FsFutime(loop *Loop, req *Fs, file UvFile, atime c.Int, mtime c.Int, cb FsCb) c.Int func FsFutime(loop *Loop, req *Fs, file File, atime c.Int, mtime c.Int, cb FsCb) c.Int
//go:linkname FsLutime C.uv_fs_lutime //go:linkname FsLutime C.uv_fs_lutime
func FsLutime(loop *Loop, req *Fs, path *c.Char, atime c.Int, mtime c.Int, cb FsCb) c.Int func FsLutime(loop *Loop, req *Fs, path *c.Char, atime c.Int, mtime c.Int, cb FsCb) c.Int
@@ -238,7 +244,7 @@ func FsStatfs(loop *Loop, req *Fs, path *c.Char, cb FsCb) c.Int
func FsChown(loop *Loop, req *Fs, path *c.Char, uid c.Int, gid c.Int, cb FsCb) c.Int func FsChown(loop *Loop, req *Fs, path *c.Char, uid c.Int, gid c.Int, cb FsCb) c.Int
//go:linkname FsFchown C.uv_fs_fchown //go:linkname FsFchown C.uv_fs_fchown
func FsFchown(loop *Loop, req *Fs, file UvFile, uid c.Int, gid c.Int, cb FsCb) c.Int func FsFchown(loop *Loop, req *Fs, file File, uid c.Int, gid c.Int, cb FsCb) c.Int
//go:linkname FsLchown C.uv_fs_lchown //go:linkname FsLchown C.uv_fs_lchown
func FsLchown(loop *Loop, req *Fs, path *c.Char, uid c.Int, gid c.Int, cb FsCb) c.Int func FsLchown(loop *Loop, req *Fs, path *c.Char, uid c.Int, gid c.Int, cb FsCb) c.Int
@@ -246,32 +252,56 @@ func FsLchown(loop *Loop, req *Fs, path *c.Char, uid c.Int, gid c.Int, cb FsCb)
//go:linkname FsLstat C.uv_fs_lstat //go:linkname FsLstat C.uv_fs_lstat
func FsLstat(loop *Loop, req *Fs, path *c.Char, cb FsCb) c.Int func FsLstat(loop *Loop, req *Fs, path *c.Char, cb FsCb) c.Int
// ----------------------------------------------
/* FsEvent related function and method */
//go:linkname FsEventInit C.uv_fs_event_init //go:linkname FsEventInit C.uv_fs_event_init
func FsEventInit(loop *Loop, handle *FsEvent) c.Int func FsEventInit(loop *Loop, handle *FsEvent) c.Int
//go:linkname FsEventStart C.uv_fs_event_start // llgo:link (*FsEvent).Start C.uv_fs_event_start
func FsEventStart(handle *FsEvent, cb FsEventCb, path *c.Char, flags c.Int) c.Int func (handle *FsEvent) Start(cb FsEventCb, path *c.Char, flags c.Int) c.Int {
return 0
}
//go:linkname FsEventStop C.uv_fs_event_stop // llgo:link (*FsEvent).Stop C.uv_fs_event_stop
func FsEventStop(handle *FsEvent) c.Int func (handle *FsEvent) Stop() c.Int {
return 0
}
//go:linkname FsEventClose C.uv_fs_event_close // llgo:link (*FsEvent).Close C.uv_fs_event_close
func FsEventClose(handle *FsEvent) c.Int func (handle *FsEvent) Close() c.Int {
return 0
}
//go:linkname FsEventGetpath C.uv_fs_event_getpath // llgo:link (*FsEvent).Getpath C.uv_fs_event_getpath
func FsEventGetpath(handle *FsEvent) *c.Char func (handle *FsEvent) Getpath() *c.Char {
return nil
}
// ----------------------------------------------
/* FsPoll related function and method */
//go:linkname FsPollInit C.uv_fs_poll_init //go:linkname FsPollInit C.uv_fs_poll_init
func FsPollInit(loop *Loop, handle *FsPoll) c.Int func FsPollInit(loop *Loop, handle *FsPoll) c.Int
//go:linkname FsPollStart C.uv_fs_poll_start // llgo:link (*FsPoll).Start C.uv_fs_poll_start
func FsPollStart(handle *FsPoll, cb FsPollCb, path *c.Char, interval uint) c.Int func (handle *FsPoll) Start(cb FsPollCb, path *c.Char, interval uint) c.Int {
return 0
}
//go:linkname FsPollStop C.uv_fs_poll_stop // llgo:link (*FsPoll).Stop C.uv_fs_poll_stop
func FsPollStop(handle *FsPoll) c.Int func (handle *FsPoll) Stop() c.Int {
return 0
}
//go:linkname FsPollClose C.uv_fs_poll_close // llgo:link (*FsPoll).Close C.uv_fs_poll_close
func FsPollClose(handle *FsPoll) c.Int func (handle *FsPoll) Close() c.Int {
return 0
}
//go:linkname FsPollGetPath C.uv_fs_poll_getpath // llgo:link (*FsPoll).GetPath C.uv_fs_poll_getpath
func FsPollGetPath(handle *FsPoll) *c.Char func (handle *FsPoll) GetPath() *c.Char {
return nil
}

View File

@@ -9,6 +9,7 @@ import (
const ( const (
LLGoPackage = "link: $(pkg-config --libs libuv); -luv" LLGoPackage = "link: $(pkg-config --libs libuv); -luv"
LLGoFiles = "$(pkg-config --cflags libuv): _wrap/libuv.c"
) )
// ---------------------------------------------- // ----------------------------------------------
@@ -97,76 +98,12 @@ type Loop struct {
Unused [0]byte Unused [0]byte
} }
type Handle struct {
Unused [96]byte
}
type Dir struct {
Unused [0]byte
}
type Stream struct {
Unused [264]byte
}
type Pipe struct {
Unused [0]byte
}
type Tty struct {
Unused [0]byte
}
type Poll struct { type Poll struct {
Unused [0]byte Unused [0]byte
} }
type Prepare struct {
Unused [0]byte
}
type Check struct {
Unused [0]byte
}
type Idle struct {
Unused [0]byte
}
type Async struct {
Unused [0]byte
}
type Process struct {
Unused [0]byte
}
/* Request types. */ /* Request types. */
type Req struct {
Unused [0]byte
}
type GetAddrInfo struct {
Unused [0]byte
}
type GetNameInfo struct {
Unused [0]byte
}
type Shutdown struct {
Unused [0]byte
}
type Write struct {
Unused [192]byte
}
type Connect struct {
Unused [0]byte
}
type Buf struct { type Buf struct {
Base *c.Char Base *c.Char
Len uintptr Len uintptr
@@ -189,24 +126,12 @@ type FreeFunc func(ptr c.Pointer)
// llgo:type C // llgo:type C
type AllocCb func(handle *Handle, suggestedSize uintptr, buf *Buf) type AllocCb func(handle *Handle, suggestedSize uintptr, buf *Buf)
// llgo:type C
type ReadCb func(stream *Stream, nread c.Long, buf *Buf)
// llgo:type C
type WriteCb func(req *Write, status c.Int)
// llgo:type C // llgo:type C
type GetaddrinfoCb func(req *GetAddrInfo, status c.Int, res *net.AddrInfo) type GetaddrinfoCb func(req *GetAddrInfo, status c.Int, res *net.AddrInfo)
// llgo:type C // llgo:type C
type GetnameinfoCb func(req *GetNameInfo, status c.Int, hostname *c.Char, service *c.Char) type GetnameinfoCb func(req *GetNameInfo, status c.Int, hostname *c.Char, service *c.Char)
// llgo:type C
type ConnectionCb func(server *Stream, status c.Int)
// llgo:type C
type ShutdownCb func(req *Shutdown, status c.Int)
// llgo:type C // llgo:type C
type WalkCb func(handle *Handle, arg c.Pointer) type WalkCb func(handle *Handle, arg c.Pointer)
@@ -229,223 +154,88 @@ func ReplaceAllocator(mallocFunc MallocFunc, reallocFunc ReallocFunc, callocFunc
// ---------------------------------------------- // ----------------------------------------------
// llgo:link (*Shutdown).Shutdown C.uv_shutdown
func (shutdown *Shutdown) Shutdown(stream *Stream, shutdownCb ShutdownCb) c.Int {
return 0
}
// ----------------------------------------------
/* Handle related function and method */
// llgo:link (*Handle).Ref C.uv_ref
func (handle *Handle) Ref() {}
// llgo:link (*Handle).Unref C.uv_unref
func (handle *Handle) Unref() {}
// llgo:link (*Handle).HasRef C.uv_has_ref
func (handle *Handle) HasRef() c.Int {
return 0
}
//go:linkname HandleSize C.uv_handle_size
func HandleSize(handleType HandleType) uintptr
// llgo:link (*Handle).GetType C.uv_handle_get_type
func (handle *Handle) GetType() HandleType {
return 0
}
//go:linkname HandleTypeName C.uv_handle_type_name
func HandleTypeName(handleType HandleType) *c.Char
// llgo:link (*Handle).GetData C.uv_handle_get_data
func (handle *Handle) GetData() c.Pointer {
return nil
}
// llgo:link (*Handle).GetLoop C.uv_handle_get_loop
func (handle *Handle) GetLoop() *Loop {
return nil
}
// llgo:link (*Handle).SetData C.uv_handle_set_data
func (handle *Handle) SetData(data c.Pointer) {}
// llgo:link (*Handle).IsActive C.uv_is_active
func (handle *Handle) IsActive() c.Int {
return 0
}
// llgo:link (*Handle).Close C.uv_close
func (handle *Handle) Close(closeCb CloseCb) {}
// llgo:link (*Handle).SendBufferSize C.uv_send_buffer_size
func (handle *Handle) SendBufferSize(value *c.Int) c.Int {
return 0
}
// llgo:link (*Handle).RecvBufferSize C.uv_recv_buffer_size
func (handle *Handle) RecvBufferSize(value *c.Int) c.Int {
return 0
}
// llgo:link (*Handle).Fileno C.uv_fileno
func (handle *Handle) Fileno(fd *OsFd) c.Int {
return 0
}
//go:linkname UvPipe C.uv_pipe
func UvPipe(fds [2]UvFile, readFlags c.Int, writeFlags c.Int) c.Int {
return 0
}
//go:linkname Socketpair C.uv_socketpair
func Socketpair(_type c.Int, protocol c.Int, socketVector [2]OsSock, flag0 c.Int, flag1 c.Int) c.Int {
return 0
}
// llgo:link (*Handle).IsClosing C.uv_is_closing
func (handle *Handle) IsClosing() c.Int {
return 0
}
// ----------------------------------------------
/* Req related function and method */
//go:linkname ReqSize C.uv_req_size
func ReqSize(reqType ReqType) uintptr
// llgo:link (*Req).GetData C.uv_req_get_data
func (req *Req) GetData() c.Pointer {
return nil
}
// llgo:link (*Req).SetData C.uv_handle_set_data
func (req *Req) SetData(data c.Pointer) {}
// llgo:link (*Req).GetType C.uv_req_get_type
func (req *Req) GetType() ReqType {
return 0
}
//go:linkname TypeName C.uv_req_type_name
func TypeName(reqType ReqType) *c.Char
// ----------------------------------------------
/* Stream related function and method */
// llgo:link (*Stream).GetWriteQueueSize C.uv_stream_get_write_queue_size
func (stream *Stream) GetWriteQueueSize() uintptr {
return 0
}
// llgo:link (*Stream).Listen C.uv_listen
func (stream *Stream) Listen(backlog c.Int, connectionCb ConnectionCb) c.Int {
return 0
}
// llgo:link (*Stream).Accept C.uv_accept
func (server *Stream) Accept(client *Stream) c.Int {
return 0
}
// llgo:link (*Stream).StartRead C.uv_read_start
func (stream *Stream) StartRead(allocCb AllocCb, readCb ReadCb) c.Int {
return 0
}
// llgo:link (*Stream).StopRead C.uv_read_stop
func (stream *Stream) StopRead() c.Int {
return 0
}
// llgo:link (*Write).Write C.uv_write
func (req *Write) Write(stream *Stream, bufs *Buf, nbufs c.Uint, writeCb WriteCb) c.Int {
return 0
}
// llgo:link (*Write).Write2 C.uv_write2
func (req *Write) Write2(stream *Stream, bufs *Buf, nbufs c.Uint, sendStream *Stream, writeCb WriteCb) c.Int {
return 0
}
// llgo:link (*Stream).TryWrite C.uv_try_write
func (stream *Stream) TryWrite(bufs *Buf, nbufs c.Uint) c.Int {
return 0
}
// llgo:link (*Stream).TryWrite2 C.uv_try_write2
func (stream *Stream) TryWrite2(bufs *Buf, nbufs c.Uint, sendStream *Stream) c.Int {
return 0
}
// llgo:link (*Stream).IsReadable C.uv_is_readable
func (stream *Stream) IsReadable() c.Int {
return 0
}
// llgo:link (*Stream).IsWritable C.uv_is_writable
func (stream *Stream) IsWritable() c.Int {
return 0
}
// llgo:link (*Stream).SetBlocking C.uv_stream_set_blocking
func (stream *Stream) SetBlocking(blocking c.Int) c.Int {
return 0
}
// ----------------------------------------------
/* Loop related functions and method. */ /* Loop related functions and method. */
//go:linkname DefaultLoop C.uv_default_loop
func DefaultLoop() *Loop
//go:linkname LoopSize C.uv_loop_size //go:linkname LoopSize C.uv_loop_size
func LoopSize() uintptr func LoopSize() uintptr
//go:linkname Run C.uv_run // llgo:link (*Loop).Run C.uv_run
func Run(loop *Loop, mode RunMode) c.Int func (loop *Loop) Run(mode RunMode) c.Int {
return 0
}
//go:linkname LoopAlive C.uv_loop_alive // llgo:link (*Loop).Alive C.uv_loop_alive
func LoopAlive(loop *Loop) c.Int func (loop *Loop) Alive() c.Int {
return 0
}
//go:linkname LoopClose C.uv_loop_close // void uv_stop(uv_loop_t *loop)
func LoopClose(loop *Loop) c.Int //
// llgo:link (*Loop).Stop C.uv_stop
func (loop *Loop) Stop() {}
//go:linkname LoopConfigure C.uv_loop_configure // llgo:link (*Loop).Close C.uv_loop_close
func LoopConfigure(loop *Loop, option LoopOption, arg c.Int) c.Int func (loop *Loop) Close() c.Int {
return 0
}
//go:linkname LoopDefault C.uv_default_loop // llgo:link (*Loop).Configure C.uv_loop_configure
func LoopDefault() *Loop func (loop *Loop) Configure(option LoopOption, arg c.Int) c.Int {
return 0
}
//go:linkname LoopDelete C.uv_loop_delete // llgo:link LoopDefault C.uv_default_loop
func LoopDelete(loop *Loop) c.Int func LoopDefault() *Loop {
return nil
}
//go:linkname LoopFork C.uv_loop_fork // llgo:link (*Loop).Delete C.uv_loop_delete
func LoopFork(loop *Loop) c.Int func (loop *Loop) Delete() c.Int {
return 0
}
//go:linkname LoopInit C.uv_loop_init // llgo:link (*Loop).Fork C.uv_loop_fork
func LoopInit(loop *Loop) c.Int func (loop *Loop) Fork() c.Int {
return 0
}
//go:linkname LoopNew C.uv_loop_new // llgo:link (*Loop).Init C.uv_loop_init
func LoopNew() *Loop func (loop *Loop) Init() c.Int {
return 0
}
//go:linkname LoopNow C.uv_now // llgo:link LoopNew C.uv_loop_new
func LoopNow(loop *Loop) c.UlongLong func LoopNew() *Loop {
return nil
}
//go:linkname LoopUpdateTime C.uv_update_time // llgo:link (*Loop).Now C.uv_now
func LoopUpdateTime(loop *Loop) func (loop *Loop) Now() c.UlongLong {
return 0
}
//go:linkname LoopBackendFd C.uv_backend_fd // llgo:link (*Loop).UpdateTime C.uv_update_time
func LoopBackendFd(loop *Loop) c.Int func (loop *Loop) UpdateTime() {
// No return value needed for this method
}
//go:linkname LoopBackendTimeout C.uv_backend_timeout // llgo:link (*Loop).BackendFd C.uv_backend_fd
func LoopBackendTimeout(loop *Loop) c.Int func (loop *Loop) BackendFd() c.Int {
return 0
}
//go:linkname LoopWalk C.uv_walk // llgo:link (*Loop).BackendTimeout C.uv_backend_timeout
func LoopWalk(loop *Loop, walkCb WalkCb, arg c.Pointer) func (loop *Loop) BackendTimeout() c.Int {
return 0
}
// llgo:link (*Loop).Walk C.uv_walk
func (loop *Loop) Walk(walkCb WalkCb, arg c.Pointer) {
// No return value needed for this method
}
// ---------------------------------------------- // ----------------------------------------------
@@ -461,28 +251,15 @@ func InitBuf(base *c.Char, len c.Uint) Buf
//go:linkname PollInit C.uv_poll_init //go:linkname PollInit C.uv_poll_init
func PollInit(loop *Loop, handle *Poll, fd OsFd) c.Int func PollInit(loop *Loop, handle *Poll, fd OsFd) c.Int
//go:linkname PollStart C.uv_poll_start
func PollStart(handle *Poll, events c.Int, cb PollCb) c.Int
//go:linkname PollStop C.uv_poll_stop
func PollStop(handle *Poll) c.Int
//go:linkname PollInitSocket C.uv_poll_init_socket //go:linkname PollInitSocket C.uv_poll_init_socket
func PollInitSocket(loop *Loop, handle *Poll, socket c.Int) c.Int func PollInitSocket(loop *Loop, handle *Poll, socket c.Int) c.Int
// ---------------------------------------------- // llgo:link (*Poll).Start C.uv_poll_start
func (handle *Poll) Start(events c.Int, cb PollCb) c.Int {
return 0
}
/* Getaddrinfo related function and method */ // llgo:link (*Poll).Stop C.uv_poll_stop
func (handle *Poll) Stop() c.Int {
//go:linkname Getaddrinfo C.uv_getaddrinfo return 0
func Getaddrinfo(loop *Loop, req *GetAddrInfo, getaddrinfoCb GetaddrinfoCb, node *c.Char, service *c.Char, hints *net.AddrInfo) c.Int }
//go:linkname Freeaddrinfo C.uv_freeaddrinfo
func Freeaddrinfo(addrInfo *net.AddrInfo)
// ----------------------------------------------
/* Getnameinfo related function and method */
//go:linkname Getnameinfo C.uv_getnameinfo
func Getnameinfo(loop *Loop, req *GetNameInfo, getnameinfoCb GetnameinfoCb, addr *net.SockAddr, flags c.Int) c.Int

View File

@@ -65,8 +65,22 @@ type UdpFlags c.Int
/* Handle types. */ /* Handle types. */
// TODO(spongehah): Handle
type Handle struct {
Data c.Pointer
Unused [88]byte
}
// TODO(spongehah): Stream
type Stream struct {
Data c.Pointer
Unused [256]byte
}
// TODO(spongehah): Tcp
type Tcp struct { type Tcp struct {
Unused [264]byte Data c.Pointer
Unused [256]byte
} }
type Udp struct { type Udp struct {
@@ -75,10 +89,38 @@ type Udp struct {
/* Request types. */ /* Request types. */
type Req struct {
Unused [0]byte
}
type UdpSend struct { type UdpSend struct {
Unused [0]byte Unused [0]byte
} }
// TODO(spongehah): Write
type Write struct {
Data c.Pointer
Unused [184]byte
}
// TODO(spongehah): Connect
type Connect struct {
Data c.Pointer
Unused [88]byte
}
type GetAddrInfo struct {
Unused [0]byte
}
type GetNameInfo struct {
Unused [0]byte
}
type Shutdown struct {
Unused [0]byte
}
// ---------------------------------------------- // ----------------------------------------------
/* Function type */ /* Function type */
@@ -95,6 +137,197 @@ type UdpSendCb func(req *UdpSend, status c.Int)
// llgo:type C // llgo:type C
type UdpRecvCb func(handle *Udp, nread c.Long, buf *Buf, addr *net.SockAddr, flags c.Uint) type UdpRecvCb func(handle *Udp, nread c.Long, buf *Buf, addr *net.SockAddr, flags c.Uint)
// llgo:type C
type ReadCb func(stream *Stream, nread c.Long, buf *Buf)
// llgo:type C
type WriteCb func(req *Write, status c.Int)
// llgo:type C
type ConnectionCb func(server *Stream, status c.Int)
// llgo:type C
type ShutdownCb func(req *Shutdown, status c.Int)
// ----------------------------------------------
/* Handle related function and method */
//go:linkname HandleSize C.uv_handle_size
func HandleSize(handleType HandleType) uintptr
//go:linkname HandleTypeName C.uv_handle_type_name
func HandleTypeName(handleType HandleType) *c.Char
// llgo:link (*Handle).Ref C.uv_ref
func (handle *Handle) Ref() {}
// llgo:link (*Handle).Unref C.uv_unref
func (handle *Handle) Unref() {}
// llgo:link (*Handle).HasRef C.uv_has_ref
func (handle *Handle) HasRef() c.Int {
return 0
}
// llgo:link (*Handle).GetType C.uv_handle_get_type
func (handle *Handle) GetType() HandleType {
return 0
}
// llgo:link (*Handle).GetData C.uv_handle_get_data
func (handle *Handle) GetData() c.Pointer {
return nil
}
// llgo:link (*Handle).GetLoop C.uv_handle_get_loop
func (handle *Handle) GetLoop() *Loop {
return nil
}
// llgo:link (*Handle).SetData C.uv_handle_set_data
func (handle *Handle) SetData(data c.Pointer) {}
// llgo:link (*Handle).IsActive C.uv_is_active
func (handle *Handle) IsActive() c.Int {
return 0
}
// llgo:link (*Handle).Close C.uv_close
func (handle *Handle) Close(closeCb CloseCb) {}
// llgo:link (*Handle).SendBufferSize C.uv_send_buffer_size
func (handle *Handle) SendBufferSize(value *c.Int) c.Int {
return 0
}
// llgo:link (*Handle).RecvBufferSize C.uv_recv_buffer_size
func (handle *Handle) RecvBufferSize(value *c.Int) c.Int {
return 0
}
// llgo:link (*Handle).Fileno C.uv_fileno
func (handle *Handle) Fileno(fd *OsFd) c.Int {
return 0
}
// llgo:link (*Handle).IsClosing C.uv_is_closing
func (handle *Handle) IsClosing() c.Int {
return 0
}
// llgo:link (*Handle).IsReadable C.uv_is_readable
func (handle *Handle) IsReadable() c.Int {
return 0
}
// llgo:link (*Handle).IsWritable C.uv_is_writable
func (handle *Handle) IsWritable() c.Int {
return 0
}
//go:linkname Pipe C.uv_pipe
func Pipe(fds [2]File, readFlags c.Int, writeFlags c.Int) c.Int {
return 0
}
//go:linkname Socketpair C.uv_socketpair
func Socketpair(_type c.Int, protocol c.Int, socketVector [2]OsSock, flag0 c.Int, flag1 c.Int) c.Int {
return 0
}
// ----------------------------------------------
/* Req related function and method */
//go:linkname ReqSize C.uv_req_size
func ReqSize(reqType ReqType) uintptr
//go:linkname TypeName C.uv_req_type_name
func TypeName(reqType ReqType) *c.Char
// llgo:link (*Req).GetData C.uv_req_get_data
func (req *Req) GetData() c.Pointer {
return nil
}
// llgo:link (*Req).SetData C.uv_req_set_data
func (req *Req) SetData(data c.Pointer) {}
// llgo:link (*Req).GetType C.uv_req_get_type
func (req *Req) GetType() ReqType {
return 0
}
// ----------------------------------------------
/* Stream related function and method */
// llgo:link (*Stream).GetWriteQueueSize C.uv_stream_get_write_queue_size
func (stream *Stream) GetWriteQueueSize() uintptr {
return 0
}
// llgo:link (*Stream).Listen C.uv_listen
func (stream *Stream) Listen(backlog c.Int, connectionCb ConnectionCb) c.Int {
return 0
}
// llgo:link (*Stream).Accept C.uv_accept
func (server *Stream) Accept(client *Stream) c.Int {
return 0
}
// llgo:link (*Stream).StartRead C.uv_read_start
func (stream *Stream) StartRead(allocCb AllocCb, readCb ReadCb) c.Int {
return 0
}
// llgo:link (*Stream).StopRead C.uv_read_stop
func (stream *Stream) StopRead() c.Int {
return 0
}
// llgo:link (*Write).Write C.uv_write
func (req *Write) Write(stream *Stream, bufs *Buf, nbufs c.Uint, writeCb WriteCb) c.Int {
return 0
}
// llgo:link (*Write).Write2 C.uv_write2
func (req *Write) Write2(stream *Stream, bufs *Buf, nbufs c.Uint, sendStream *Stream, writeCb WriteCb) c.Int {
return 0
}
// llgo:link (*Stream).TryWrite C.uv_try_write
func (stream *Stream) TryWrite(bufs *Buf, nbufs c.Uint) c.Int {
return 0
}
// llgo:link (*Stream).TryWrite2 C.uv_try_write2
func (stream *Stream) TryWrite2(bufs *Buf, nbufs c.Uint, sendStream *Stream) c.Int {
return 0
}
// llgo:link (*Stream).IsReadable C.uv_is_readable
func (stream *Stream) IsReadable() c.Int {
return 0
}
// llgo:link (*Stream).IsWritable C.uv_is_writable
func (stream *Stream) IsWritable() c.Int {
return 0
}
// llgo:link (*Stream).SetBlocking C.uv_stream_set_blocking
func (stream *Stream) SetBlocking(blocking c.Int) c.Int {
return 0
}
//go:linkname StreamShutdown C.uv_shutdown
func StreamShutdown(shutdown *Shutdown, stream *Stream, shutdownCb ShutdownCb) c.Int {
return 0
}
// ---------------------------------------------- // ----------------------------------------------
/* Tcp related function and method */ /* Tcp related function and method */
@@ -145,6 +378,11 @@ func (tcp *Tcp) CloseReset(closeCb CloseCb) c.Int {
return 0 return 0
} }
// llgo:link (*Tcp).GetIoWatcherFd C.uv_tcp_get_io_watcher_fd
func (tcp *Tcp) GetIoWatcherFd() c.Int {
return 0
}
//go:linkname TcpConnect C.uv_tcp_connect //go:linkname TcpConnect C.uv_tcp_connect
func TcpConnect(req *Connect, tcp *Tcp, addr *net.SockAddr, connectCb ConnectCb) c.Int func TcpConnect(req *Connect, tcp *Tcp, addr *net.SockAddr, connectCb ConnectCb) c.Int
@@ -218,9 +456,6 @@ func (udp *Udp) SetTTL(ttl c.Int) c.Int {
return 0 return 0
} }
//go:linkname Send C.uv_udp_send
func Send(req *UdpSend, udp *Udp, bufs *Buf, nbufs c.Uint, addr *net.SockAddr, sendCb UdpSendCb) c.Int
// llgo:link (*Udp).TrySend C.uv_udp_try_send // llgo:link (*Udp).TrySend C.uv_udp_try_send
func (udp *Udp) TrySend(bufs *Buf, nbufs c.Uint, addr *net.SockAddr) c.Int { func (udp *Udp) TrySend(bufs *Buf, nbufs c.Uint, addr *net.SockAddr) c.Int {
return 0 return 0
@@ -251,8 +486,13 @@ func (udp *Udp) GetSendQueueCount() uintptr {
return 0 return 0
} }
//go:linkname Send C.uv_udp_send
func Send(req *UdpSend, udp *Udp, bufs *Buf, nbufs c.Uint, addr *net.SockAddr, sendCb UdpSendCb) c.Int
// ---------------------------------------------- // ----------------------------------------------
/* DNS related function and method */
//go:linkname Ip4Addr C.uv_ip4_addr //go:linkname Ip4Addr C.uv_ip4_addr
func Ip4Addr(ip *c.Char, port c.Int, addr *net.SockaddrIn) c.Int func Ip4Addr(ip *c.Char, port c.Int, addr *net.SockaddrIn) c.Int
@@ -273,3 +513,20 @@ func InetNtop(af c.Int, src c.Pointer, dst *c.Char, size uintptr) c.Int
//go:linkname InetPton C.uv_inet_pton //go:linkname InetPton C.uv_inet_pton
func InetPton(af c.Int, src *c.Char, dst c.Pointer) c.Int func InetPton(af c.Int, src *c.Char, dst c.Pointer) c.Int
// ----------------------------------------------
/* Getaddrinfo related function and method */
//go:linkname Getaddrinfo C.uv_getaddrinfo
func Getaddrinfo(loop *Loop, req *GetAddrInfo, getaddrinfoCb GetaddrinfoCb, node *c.Char, service *c.Char, hints *net.AddrInfo) c.Int
//go:linkname Freeaddrinfo C.uv_freeaddrinfo
func Freeaddrinfo(addrInfo *net.AddrInfo)
// ----------------------------------------------
/* Getnameinfo related function and method */
//go:linkname Getnameinfo C.uv_getnameinfo
func Getnameinfo(loop *Loop, req *GetNameInfo, getnameinfoCb GetnameinfoCb, addr *net.SockAddr, flags c.Int) c.Int

View File

@@ -26,8 +26,17 @@ type SignalCb func(handle *Signal, sigNum c.Int)
//go:linkname SignalInit C.uv_signal_init //go:linkname SignalInit C.uv_signal_init
func SignalInit(loop *Loop, handle *Signal) c.Int func SignalInit(loop *Loop, handle *Signal) c.Int
//go:linkname SignalStart C.uv_signal_start // llgo:link (*Signal).Start C.uv_signal_start
func SignalStart(handle *Signal, cb SignalCb, signum c.Int) c.Int func (handle *Signal) Start(cb SignalCb, signum c.Int) c.Int {
return 0
}
//go:linkname SignalStartOneshot C.uv_signal_start_oneshot // llgo:link (*Signal).StartOneshot C.uv_signal_start_oneshot
func SignalStartOneshot(handle *Signal, cb SignalCb, signum c.Int) c.Int func (handle *Signal) StartOneshot(cb SignalCb, signum c.Int) c.Int {
return 0
}
// llgo:link (*Signal).Stop C.uv_signal_stop
func (handle *Signal) Stop() c.Int {
return 0
}

View File

@@ -10,6 +10,7 @@ import (
/* Handle types. */ /* Handle types. */
// TODO(spongehah): Timer
type Timer struct { type Timer struct {
Unused [0]byte Unused [0]byte
} }

View File

@@ -0,0 +1,42 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/lua"
)
func coroutineFunc(L *lua.State) c.Int {
c.Printf(c.Str("Coroutine started\n"))
L.Yield(0) // Pause the coroutine
c.Printf(c.Str("Coroutine resumed\n"))
return 0
}
func main() {
L := lua.Newstate()
defer L.Close()
L.Openlibs()
co := L.Newthread()
L.Pushcfunction(coroutineFunc)
L.Xmove(co, 1)
var nres c.Int
c.Printf(c.Str("Resuming coroutine for the first time\n"))
result := co.Resume(nil, 0, &nres)
if result == lua.YIELD {
c.Printf(c.Str("Coroutine yielded\n"))
result = co.Resume(nil, 0, &nres)
if result == 0 {
c.Printf(c.Str("Coroutine finished\n"))
}
}
}
/* Expected output:
Resuming coroutine for the first time
Coroutine started
Coroutine yielded
Coroutine finished
*/

View File

@@ -36,8 +36,8 @@ func main() {
// Resume coroutine and handle yields // Resume coroutine and handle yields
for { for {
status = co.Resume(nil, 0, &nres) status = co.Resume(nil, 0, &nres)
c.Printf(c.Str("Resuming coroutine %d...\n"), status)
if status == lua.YIELD { if status == lua.YIELD {
c.Printf(c.Str("Resuming coroutine %d...\n"), status)
yieldValue := co.Tointeger(-1) yieldValue := co.Tointeger(-1)
c.Printf(c.Str("Yield value: %d\n"), yieldValue) c.Printf(c.Str("Yield value: %d\n"), yieldValue)
co.Pop(1) // Clean up the stack co.Pop(1) // Clean up the stack
@@ -58,3 +58,23 @@ func main() {
finalStatus := co.Status() finalStatus := co.Status()
c.Printf(c.Str("Final status of coroutine: %d\n"), finalStatus) c.Printf(c.Str("Final status of coroutine: %d\n"), finalStatus)
} }
/* Expected output:
Resuming coroutine...
Resuming coroutine 1...
Yield value: 1
Coroutine is yieldable.
Resuming coroutine 1...
Yield value: 2
Coroutine is yieldable.
Resuming coroutine 1...
Yield value: 3
Coroutine is yieldable.
Resuming coroutine 1...
Yield value: 4
Coroutine is yieldable.
Resuming coroutine 1...
Yield value: 5
Coroutine is yieldable.
Final status of coroutine: 0
*/

View File

@@ -0,0 +1,125 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/lua"
)
func toString(L *lua.State) c.Int {
L.Pushstring(c.Str("Hello from metatable!"))
return 1
}
func printStack(L *lua.State, message string) {
top := L.Gettop()
c.Printf(c.Str("%s - Stack size: %d\n"), c.AllocaCStr(message), c.Int(top))
for i := c.Int(1); i <= top; i++ {
t := L.Type(i)
switch t {
case c.Int(lua.STRING):
c.Printf(c.Str(" %d: string: %s\n"), c.Int(i), L.Tostring(i))
case c.Int(lua.BOOLEAN):
c.Printf(c.Str(" %d: boolean: %v\n"), c.Int(i), L.Toboolean(i))
case c.Int(lua.NUMBER):
c.Printf(c.Str(" %d: number: %f\n"), c.Int(i), L.Tonumber(i))
default:
c.Printf(c.Str(" %d: %s\n"), c.Int(i), L.Typename(t))
}
}
}
func main() {
L := lua.Newstate()
defer L.Close()
L.Openlibs()
L.Newtable()
printStack(L, "After creating main table")
L.Newtable()
printStack(L, "After creating metatable")
L.Pushcfunction(toString)
printStack(L, "After Push CFunction")
L.Setfield(-2, c.Str("__tostring"))
printStack(L, "After setting __tostring")
if L.Setmetatable(-2) == 0 {
c.Printf(c.Str("Failed to set metatable\n"))
}
printStack(L, "After setting metatable")
L.Setglobal(c.Str("obj"))
printStack(L, "After setting global obj")
testcode := c.Str(`
if obj == nil then
print('obj is not defined')
else
local mt = getmetatable(obj)
if not mt then
print('Metatable not set')
elseif not mt.__tostring then
print('__tostring not set in metatable')
else
print(mt.__tostring(obj))
end
end
`)
if L.Dostring(testcode) != lua.OK {
c.Printf(c.Str("Error: %s\n"), L.Tostring(-1))
}
L.Getglobal(c.Str("obj"))
if L.Getmetatable(-1) != 0 {
c.Printf(c.Str("Metatable get success\n"))
L.Pushstring(c.Str("__tostring"))
L.Gettable(-2)
if L.Isfunction(-1) {
c.Printf(c.Str("__tostring function found in metatable\n"))
if L.Iscfunction(-1) != 0 {
c.Printf(c.Str("__tostring is a C function\n"))
cfunc := L.Tocfunction(-1)
if cfunc != nil {
c.Printf(c.Str("Successfully retrieved __tostring C function pointer\n"))
L.Pushcfunction(cfunc)
if L.Call(0, 1) == lua.OK {
result := L.Tostring(-1)
c.Printf(c.Str("Result of calling __tostring: %s\n"), result)
}
}
}
} else {
c.Printf(c.Str("__tostring function not found in metatable\n"))
}
} else {
c.Printf(c.Str("No metatable found using GetTable\n"))
}
}
/* Expected output:
After creating main table - Stack size: 1
1: table
After creating metatable - Stack size: 2
1: table
2: table
After Push CFunction - Stack size: 3
1: table
2: table
3: function
After setting __tostring - Stack size: 2
1: table
2: table
After setting metatable - Stack size: 1
1: table
After setting global obj - Stack size: 0
Hello from metatable!
Metatable get success
__tostring function found in metatable
__tostring is a C function
Successfully retrieved __tostring C function pointer
Result of calling __tostring: Hello from metatable!
*/

View File

@@ -41,17 +41,17 @@ type State struct {
// ** basic types // ** basic types
// */ // */
const ( const (
NONE = int(-1) NONE c.Int = -1
NIL = int(0) NIL c.Int = 0
BOOLEAN = int(1) BOOLEAN c.Int = 1
LIGHTUSERDATA = int(2) LIGHTUSERDATA c.Int = 2
NUMBER = int(3) NUMBER c.Int = 3
STRING = int(4) STRING c.Int = 4
TABLE = int(5) TABLE c.Int = 5
FUNCTION = int(6) FUNCTION c.Int = 6
USERDATA = int(7) USERDATA c.Int = 7
THREAD = int(8) THREAD c.Int = 8
UMTYPES = int(9) UMTYPES c.Int = 9
) )
// /* minimum Lua stack available to a C function */ // /* minimum Lua stack available to a C function */
@@ -78,13 +78,15 @@ type Integer = c.Int
type Unsigned = c.Uint type Unsigned = c.Uint
// /* type for continuation-function contexts */ // /* type for continuation-function contexts */
// TODO(zzy): Context may not be c.Int type KContext = c.Pointer
type KContext c.Int
// /* // /*
// ** Type for C functions registered with Lua // ** Type for C functions registered with Lua
// */ // */
// llgo:type C
type CFunction func(L *State) c.Int
// /* // /*
// ** Type for continuation functions // ** Type for continuation functions
// */ // */
@@ -144,7 +146,6 @@ type KFunction func(L *State, status c.Int, ctx KContext) c.Int
func (L *State) Close() {} func (L *State) Close() {}
// State *(lua_newstate) (lua_Alloc f, void *ud); // State *(lua_newstate) (lua_Alloc f, void *ud);
// State *(lua_newthread) (State *L);
// 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 }
@@ -185,9 +186,6 @@ func (L *State) Xmove(to *State, n c.Int) {}
// /* // /*
// ** access functions (stack -> C) // ** access functions (stack -> C)
// */ // */
// LUA_API int (lua_isinteger) (State *L, int idx);
// llgo:link (*State).Isinteger C.lua_isinteger
func (L *State) Isinteger(idx c.Int) c.Int { return 0 }
// 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 }
@@ -195,11 +193,17 @@ func (L *State) Isnumber(idx c.Int) c.Int { return 0 }
// llgo:link (*State).Isstring C.lua_isstring // llgo:link (*State).Isstring C.lua_isstring
func (L *State) Isstring(idx c.Int) c.Int { return 0 } func (L *State) Isstring(idx c.Int) c.Int { return 0 }
// TODO(zzy):add to demo // llgo:link (*State).Iscfunction C.lua_iscfunction
func (L *State) Iscfunction(idx c.Int) c.Int { return 0 }
// llgo:link (*State).Isinteger C.lua_isinteger
func (L *State) Isinteger(idx c.Int) c.Int { return 0 }
// LUA_API int (lua_isuserdata) (State *L, int idx);
// 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 }
// TODO(zzy)
// llgo:link (*State).Typename C.lua_typename // llgo:link (*State).Typename C.lua_typename
func (L *State) Typename(tp c.Int) *c.Char { return nil } func (L *State) Typename(tp c.Int) *c.Char { return nil }
@@ -215,11 +219,11 @@ func (L *State) Toboolean(idx c.Int) bool { return false }
// llgo:link (*State).Tolstring C.lua_tolstring // llgo:link (*State).Tolstring C.lua_tolstring
func (L *State) Tolstring(idx c.Int, len *c.Ulong) *c.Char { return nil } func (L *State) Tolstring(idx c.Int, len *c.Ulong) *c.Char { return nil }
// LUA_API int (lua_iscfunction) (State *L, int idx);
// LUA_API int (lua_isuserdata) (State *L, int idx);
// LUA_API lua_Unsigned (lua_rawlen) (State *L, int idx); // LUA_API lua_Unsigned (lua_rawlen) (State *L, int idx);
// LUA_API lua_CFunction (lua_tocfunction) (State *L, int idx);
// llgo:link (*State).Tocfunction C.lua_tocfunction
func (L *State) Tocfunction(idx c.Int) CFunction { return nil }
// LUA_API void *(lua_touserdata) (State *L, int idx); // LUA_API void *(lua_touserdata) (State *L, int idx);
// LUA_API State *(lua_tothread) (State *L, int idx); // LUA_API State *(lua_tothread) (State *L, int idx);
// LUA_API const void *(lua_topointer) (State *L, int idx); // LUA_API const void *(lua_topointer) (State *L, int idx);
@@ -240,24 +244,21 @@ func (L *State) Pushnumber(n Number) {}
// llgo:link (*State).Pushinteger C.lua_pushinteger // llgo:link (*State).Pushinteger C.lua_pushinteger
func (L *State) Pushinteger(n Integer) {} func (L *State) Pushinteger(n Integer) {}
// llgo:link (*State).Pushstring C.lua_pushstring
func (L *State) Pushstring(s *c.Char) *c.Char {
return nil
}
// llgo:link (*State).Pushlstring C.lua_pushlstring // llgo:link (*State).Pushlstring C.lua_pushlstring
func (L *State) Pushlstring(s *c.Char, len c.Ulong) *c.Char { func (L *State) Pushlstring(s *c.Char, len c.Ulong) *c.Char { return nil }
return nil
} // llgo:link (*State).Pushstring C.lua_pushstring
func (L *State) Pushstring(s *c.Char) *c.Char { return nil }
// llgo:link (*State).Pushfstring C.lua_pushfstring // llgo:link (*State).Pushfstring C.lua_pushfstring
func (L *State) Pushfstring(format *c.Char, __llgo_va_list ...any) *c.Char { return nil } func (L *State) Pushfstring(format *c.Char, __llgo_va_list ...any) *c.Char { return nil }
// llgo:link (*State).Pushcclosure C.lua_pushcclosure
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) {}
//const char *(lua_pushvfstring) (State *L, const char *fmt,va_list argp);
//void (lua_pushcclosure) (State *L, lua_CFunction fn, int n);
//void (lua_pushlightuserdata) (State *L, void *p); //void (lua_pushlightuserdata) (State *L, void *p);
//int (lua_pushthread) (State *L); //int (lua_pushthread) (State *L);
@@ -274,23 +275,25 @@ 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 }
// llgo:link (*State).Createtable C.lua_createtable
func (L *State) Createtable(narr c.Int, nrec c.Int) {}
// LUA_API int (lua_geti) (State *L, int idx, lua_Integer n); // LUA_API int (lua_geti) (State *L, int idx, lua_Integer n);
// LUA_API int (lua_rawget) (State *L, int idx); // LUA_API int (lua_rawget) (State *L, int idx);
// LUA_API int (lua_rawgeti) (State *L, int idx, lua_Integer n); // LUA_API int (lua_rawgeti) (State *L, int idx, lua_Integer n);
// LUA_API int (lua_rawgetp) (State *L, int idx, const void *p); // LUA_API int (lua_rawgetp) (State *L, int idx, const void *p);
// llgo:link (*State).Createtable C.lua_createtable
func (L *State) Createtable(narr c.Int, nrec c.Int) {}
// LUA_API void *(lua_newuserdatauv) (State *L, size_t sz, int nuvalue); // LUA_API void *(lua_newuserdatauv) (State *L, size_t sz, int nuvalue);
// LUA_API int (lua_getmetatable) (State *L, int objindex);
// llgo:link (*State).Getmetatable C.lua_getmetatable
func (L *State) Getmetatable(objindex c.Int) c.Int { return 0 }
// LUA_API int (lua_getiuservalue) (State *L, int idx, int n); // LUA_API int (lua_getiuservalue) (State *L, int idx, int n);
// /* // /*
// ** set functions (stack -> Lua) // ** set functions (stack -> Lua)
// */ // */
// TODO(zzy):add to demo
// 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) {}
@@ -304,25 +307,34 @@ func (L *State) Setfield(idx c.Int, k *c.Char) {}
//void (lua_rawset) (State *L, int idx); //void (lua_rawset) (State *L, int idx);
//void (lua_rawseti) (State *L, int idx, lua_Integer n); //void (lua_rawseti) (State *L, int idx, lua_Integer n);
//void (lua_rawsetp) (State *L, int idx, const void *p); //void (lua_rawsetp) (State *L, int idx, const void *p);
//int (lua_setmetatable) (State *L, int objindex);
// llgo:link (*State).Setmetatable C.lua_setmetatable
func (L *State) Setmetatable(objindex c.Int) c.Int { return 0 }
//int (lua_setiuservalue) (State *L, int idx, int n); //int (lua_setiuservalue) (State *L, int idx, int n);
// /* // /*
// ** '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
func (L *State) Callk(nargs c.Int, nresults c.Int, ctx KContext, k KFunction) c.Int {
return 0
}
func (L *State) Call(nargs c.Int, nresults c.Int) c.Int {
return L.Callk(nargs, nresults, nil, nil)
}
// llgo:link (*State).Pcallk C.lua_pcallk // llgo:link (*State).Pcallk C.lua_pcallk
func (L *State) Pcallk(nargs c.Int, nresults c.Int, errfunc c.Int, ctx KContext, k *KFunction) c.Int { func (L *State) Pcallk(nargs c.Int, nresults c.Int, errfunc c.Int, ctx KContext, k KFunction) c.Int {
return 0 return 0
} }
func (L *State) Pcall(nargs c.Int, nresults c.Int, errfunc c.Int) c.Int { func (L *State) Pcall(nargs c.Int, nresults c.Int, errfunc c.Int) c.Int {
return L.Pcallk(nargs, nresults, errfunc, KContext(c.Int(0)), nil) return L.Pcallk(nargs, nresults, errfunc, nil, nil)
} }
// void (lua_callk) (State *L, int nargs, int nresults, lua_KContext ctx, lua_KFunction k);
// #define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL)
// int (lua_load) (State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode); // int (lua_load) (State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode);
// int (lua_dump) (State *L, lua_Writer writer, void *data, int strip); // int (lua_dump) (State *L, lua_Writer writer, void *data, int strip);
@@ -340,9 +352,9 @@ func (L *State) Status() c.Int { return 0 }
// llgo:link (*State).Isyieldable C.lua_isyieldable // llgo:link (*State).Isyieldable C.lua_isyieldable
func (L *State) Isyieldable() c.Int { return 0 } func (L *State) Isyieldable() c.Int { return 0 }
// TODO(zzy) // llgo:link (*State).Yieldk C.lua_yieldk
// int (lua_yieldk) (State *L, int nresults, lua_KContext ctx, lua_KFunction k); func (L *State) Yieldk(nresults c.Int, ctx KContext, k KFunction) c.Int { return 0 }
// #define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL) func (L *State) Yield(nresults c.Int) c.Int { return L.Yieldk(nresults, nil, nil) }
// /* // /*
// ** Warning-related functions // ** Warning-related functions
@@ -396,11 +408,17 @@ func (L *State) Next(idx c.Int) c.Int { return 0 }
// ** =============================================================== // ** ===============================================================
// */ // */
func (L *State) Tonumber(idx c.Int) Number { return L.Tonumberx(idx, nil) } // #define lua_getextraspace(L) ((void *)((char *)(L) - LUA_EXTRASPACE))
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) Tonumber(idx c.Int) Number { return L.Tonumberx(idx, nil) }
func (L *State) Pop(n c.Int) { L.Settop(-(n) - 1) } func (L *State) Tostring(idx c.Int) *c.Char { return L.Tolstring(idx, nil) }
func (L *State) Newtable() { L.Createtable(0, 0) } 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) Newtable() { L.Createtable(0, 0) }
// #define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
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) }
func (L *State) Istable(n c.Int) bool { return L.Type(n) == c.Int(TABLE) } func (L *State) Istable(n c.Int) bool { return L.Type(n) == c.Int(TABLE) }
func (L *State) Islightuserdata(n c.Int) bool { return L.Type(n) == c.Int(LIGHTUSERDATA) } func (L *State) Islightuserdata(n c.Int) bool { return L.Type(n) == c.Int(LIGHTUSERDATA) }
@@ -410,20 +428,11 @@ 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 }
// #define lua_getextraspace(L) ((void *)((char *)(L) - LUA_EXTRASPACE))
// #define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
// #define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)
// #define lua_pushliteral(L, s) lua_pushstring(L, "" s) // #define lua_pushliteral(L, s) lua_pushstring(L, "" s)
// #define lua_pushglobaltable(L) ((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)) // #define lua_pushglobaltable(L) ((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS))
// #define lua_insert(L,idx) lua_rotate(L, (idx), 1) // #define lua_insert(L,idx) lua_rotate(L, (idx), 1)
// #define lua_remove(L,idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1)) // #define lua_remove(L,idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1))
// #define lua_replace(L,idx) (lua_copy(L, -1, (idx)), lua_pop(L, 1)) // #define lua_replace(L,idx) (lua_copy(L, -1, (idx)), lua_pop(L, 1))
// /* }============================================================== */ // /* }============================================================== */

View File

@@ -17,7 +17,7 @@
package net package net
import ( import (
_ "unsafe" "unsafe"
"github.com/goplus/llgo/c" "github.com/goplus/llgo/c"
) )
@@ -97,6 +97,13 @@ const (
EAI_OVERFLOW /* argument buffer overflow */ EAI_OVERFLOW /* argument buffer overflow */
) )
const (
ALIGNSIZE = unsafe.Sizeof(c.LongLong(0))
MAXSIZE = 128
PAD1_SIZE = ALIGNSIZE - unsafe.Sizeof(byte(0)) - unsafe.Sizeof(byte(0))
PAD2_SIZE = MAXSIZE - unsafe.Sizeof(byte(0)) - unsafe.Sizeof(byte(0)) - PAD1_SIZE - ALIGNSIZE
)
// (TODO) merge to inet // (TODO) merge to inet
const INET_ADDRSTRLEN = 16 const INET_ADDRSTRLEN = 16
@@ -117,6 +124,14 @@ type SockaddrIn6 struct {
ScopeId c.Uint ScopeId c.Uint
} }
type SockaddrStorage struct {
Len uint8
Family uint8
pad1 [PAD1_SIZE]c.Char
align c.LongLong
pad2 [PAD2_SIZE]c.Char
}
type InAddr struct { type InAddr struct {
Addr c.Uint Addr c.Uint
} }
@@ -171,6 +186,9 @@ func Send(c.Int, c.Pointer, uintptr, c.Int) c.Long
//go:linkname Recv C.recv //go:linkname Recv C.recv
func Recv(c.Int, c.Pointer, uintptr, c.Int) c.Long func Recv(c.Int, c.Pointer, uintptr, c.Int) c.Long
//go:linkname SetSockOpt C.setsockopt
func SetSockOpt(socket c.Int, level c.Int, optionName c.Int, optionValue c.Pointer, sockLen c.Uint) c.Int
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
type AddrInfo struct { type AddrInfo struct {
@@ -196,8 +214,27 @@ func swapInt16(data uint16) uint16 {
return (data << 8) | (data >> 8) 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 { func Htons(x uint16) uint16 {
return swapInt16(x) 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)
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@@ -0,0 +1,44 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/openssl"
)
func newInt(n openssl.BN_ULONG) *openssl.BIGNUM {
ret := openssl.BNNew()
ret.SetWord(n)
return ret
}
func main() {
ctx := openssl.BN_CTXNew()
defer ctx.Free()
// Initialize two big ints with the first two numbers in the sequence.
a := newInt(0)
b := newInt(1)
defer a.Free()
defer b.Free()
// Initialize limit as 10^99, the smallest integer with 100 digits.
v10, v99 := newInt(10), newInt(99)
defer v10.Free()
defer v99.Free()
limit := openssl.BNNew()
defer limit.Free()
limit.Exp(v10, v99, ctx)
// Loop while a is smaller than 1e100.
for a.Cmp(limit) < 0 {
// Compute the next Fibonacci number, storing it in a.
a.Add(a, b)
// Swap a and b so that b is the next number in the sequence.
a, b = b, a
}
cstr := a.CStr()
c.Printf(c.Str("%s\n"), cstr) // 100-digit Fibonacci number
openssl.FreeCStr(cstr)
}

View File

@@ -0,0 +1,40 @@
package main
import (
"fmt"
"unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/openssl"
)
func main() {
str := "Hello, World!"
key := "123456"
var lenKey = len(key)
var digest = make([]byte, openssl.EVP_MAX_MD_SIZE)
var digestLen c.Uint
ctx := openssl.NewHMAC_CTX()
if ctx == nil {
c.Fprintf(c.Stderr, c.Str("%s\n"), c.Str("Error creating HMAC_CTX"))
return
}
defer ctx.Free()
var ret c.Int = ctx.InitEx(unsafe.Pointer(unsafe.StringData(key)), c.Int(lenKey), openssl.EVP_sha256(), nil)
if ret == 0 {
c.Fprintf(c.Stderr, c.Str("%s\n"), c.Str("Error initializing HMAC_CTX"))
return
}
ret = ctx.UpdateString(str)
if ret == 0 {
c.Fprintf(c.Stderr, c.Str("%s\n"), c.Str("Error updating HMAC_CTX"))
return
}
ret = ctx.Final(unsafe.SliceData(digest), &digestLen)
if ret == 0 {
c.Fprintf(c.Stderr, c.Str("%s\n"), c.Str("Error finalizing HMAC_CTX"))
return
}
fmt.Printf("HMAC:%x\n", digest[:digestLen])
}

View File

@@ -0,0 +1,18 @@
package main
import (
"fmt"
"unsafe"
"github.com/goplus/llgo/c/openssl"
)
func main() {
var md5 openssl.MD5_CTX
var h = make([]byte, openssl.MD5_LBLOCK)
md5.Init()
md5.UpdateString("The fog is getting thicker!")
md5.UpdateString("And Leon's getting laaarger!")
md5.Final(unsafe.SliceData(h))
fmt.Printf("%x", h)
}

View File

@@ -0,0 +1,17 @@
package main
import (
"fmt"
"github.com/goplus/llgo/c/openssl"
)
func main() {
b := make([]byte, 10)
openssl.RANDBytes(b)
fmt.Printf("%x\n", b)
openssl.RANDPrivBytes(b)
fmt.Printf("%x\n", b)
}

View File

@@ -0,0 +1,68 @@
package main
import (
"fmt"
"unsafe"
"github.com/goplus/llgo/c/openssl"
)
func main() {
str := "His money is twice tainted:"
var sha1 openssl.SHA_CTX
sha1.Init()
sha1.UpdateString(str)
h1 := make([]byte, openssl.SHA_DIGEST_LENGTH)
sha1.Final(unsafe.SliceData(h1))
fmt.Printf("%x\n", h1)
h2 := make([]byte, openssl.SHA_DIGEST_LENGTH)
openssl.SHA1String(str, unsafe.SliceData(h2))
fmt.Printf("%x\n", h2)
var sha256 openssl.SHA256_CTX
sha256.Init()
sha256.UpdateString(str)
h3 := make([]byte, openssl.SHA256_DIGEST_LENGTH)
sha256.Final(unsafe.SliceData(h3))
fmt.Printf("%x\n", h3)
h4 := make([]byte, openssl.SHA256_DIGEST_LENGTH)
openssl.SHA256String(str, unsafe.SliceData(h4))
fmt.Printf("%x\n", h4)
var sha512 openssl.SHA512_CTX
sha512.Init()
sha512.UpdateString("His money is twice tainted:")
h5 := make([]byte, openssl.SHA512_DIGEST_LENGTH)
sha512.Final(unsafe.SliceData(h5))
fmt.Printf("%x\n", h5)
h6 := make([]byte, openssl.SHA512_DIGEST_LENGTH)
openssl.SHA512String(str, unsafe.SliceData(h6))
fmt.Printf("%x\n", h6)
var sha224 openssl.SHA224_CTX
sha224.Init()
sha224.UpdateString(str)
h7 := make([]byte, openssl.SHA224_DIGEST_LENGTH)
sha224.Final(unsafe.SliceData(h7))
fmt.Printf("%x\n", h7)
h8 := make([]byte, openssl.SHA224_DIGEST_LENGTH)
openssl.SHA224String(str, unsafe.SliceData(h8))
fmt.Printf("%x\n", h8)
var sha384 openssl.SHA384_CTX
sha384.Init()
sha384.UpdateString(str)
h9 := make([]byte, openssl.SHA384_DIGEST_LENGTH)
sha384.Final(unsafe.SliceData(h9))
fmt.Printf("%x\n", h9)
h10 := make([]byte, openssl.SHA384_DIGEST_LENGTH)
openssl.SHA384String(str, unsafe.SliceData(h10))
fmt.Printf("%x\n", h10)
}

View File

@@ -0,0 +1,5 @@
#include <openssl/crypto.h>
void opensslFree(void *ptr) {
OPENSSL_free(ptr);
}

61
c/openssl/bio.go Normal file
View File

@@ -0,0 +1,61 @@
/*
* 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 openssl
import (
"unsafe"
"github.com/goplus/llgo/c"
)
// -----------------------------------------------------------------------------
type BIO struct {
Unused [0]byte
}
// BIO *BIO_new_mem_buf(const void *buf, int len);
//
//go:linkname BIONewMemBuf C.BIO_new_mem_buf
func BIONewMemBuf(buf unsafe.Pointer, len c.Int) *BIO
// int BIO_free(BIO *a);
//
// llgo:link (*BIO).Free C.BIO_free
func (*BIO) Free() c.Int { return 0 }
// int BIO_up_ref(BIO *a);
//
// llgo:link (*BIO).UpRef C.BIO_up_ref
func (*BIO) UpRef() c.Int { return 0 }
// int BIO_read_ex(BIO *b, void *data, size_t dlen, size_t *readbytes);
//
// llgo:link (*BIO).ReadEx C.BIO_read_ex
func (*BIO) ReadEx(data unsafe.Pointer, dlen uintptr, readbytes *uintptr) c.Int { return 0 }
// int BIO_write(BIO *b, const void *data, int dlen);
//
// llgo:link (*BIO).Write C.BIO_write
func (*BIO) Write(data unsafe.Pointer, dlen c.Int) c.Int { return 0 }
// int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written);
//
// llgo:link (*BIO).WriteEx C.BIO_write_ex
func (*BIO) WriteEx(data unsafe.Pointer, dlen uintptr, written *uintptr) c.Int { return 0 }
// -----------------------------------------------------------------------------

409
c/openssl/bn.go Normal file
View File

@@ -0,0 +1,409 @@
/*
* 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 openssl
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
type BN_ULONG = uint64
// -----------------------------------------------------------------------------
type BN_CTX struct {
Unused [0]byte
}
// BN_CTX *BN_CTX_new(void);
//
//go:linkname BN_CTXNew C.BN_CTX_new
func BN_CTXNew() *BN_CTX
// BN_CTX *BN_CTX_secure_new(void);
//
//go:linkname BN_CTXSecureNew C.BN_CTX_secure_new
func BN_CTXSecureNew() *BN_CTX
// BN_CTX *BN_CTX_new_ex(OSSL_LIB_CTX *ctx);
// BN_CTX *BN_CTX_secure_new_ex(OSSL_LIB_CTX *ctx);
// void BN_CTX_free(BN_CTX *c);
//
// llgo:link (*BN_CTX).Free C.BN_CTX_free
func (*BN_CTX) Free() {}
// void BN_CTX_start(BN_CTX *ctx);
//
// llgo:link (*BN_CTX).Start C.BN_CTX_start
func (*BN_CTX) Start() {}
// BIGNUM *BN_CTX_get(BN_CTX *ctx);
//
// llgo:link (*BN_CTX).Get C.BN_CTX_get
func (*BN_CTX) Get() *BIGNUM { return nil }
// void BN_CTX_end(BN_CTX *ctx);
//
// llgo:link (*BN_CTX).End C.BN_CTX_end
func (*BN_CTX) End() {}
// -----------------------------------------------------------------------------
type BIGNUM struct {
Unused [0]byte
}
// BIGNUM *BN_new(void);
//
//go:linkname BNNew C.BN_new
func BNNew() *BIGNUM
// BIGNUM *BN_secure_new(void);
//
//go:linkname BNSecureNew C.BN_secure_new
func BNSecureNew() *BIGNUM
// void BN_free(BIGNUM *a);
//
// llgo:link (*BIGNUM).Free C.BN_free
func (*BIGNUM) Free() {}
// void BN_clear_free(BIGNUM *a);
//
// llgo:link (*BIGNUM).ClearFree C.BN_clear_free
func (*BIGNUM) ClearFree() {}
// void BN_clear(BIGNUM *a);
//
// llgo:link (*BIGNUM).Clear C.BN_clear
func (*BIGNUM) Clear() {}
// BIGNUM *BN_dup(const BIGNUM *a);
//
// llgo:link (*BIGNUM).Dup C.BN_dup
func (*BIGNUM) Dup() *BIGNUM { return nil }
// BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
//
// llgo:link (*BIGNUM).Copy C.BN_copy
func (*BIGNUM) Copy(b *BIGNUM) *BIGNUM { return nil }
// void BN_swap(BIGNUM *a, BIGNUM *b);
//
// llgo:link (*BIGNUM).Swap C.BN_swap
func (*BIGNUM) Swap(b *BIGNUM) {}
// int BN_is_zero(const BIGNUM *a);
//
// llgo:link (*BIGNUM).IsZero C.BN_is_zero
func (*BIGNUM) IsZero() c.Int { return 0 }
// void BN_zero_ex(BIGNUM *a);
//
// llgo:link (*BIGNUM).SetZero C.BN_zero_ex
func (*BIGNUM) SetZero() {}
// int BN_is_one(const BIGNUM *a);
//
// llgo:link (*BIGNUM).IsOne C.BN_is_one
func (*BIGNUM) IsOne() c.Int { return 0 }
// int BN_is_odd(const BIGNUM *a);
//
// llgo:link (*BIGNUM).IsOdd C.BN_is_odd
func (*BIGNUM) IsOdd() c.Int { return 0 }
// int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w);
//
// llgo:link (*BIGNUM).AbsIsWord C.BN_abs_is_word
func (*BIGNUM) AbsIsWord(w BN_ULONG) c.Int { return 0 }
// int BN_is_word(const BIGNUM *a, const BN_ULONG w);
//
// llgo:link (*BIGNUM).IsWord C.BN_is_word
func (*BIGNUM) IsWord(w BN_ULONG) c.Int { return 0 }
// int BN_set_word(BIGNUM *a, BN_ULONG w);
//
// llgo:link (*BIGNUM).SetWord C.BN_set_word
func (*BIGNUM) SetWord(w BN_ULONG) c.Int { return 0 }
// BN_ULONG BN_get_word(const BIGNUM *a);
//
// llgo:link (*BIGNUM).GetWord C.BN_get_word
func (*BIGNUM) GetWord() BN_ULONG { return 0 }
// BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
//
// llgo:link (*BIGNUM).ModWord C.BN_mod_word
func (*BIGNUM) ModWord(w BN_ULONG) BN_ULONG { return 0 }
// BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
//
// llgo:link (*BIGNUM).DivWord C.BN_div_word
func (*BIGNUM) DivWord(w BN_ULONG) BN_ULONG { return 0 }
// int BN_mul_word(BIGNUM *a, BN_ULONG w);
//
// llgo:link (*BIGNUM).MulWord C.BN_mul_word
func (*BIGNUM) MulWord(w BN_ULONG) c.Int { return 0 }
// int BN_add_word(BIGNUM *a, BN_ULONG w);
//
// llgo:link (*BIGNUM).AddWord C.BN_add_word
func (*BIGNUM) AddWord(w BN_ULONG) c.Int { return 0 }
// int BN_sub_word(BIGNUM *a, BN_ULONG w);
//
// llgo:link (*BIGNUM).SubWord C.BN_sub_word
func (*BIGNUM) SubWord(w BN_ULONG) c.Int { return 0 }
// char *BN_bn2hex(const BIGNUM *a);
//
// llgo:link (*BIGNUM).Bn2hex C.BN_bn2hex
func (*BIGNUM) Bn2hex() *c.Char { return nil }
// char *BN_bn2dec(const BIGNUM *a);
//
// llgo:link (*BIGNUM).Bn2dec C.BN_bn2dec
func (*BIGNUM) Bn2dec() *c.Char { return nil }
// llgo:link (*BIGNUM).CStr C.BN_bn2dec
func (*BIGNUM) CStr() *c.Char { return nil }
// int BN_hex2bn(BIGNUM **a, const char *str);
//
//go:linkname BNHex2bn C.BN_hex2bn
func BNHex2bn(a **BIGNUM, str *c.Char) c.Int
// int BN_dec2bn(BIGNUM **a, const char *str);
//
//go:linkname BNDec2bn C.BN_dec2bn
func BNDec2bn(a **BIGNUM, str *c.Char) c.Int
// int BN_asc2bn(BIGNUM **a, const char *str);
//
//go:linkname BNAsc2bn C.BN_asc2bn
func BNAsc2bn(a **BIGNUM, str *c.Char) c.Int
// BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
//
//go:linkname BNBin2bn C.BN_bin2bn
func BNBin2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM
// BIGNUM *BN_signed_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
//
//go:linkname BNSignedBin2bn C.BN_signed_bin2bn
func BNSignedBin2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM
// int BN_bn2bin(const BIGNUM *a, unsigned char *to);
//
// llgo:link (*BIGNUM).Bn2bin C.BN_bn2bin
func (bn *BIGNUM) Bn2bin(to *byte) c.Int { return 0 }
// int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen);
//
// llgo:link (*BIGNUM).Bn2binpad C.BN_bn2binpad
func (bn *BIGNUM) Bn2binpad(to *byte, tolen c.Int) c.Int { return 0 }
// int BN_signed_bn2bin(const BIGNUM *a, unsigned char *to, int tolen);
//
// llgo:link (*BIGNUM).SignedBn2bin C.BN_signed_bn2bin
func (bn *BIGNUM) SignedBn2bin(to *byte, tolen c.Int) c.Int { return 0 }
// BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret);
//
//go:linkname BNLebin2bn C.BN_lebin2bn
func BNLebin2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM
// BIGNUM *BN_signed_lebin2bn(const unsigned char *s, int len, BIGNUM *ret);
//
//go:linkname BNSignedLebin2bn C.BN_signed_lebin2bn
func BNSignedLebin2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM
// int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen);
//
// llgo:link (*BIGNUM).Bn2lebinpad C.BN_bn2lebinpad
func (bn *BIGNUM) Bn2lebinpad(to *byte, tolen c.Int) c.Int { return 0 }
// int BN_signed_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen);
//
// llgo:link (*BIGNUM).SignedBn2lebin C.BN_signed_bn2lebin
func (bn *BIGNUM) SignedBn2lebin(to *byte, tolen c.Int) c.Int { return 0 }
// BIGNUM *BN_native2bn(const unsigned char *s, int len, BIGNUM *ret);
//
//go:linkname BNNative2bn C.BN_native2bn
func BNNative2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM
// BIGNUM *BN_signed_native2bn(const unsigned char *s, int len, BIGNUM *ret);
//
//go:linkname BNSignedNative2bn C.BN_signed_native2bn
func BNSignedNative2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM
// int BN_bn2nativepad(const BIGNUM *a, unsigned char *to, int tolen);
//
// llgo:link (*BIGNUM).Bn2nativepad C.BN_bn2nativepad
func (bn *BIGNUM) Bn2nativepad(to *byte, tolen c.Int) c.Int { return 0 }
// int BN_signed_bn2native(const BIGNUM *a, unsigned char *to, int tolen);
//
// llgo:link (*BIGNUM).SignedBn2native C.BN_signed_bn2native
func (bn *BIGNUM) SignedBn2native(to *byte, tolen c.Int) c.Int { return 0 }
// BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret);
//
//go:linkname BNMpi2bn C.BN_mpi2bn
func BNMpi2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM
// int BN_bn2mpi(const BIGNUM *a, unsigned char *to);
//
// llgo:link (*BIGNUM).Bn2mpi C.BN_bn2mpi
func (bn *BIGNUM) Bn2mpi(to *byte) c.Int { return 0 }
// int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
//
// llgo:link (*BIGNUM).Sub C.BN_sub
func (*BIGNUM) Sub(a, b *BIGNUM) c.Int { return 0 }
// int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
//
// llgo:link (*BIGNUM).Add C.BN_add
func (*BIGNUM) Add(a, b *BIGNUM) c.Int { return 0 }
// int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
//
// llgo:link (*BIGNUM).Usub C.BN_usub
func (*BIGNUM) Usub(a, b *BIGNUM) c.Int { return 0 }
// int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
//
// llgo:link (*BIGNUM).Uadd C.BN_uadd
func (*BIGNUM) Uadd(a, b *BIGNUM) c.Int { return 0 }
// int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
//
// llgo:link (*BIGNUM).Mul C.BN_mul
func (*BIGNUM) Mul(r, a, b *BIGNUM, ctx *BN_CTX) c.Int { return 0 }
// int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx);
//
// llgo:link (*BIGNUM).Sqr C.BN_sqr
func (*BIGNUM) Sqr(r, a *BIGNUM, ctx *BN_CTX) c.Int { return 0 }
/** BN_set_negative sets sign of a BIGNUM
* \param b pointer to the BIGNUM object
* \param n 0 if the BIGNUM b should be positive and a value != 0 otherwise
*/
// void BN_set_negative(BIGNUM *b, int n);
//
// llgo:link (*BIGNUM).SetNegative C.BN_set_negative
func (*BIGNUM) SetNegative(n c.Int) {}
/** BN_is_negative returns 1 if the BIGNUM is negative
* \param b pointer to the BIGNUM object
* \return 1 if a < 0 and 0 otherwise
*/
// int BN_is_negative(const BIGNUM *b);
//
// llgo:link (*BIGNUM).IsNegative C.BN_is_negative
func (*BIGNUM) IsNegative() c.Int { return 0 }
// int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
//
// llgo:link (*BIGNUM).Div C.BN_div
func (*BIGNUM) Div(rem, m, d *BIGNUM, ctx *BN_CTX) c.Int { return 0 }
// int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
//
// llgo:link (*BIGNUM).Nnmod C.BN_nnmod
func (*BIGNUM) Nnmod(r, m, d *BIGNUM, ctx *BN_CTX) c.Int { return 0 }
// int BN_cmp(const BIGNUM *a, const BIGNUM *b);
//
// llgo:link (*BIGNUM).Cmp C.BN_cmp
func (*BIGNUM) Cmp(b *BIGNUM) c.Int { return 0 }
// int BN_ucmp(const BIGNUM *a, const BIGNUM *b);
//
// llgo:link (*BIGNUM).Ucmp C.BN_ucmp
func (*BIGNUM) Ucmp(b *BIGNUM) c.Int { return 0 }
// int BN_is_bit_set(const BIGNUM *a, int n);
//
// llgo:link (*BIGNUM).IsBitSet C.BN_is_bit_set
func (*BIGNUM) IsBitSet(n c.Int) c.Int { return 0 }
// int BN_set_bit(BIGNUM *a, int n);
//
// llgo:link (*BIGNUM).SetBit C.BN_set_bit
func (*BIGNUM) SetBit(n c.Int) c.Int { return 0 }
// int BN_clear_bit(BIGNUM *a, int n);
//
// llgo:link (*BIGNUM).ClearBit C.BN_clear_bit
func (*BIGNUM) ClearBit(n c.Int) c.Int { return 0 }
// int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
//
// llgo:link (*BIGNUM).Lshift C.BN_lshift
func (*BIGNUM) Lshift(a *BIGNUM, n c.Int) c.Int { return 0 }
// int BN_lshift1(BIGNUM *r, const BIGNUM *a);
//
// llgo:link (*BIGNUM).Lshift1 C.BN_lshift1
func (*BIGNUM) Lshift1(a *BIGNUM) c.Int { return 0 }
// int BN_rshift(BIGNUM *r, const BIGNUM *a, int n);
//
// llgo:link (*BIGNUM).Rshift C.BN_rshift
func (*BIGNUM) Rshift(a *BIGNUM, n c.Int) c.Int { return 0 }
// int BN_rshift1(BIGNUM *r, const BIGNUM *a);
//
// llgo:link (*BIGNUM).Rshift1 C.BN_rshift1
func (*BIGNUM) Rshift1(a *BIGNUM) c.Int { return 0 }
// int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
//
// llgo:link (*BIGNUM).Exp C.BN_exp
func (*BIGNUM) Exp(a, p *BIGNUM, ctx *BN_CTX) c.Int { return 0 }
// int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx);
//
// llgo:link (*BIGNUM).ModExp C.BN_mod_exp
func (*BIGNUM) ModExp(a, p, m *BIGNUM, ctx *BN_CTX) c.Int { return 0 }
// int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
//
// llgo:link (*BIGNUM).Gcd C.BN_gcd
func (*BIGNUM) Gcd(a, b *BIGNUM, ctx *BN_CTX) c.Int { return 0 }
// int BN_are_coprime(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
//
// llgo:link (*BIGNUM).AreCoprime C.BN_are_coprime
func (*BIGNUM) AreCoprime(b *BIGNUM, ctx *BN_CTX) c.Int { return 0 }
// -----------------------------------------------------------------------------
type BN_GENCB struct {
Unused [0]byte
}
// -----------------------------------------------------------------------------

156
c/openssl/err.go Normal file
View File

@@ -0,0 +1,156 @@
/*
* 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 openssl
import (
"unsafe"
"github.com/goplus/llgo/c"
)
// -----------------------------------------------------------------------------
/*-
* The error code packs differently depending on if it records a system
* error or an OpenSSL error.
*
* A system error packs like this (we follow POSIX and only allow positive
* numbers that fit in an |int|):
*
* +-+-------------------------------------------------------------+
* |1| system error number |
* +-+-------------------------------------------------------------+
*
* An OpenSSL error packs like this:
*
* <---------------------------- 32 bits -------------------------->
* <--- 8 bits ---><------------------ 23 bits ----------------->
* +-+---------------+---------------------------------------------+
* |0| library | reason |
* +-+---------------+---------------------------------------------+
*
* A few of the reason bits are reserved as flags with special meaning:
*
* <5 bits-<>--------- 19 bits ----------------->
* +-------+-+-----------------------------------+
* | rflags| | reason |
* +-------+-+-----------------------------------+
* ^
* |
* ERR_RFLAG_FATAL = ERR_R_FATAL
*
* The reason flags are part of the overall reason code for practical
* reasons, as they provide an easy way to place different types of
* reason codes in different numeric ranges.
*
* The currently known reason flags are:
*
* ERR_RFLAG_FATAL Flags that the reason code is considered fatal.
* For backward compatibility reasons, this flag
* is also the code for ERR_R_FATAL (that reason
* code served the dual purpose of flag and reason
* code in one in pre-3.0 OpenSSL).
* ERR_RFLAG_COMMON Flags that the reason code is common to all
* libraries. All ERR_R_ macros must use this flag,
* and no other _R_ macro is allowed to use it.
*/
type Errno c.Ulong
// ERR_get_error returns the earliest error code from the thread's error queue and
// removes the entry. This function can be called repeatedly until there are no more
// error codes to return.
//
// unsigned long ERR_get_error(void);
//
//go:linkname ERRGetError C.ERR_get_error
func ERRGetError() Errno
// ERR_get_error_all() is the same as ERR_get_error(), but on success it additionally
// stores the filename, line number and function where the error occurred in *file,
// *line and *func, and also extra text and flags in *data, *flags. If any of those
// parameters are NULL, it will not be changed.
//
// unsigned long ERR_get_error_all(
// const char **file, int *line, const char **func, const char **data, int *flags);
//
//go:linkname ERRGetErrorAll C.ERR_get_error_all
func ERRGetErrorAll(
file **c.Char, line *c.Int, function **c.Char, data **c.Char, flags *c.Int) Errno
// unsigned long ERR_peek_error(void);
//
//go:linkname ERRPeekError C.ERR_peek_error
func ERRPeekError() Errno
// unsigned long ERR_peek_error_all(
// const char **file, int *line, const char **func, const char **data, int *flags);
//
//go:linkname ERRPeekErrorAll C.ERR_peek_error_all
func ERRPeekErrorAll(
file **c.Char, line *c.Int, function **c.Char, data **c.Char, flags *c.Int) Errno
// unsigned long ERR_peek_last_error(void);
//
//go:linkname ERRPeekLastError C.ERR_peek_last_error
func ERRPeekLastError() Errno
// unsigned long ERR_peek_last_error_all(
// const char **file, int *line, const char **func, const char **data, int *flags);
//
//go:linkname ERRPeekLastErrorAll C.ERR_peek_last_error_all
func ERRPeekLastErrorAll(
file **c.Char, line *c.Int, function **c.Char, data **c.Char, flags *c.Int) Errno
// void ERR_clear_error(void);
//
//go:linkname ERRClearError C.ERR_clear_error
func ERRClearError()
// ERR_error_string() generates a human-readable string representing the error code e,
// and places it at buf. buf must be at least 256 bytes long.
//
// char *ERR_error_string(unsigned long e, char *buf);
//
//go:linkname ERRErrorString C.ERR_error_string
func ERRErrorString(e Errno, buf *c.Char) *c.Char
// ERR_lib_error_string() and ERR_reason_error_string() return the library name and
// reason string respectively.
//
// const char *ERR_lib_error_string(unsigned long e);
//
//go:linkname ERRLibErrorString C.ERR_lib_error_string
func ERRLibErrorString(e Errno) *c.Char
// const char *ERR_reason_error_string(unsigned long e);
//
//go:linkname ERRReasonErrorString C.ERR_reason_error_string
func ERRReasonErrorString(e Errno) *c.Char
// void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u), void *u);
//
// [pid]:error:[error code]:[library name]:[function name]:[reason string]:[filename]:[line]:[optional text message]
//
//go:linkname ERRPrintErrorsCb C.ERR_print_errors_cb
func ERRPrintErrorsCb(cb func(str *c.Char, len uintptr, u unsafe.Pointer) c.Int, u unsafe.Pointer)
// void ERR_print_errors_fp(FILE *fp);
//
//go:linkname ERRPrintErrorsFp C.ERR_print_errors_fp
func ERRPrintErrorsFp(fp c.FilePtr)
// -----------------------------------------------------------------------------

133
c/openssl/hmac.go Normal file
View File

@@ -0,0 +1,133 @@
package openssl
import (
"unsafe"
"github.com/goplus/llgo/c"
)
const (
EVP_MAX_MD_SIZE = 64 /* longest known is SHA512 */
)
// -----------------------------------------------------------------------------
type EVP_MD struct {
Unused [0]byte
}
// const EVP_MD *EVP_sha1(void)
//
//go:linkname EVP_sha1 C.EVP_sha1
func EVP_sha1() *EVP_MD
// const EVP_MD *EVP_sha224(void)
//
//go:linkname EVP_sha224 C.EVP_sha224
func EVP_sha224() *EVP_MD
// func EVP_sha256() *EVP_MD
//
//go:linkname EVP_sha256 C.EVP_sha256
func EVP_sha256() *EVP_MD
// const EVP_MD *EVP_sha512_224(void)
//
//go:linkname EVP_sha512_224 C.EVP_sha512_224
func EVP_sha512_224() *EVP_MD
// const EVP_MD *EVP_sha512_256(void)
//
//go:linkname EVP_sha512_256 C.EVP_sha512_256
func EVP_sha512_256() *EVP_MD
// const EVP_MD *EVP_sha384(void)
//
//go:linkname EVP_sha384 C.EVP_sha384
func EVP_sha384() *EVP_MD
// const EVP_MD *EVP_sha512(void)
//
//go:linkname EVP_sha512 C.EVP_sha512
func EVP_sha512() *EVP_MD
// -----------------------------------------------------------------------------
type HMAC_CTX struct {
Unused [0]byte
}
// OSSL_DEPRECATEDIN_3_0 HMAC_CTX *HMAC_CTX_new(void);
//
//go:linkname NewHMAC_CTX C.HMAC_CTX_new
func NewHMAC_CTX() *HMAC_CTX
// OSSL_DEPRECATEDIN_3_0 void HMAC_CTX_free(HMAC_CTX *ctx);
//
// llgo:link (*HMAC_CTX).Free C.HMAC_CTX_free
func (ctx *HMAC_CTX) Free() {}
// OSSL_DEPRECATEDIN_3_0 size_t HMAC_size(const HMAC_CTX *e);
//
// llgo:link (*HMAC_CTX).Size C.HMAC_size
func (ctx *HMAC_CTX) Size() uintptr { return 0 }
// OSSL_DEPRECATEDIN_3_0 int HMAC_CTX_reset(HMAC_CTX *ctx);
//
// llgo:link (*HMAC_CTX).Reset C.HMAC_CTX_reset
func (ctx *HMAC_CTX) Reset() c.Int { return 0 }
// OSSL_DEPRECATEDIN_1_1_0 __owur int HMAC_Init(HMAC_CTX *ctx,
// const void *key, int len,
// const EVP_MD *md);
//
// llgo:link (*HMAC_CTX).Init C.HMAC_Init
func (ctx *HMAC_CTX) Init(key unsafe.Pointer, len c.Int, md *EVP_MD) c.Int { return 0 }
func (ctx *HMAC_CTX) InitBytes(key []byte, md *EVP_MD) c.Int {
return ctx.Init(unsafe.Pointer(unsafe.SliceData(key)), c.Int(len(key)), md)
}
func (ctx *HMAC_CTX) InitString(key string, md *EVP_MD) c.Int {
return ctx.Init(unsafe.Pointer(unsafe.StringData(key)), c.Int(len(key)), md)
}
// OSSL_DEPRECATEDIN_3_0 int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
// const EVP_MD *md, ENGINE *impl);
//
// llgo:link (*HMAC_CTX).InitEx C.HMAC_Init_ex
func (ctx *HMAC_CTX) InitEx(key unsafe.Pointer, len c.Int, md *EVP_MD, impl unsafe.Pointer) c.Int {
return 0
}
// OSSL_DEPRECATEDIN_3_0 int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data,
// size_t len);
//
// llgo:link (*HMAC_CTX).Update C.HMAC_Update
func (ctx *HMAC_CTX) Update(data unsafe.Pointer, len uintptr) c.Int { return 0 }
func (ctx *HMAC_CTX) UpdateBytes(data []byte) c.Int {
return ctx.Update(unsafe.Pointer(unsafe.SliceData(data)), uintptr(len(data)))
}
func (ctx *HMAC_CTX) UpdateString(data string) c.Int {
return ctx.Update(unsafe.Pointer(unsafe.StringData(data)), uintptr(len(data)))
}
// OSSL_DEPRECATEDIN_3_0 int HMAC_Final(HMAC_CTX *ctx, unsigned char *md,
// unsigned int *len);
//
// llgo:link (*HMAC_CTX).Final C.HMAC_Final
func (ctx *HMAC_CTX) Final(md *byte, len *c.Uint) c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 __owur int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx);
//
// llgo:link (*HMAC_CTX).Copy C.HMAC_CTX_copy
func (ctx *HMAC_CTX) Copy(sctx *HMAC_CTX) c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags);
//
// llgo:link (*HMAC_CTX).SetFlags C.HMAC_CTX_set_flags
func (ctx *HMAC_CTX) SetFlags(flags c.Ulong) {}
// -----------------------------------------------------------------------------

85
c/openssl/md5.go Normal file
View File

@@ -0,0 +1,85 @@
/*
* 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 openssl
import (
"unsafe"
"github.com/goplus/llgo/c"
)
// -----------------------------------------------------------------------------
const (
MD5_CBLOCK = 64
MD5_LBLOCK = MD5_CBLOCK / 4
)
// -----------------------------------------------------------------------------
type MD5_LONG = c.Uint
type MD5_CTX struct {
A, B, C, D MD5_LONG
Nl, Nh MD5_LONG
Data [MD5_LBLOCK]MD5_LONG
Num c.Uint
}
// OSSL_DEPRECATEDIN_3_0 int MD5_Init(MD5_CTX *c);
//
// llgo:link (*MD5_CTX).Init C.MD5_Init
func (c *MD5_CTX) Init() c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int MD5_Update(MD5_CTX *c, const void *data, size_t len);
//
// llgo:link (*MD5_CTX).Update C.MD5_Update
func (c *MD5_CTX) Update(data unsafe.Pointer, n uintptr) c.Int { return 0 }
func (c *MD5_CTX) UpdateBytes(data []byte) c.Int {
return c.Update(unsafe.Pointer(unsafe.SliceData(data)), uintptr(len(data)))
}
func (c *MD5_CTX) UpdateString(data string) c.Int {
return c.Update(unsafe.Pointer(unsafe.StringData(data)), uintptr(len(data)))
}
// OSSL_DEPRECATEDIN_3_0 int MD5_Final(unsigned char *md, MD5_CTX *c);
//
//go:linkname md5Final C.MD5_Final
func md5Final(md *byte, c *MD5_CTX) c.Int
func (c *MD5_CTX) Final(md *byte) c.Int {
return md5Final(md, c)
}
// OSSL_DEPRECATEDIN_3_0 unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md);
//
//go:linkname MD5 C.MD5
func MD5(data unsafe.Pointer, n uintptr, md *byte) *byte
func MD5Bytes(data []byte, md *byte) *byte {
return MD5(unsafe.Pointer(unsafe.SliceData(data)), uintptr(len(data)), md)
}
func MD5String(data string, md *byte) *byte {
return MD5(unsafe.Pointer(unsafe.StringData(data)), uintptr(len(data)), md)
}
// OSSL_DEPRECATEDIN_3_0 void MD5_Transform(MD5_CTX *c, const unsigned char *b);
// -----------------------------------------------------------------------------

38
c/openssl/openssl.go Normal file
View File

@@ -0,0 +1,38 @@
/*
* 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 openssl
import (
"unsafe"
"github.com/goplus/llgo/c"
)
// -----------------------------------------------------------------------------
const (
LLGoFiles = "$(pkg-config --cflags openssl): _wrap/openssl.c"
LLGoPackage = "link: $(pkg-config --libs openssl); -lssl -lcrypto"
)
//go:linkname Free C.opensslFree
func Free(ptr unsafe.Pointer)
//go:linkname FreeCStr C.opensslFree
func FreeCStr(ptr *c.Char)
// -----------------------------------------------------------------------------

37
c/openssl/pem.go Normal file
View File

@@ -0,0 +1,37 @@
/*
* 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 openssl
import (
"unsafe"
"github.com/goplus/llgo/c"
)
// -----------------------------------------------------------------------------
// typedef int (*pem_password_cb)(char *buf, int size, int rwflag, void *userdata);
//
// llgo:type C
type PemPasswordCb func(buf *c.Char, size, rwflag c.Int, userdata unsafe.Pointer) c.Int
// RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **x, pem_password_cb *cb, void *u);
//
//go:linkname PEMReadBioRSAPrivateKey C.PEM_read_bio_RSAPrivateKey
func PEMReadBioRSAPrivateKey(bp *BIO, x **RSA, cb PemPasswordCb, u unsafe.Pointer) *RSA
// -----------------------------------------------------------------------------

80
c/openssl/rand.go Normal file
View File

@@ -0,0 +1,80 @@
/*
* 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 openssl
import (
"unsafe"
"github.com/goplus/llgo/c"
)
// -----------------------------------------------------------------------------
// int RAND_bytes(unsigned char *buf, int num);
//
//go:linkname RANDBufferWithLen C.RAND_bytes
func RANDBufferWithLen(buf *byte, num c.Int) c.Int
func RANDBytes(buf []byte) c.Int {
return RANDBufferWithLen(unsafe.SliceData(buf), c.Int(len(buf)))
}
// int RAND_priv_bytes(unsigned char *buf, int num);
//
//go:linkname RANDPrivBufferWithLen C.RAND_priv_bytes
func RANDPrivBufferWithLen(buf *byte, num c.Int) c.Int
func RANDPrivBytes(buf []byte) c.Int {
return RANDPrivBufferWithLen(unsafe.SliceData(buf), c.Int(len(buf)))
}
// void RAND_seed(const void *buf, int num);
//
//go:linkname RANDSeed C.RAND_seed
func RANDSeed(buf unsafe.Pointer, num c.Int)
// void RAND_keep_random_devices_open(int keep);
//
//go:linkname RANDKeepRandomDevicesOpen C.RAND_keep_random_devices_open
func RANDKeepRandomDevicesOpen(keep c.Int)
// int RAND_load_file(const char *file, long max_bytes);
//
//go:linkname RANDLoadFile C.RAND_load_file
func RANDLoadFile(file *c.Char, maxBytes c.Long) c.Int
// int RAND_write_file(const char *file);
//
//go:linkname RANDWriteFile C.RAND_write_file
func RANDWriteFile(file *c.Char) c.Int
// const char *RAND_file_name(char *file, size_t num);
//
//go:linkname RANDFileName C.RAND_file_name
func RANDFileName(file *c.Char, num uintptr) *c.Char
// int RAND_status(void);
//
//go:linkname RANDStatus C.RAND_status
func RANDStatus() c.Int
// int RAND_poll(void);
//
//go:linkname RANDPoll C.RAND_poll
func RANDPoll() c.Int
// -----------------------------------------------------------------------------

305
c/openssl/rsa.go Normal file
View File

@@ -0,0 +1,305 @@
/*
* 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 openssl
import (
"unsafe"
"github.com/goplus/llgo/c"
)
// -----------------------------------------------------------------------------
type RSA_METHOD struct {
Unused [0]byte
}
// OSSL_DEPRECATEDIN_3_0 RSA_METHOD *RSA_meth_new(const char *name, int flags);
//
//go:linkname RSAMethNew C.RSA_meth_new
func RSAMethNew(name *byte, flags c.Int) *RSA_METHOD
// OSSL_DEPRECATEDIN_3_0 void RSA_meth_free(RSA_METHOD *meth);
//
// llgo:link (*RSA_METHOD).Free C.RSA_meth_free
func (*RSA_METHOD) Free() {}
// OSSL_DEPRECATEDIN_3_0
// int RSA_meth_set_init(RSA_METHOD *rsa, int (*init) (RSA *rsa));
//
// llgo:link (*RSA_METHOD).SetInit C.RSA_meth_set_init
func (*RSA_METHOD) SetInit(init func(rsa *RSA) c.Int) c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0
// int RSA_meth_set_finish(RSA_METHOD *rsa, int (*finish) (RSA *rsa));
//
// llgo:link (*RSA_METHOD).SetFinish C.RSA_meth_set_finish
func (*RSA_METHOD) SetFinish(finish func(rsa *RSA) c.Int) c.Int { return 0 }
/*
OSSL_DEPRECATEDIN_3_0
int RSA_meth_set_mod_exp(RSA_METHOD *rsa,
int (*mod_exp) (BIGNUM *r0, const BIGNUM *i, RSA *rsa,
BN_CTX *ctx));
*/
// llgo:link (*RSA_METHOD).SetModExp C.RSA_meth_set_mod_exp
func (*RSA_METHOD) SetModExp(modExp func(
r0 *BIGNUM, i *BIGNUM, rsa *RSA, ctx *BN_CTX) c.Int) c.Int {
return 0
}
/*
OSSL_DEPRECATEDIN_3_0
int RSA_meth_set_bn_mod_exp(RSA_METHOD *rsa,
int (*bn_mod_exp) (BIGNUM *r,
const BIGNUM *a,
const BIGNUM *p,
const BIGNUM *m,
BN_CTX *ctx,
BN_MONT_CTX *m_ctx));
//-llgo:link (*RSA_METHOD).SetBnModExp C.RSA_meth_set_bn_mod_exp
func (*RSA_METHOD) SetBnModExp(bnModExp func(
r *BIGNUM, a *BIGNUM, p *BIGNUM, m *BIGNUM, ctx *BN_CTX, mCtx *BN_MONT_CTX) c.Int) c.Int {
return 0
}
*/
/*
OSSL_DEPRECATEDIN_3_0
int RSA_meth_set_pub_enc(RSA_METHOD *rsa,
int (*pub_enc) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa,
int padding));
*/
// llgo:link (*RSA_METHOD).SetPubEnc C.RSA_meth_set_pub_enc
func (*RSA_METHOD) SetPubEnc(pubEnc func(
flen c.Int, from *byte, to *byte, rsa *RSA, padding c.Int) c.Int) c.Int {
return 0
}
/*
OSSL_DEPRECATEDIN_3_0
int RSA_meth_set_pub_dec(RSA_METHOD *rsa,
int (*pub_dec) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa,
int padding));
*/
// llgo:link (*RSA_METHOD).SetPubDec C.RSA_meth_set_pub_dec
func (*RSA_METHOD) SetPubDec(pubDec func(
flen c.Int, from *byte, to *byte, rsa *RSA, padding c.Int) c.Int) c.Int {
return 0
}
/*
OSSL_DEPRECATEDIN_3_0
int RSA_meth_set_priv_enc(RSA_METHOD *rsa,
int (*priv_enc) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa,
int padding));
*/
// llgo:link (*RSA_METHOD).SetPrivEnc C.RSA_meth_set_priv_enc
func (*RSA_METHOD) SetPrivEnc(privEnc func(
flen c.Int, from *byte, to *byte, rsa *RSA, padding c.Int) c.Int) c.Int {
return 0
}
/*
OSSL_DEPRECATEDIN_3_0
int RSA_meth_set_priv_dec(RSA_METHOD *rsa,
int (*priv_dec) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa,
int padding));
*/
// llgo:link (*RSA_METHOD).SetPrivDec C.RSA_meth_set_priv_dec
func (*RSA_METHOD) SetPrivDec(privDec func(
flen c.Int, from *byte, to *byte, rsa *RSA, padding c.Int) c.Int) c.Int {
return 0
}
/*
OSSL_DEPRECATEDIN_3_0
int RSA_meth_set_sign(RSA_METHOD *rsa,
int (*sign) (int type, const unsigned char *m,
unsigned int m_length,
unsigned char *sigret, unsigned int *siglen,
const RSA *rsa));
*/
// llgo:link (*RSA_METHOD).SetSign C.RSA_meth_set_sign
func (*RSA_METHOD) SetSign(sign func(
typ c.Int, msg *byte, mlen c.Uint,
sigret *byte, siglen *c.Uint, rsa *RSA) c.Int) c.Int {
return 0
}
/*
OSSL_DEPRECATEDIN_3_0
int RSA_meth_set_verify(RSA_METHOD *rsa,
int (*verify) (int dtype, const unsigned char *m,
unsigned int m_length,
const unsigned char *sigbuf,
unsigned int siglen, const RSA *rsa));
*/
// llgo:link (*RSA_METHOD).SetVerify C.RSA_meth_set_verify
func (*RSA_METHOD) SetVerify(verify func(
dtype c.Int, msg *byte, mlen c.Uint,
sigbuf *byte, siglen c.Uint, rsa *RSA) c.Int) c.Int {
return 0
}
/*
OSSL_DEPRECATEDIN_3_0
int RSA_meth_set_keygen(RSA_METHOD *rsa,
int (*keygen) (RSA *rsa, int bits, BIGNUM *e,
BN_GENCB *cb));
OSSL_DEPRECATEDIN_3_0
int RSA_meth_set_multi_prime_keygen(RSA_METHOD *meth,
int (*keygen) (RSA *rsa, int bits,
int primes, BIGNUM *e,
BN_GENCB *cb));
*/
// -----------------------------------------------------------------------------
type RSA struct {
Unused [0]byte
}
// OSSL_DEPRECATEDIN_3_0 RSA *RSA_new(void);
//
//go:linkname RSANew C.RSA_new
func RSANew() *RSA
// OSSL_DEPRECATEDIN_3_0 RSA *RSA_new_method(ENGINE *engine);
// OSSL_DEPRECATEDIN_3_0 void RSA_free(RSA *r);
//
// llgo:link (*RSA).Free C.RSA_free
func (*RSA) Free() {}
// "up" the RSA object's reference count
// OSSL_DEPRECATEDIN_3_0 int RSA_up_ref(RSA *r);
//
// llgo:link (*RSA).UpRef C.RSA_up_ref
func (*RSA) UpRef() c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int RSA_bits(const RSA *rsa);
//
// llgo:link (*RSA).Bits C.RSA_bits
func (*RSA) Bits() c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int RSA_size(const RSA *rsa);
//
// llgo:link (*RSA).Size C.RSA_size
func (*RSA) Size() c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int RSA_security_bits(const RSA *rsa);
//
// llgo:link (*RSA).SecurityBits C.RSA_security_bits
func (*RSA) SecurityBits() c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int RSA_flags(const RSA *r);
//
// llgo:link (*RSA).Flags C.RSA_flags
func (*RSA) Flags() c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 void RSA_set_flags(RSA *r, int flags);
//
// llgo:link (*RSA).SetFlags C.RSA_set_flags
func (*RSA) SetFlags(flags c.Int) {}
// OSSL_DEPRECATEDIN_3_0 void RSA_clear_flags(RSA *r, int flags);
//
// llgo:link (*RSA).ClearFlags C.RSA_clear_flags
func (*RSA) ClearFlags(flags c.Int) {}
// OSSL_DEPRECATEDIN_3_0 int RSA_test_flags(const RSA *r, int flags);
//
// llgo:link (*RSA).TestFlags C.RSA_test_flags
func (*RSA) TestFlags(flags c.Int) c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int RSA_get_version(RSA *r);
//
// llgo:link (*RSA).GetVersion C.RSA_get_version
func (*RSA) GetVersion() c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int RSA_set_ex_data(RSA *r, int idx, void *arg);
//
// llgo:link (*RSA).SetExData C.RSA_set_ex_data
func (*RSA) SetExData(idx c.Int, arg unsafe.Pointer) c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 void *RSA_get_ex_data(const RSA *r, int idx);
//
// llgo:link (*RSA).GetExData C.RSA_get_ex_data
func (*RSA) GetExData(idx c.Int) unsafe.Pointer { return nil }
// OSSL_DEPRECATEDIN_3_0 int RSA_set_method(RSA *rsa, const RSA_METHOD *meth);
//
// llgo:link (*RSA).SetMethod C.RSA_set_method
func (*RSA) SetMethod(meth *RSA_METHOD) c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
//
// llgo:link (*RSA).GenerateKeyEx C.RSA_generate_key_ex
func (*RSA) GenerateKeyEx(bits c.Int, e *BIGNUM, cb *BN_GENCB) c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes, BIGNUM *e, BN_GENCB *cb);
//
// llgo:link (*RSA).GenerateMultiPrimeKey C.RSA_generate_multi_prime_key
func (*RSA) GenerateMultiPrimeKey(bits, primes c.Int, e *BIGNUM, cb *BN_GENCB) c.Int { return 0 }
/*
// next 4 return -1 on error
OSSL_DEPRECATEDIN_3_0
int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to,
RSA *rsa, int padding);
OSSL_DEPRECATEDIN_3_0
int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
RSA *rsa, int padding);
OSSL_DEPRECATEDIN_3_0
int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to,
RSA *rsa, int padding);
OSSL_DEPRECATEDIN_3_0
int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
RSA *rsa, int padding);
*/
//go:linkname RSAPublicEncrypt C.RSA_public_encrypt
func RSAPublicEncrypt(flen c.Int, from *byte, to *byte, rsa *RSA, padding c.Int) c.Int
//go:linkname RSAPrivateEncrypt C.RSA_private_encrypt
func RSAPrivateEncrypt(flen c.Int, from *byte, to *byte, rsa *RSA, padding c.Int) c.Int
//go:linkname RSAPublicDecrypt C.RSA_public_decrypt
func RSAPublicDecrypt(flen c.Int, from *byte, to *byte, rsa *RSA, padding c.Int) c.Int
//go:linkname RSAPrivateDecrypt C.RSA_private_decrypt
func RSAPrivateDecrypt(flen c.Int, from *byte, to *byte, rsa *RSA, padding c.Int) c.Int
// OSSL_DEPRECATEDIN_3_0 int RSA_sign(
// int type, const unsigned char *m, unsigned int m_length,
// unsigned char *sigret, unsigned int *siglen, RSA *rsa);
//
//go:linkname RSASign C.RSA_sign
func RSASign(typ c.Int, msg *byte, mlen c.Uint, sigret *byte, siglen *c.Uint, rsa *RSA) c.Int
// OSSL_DEPRECATEDIN_3_0 int RSA_verify(int type, const unsigned char *m,
// unsigned int m_length,
// const unsigned char *sigbuf,
// unsigned int siglen, RSA *rsa);
// -----------------------------------------------------------------------------

94
c/openssl/sha1.go Normal file
View File

@@ -0,0 +1,94 @@
/*
* 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 openssl
import (
"unsafe"
"github.com/goplus/llgo/c"
)
const (
SHA_DIGEST_LENGTH = 20
SHA_LBLOCK = 16
SHA_CBLOCK = (SHA_LBLOCK * 4)
SHA_LAST_BLOCK = (SHA_CBLOCK - 8)
SHA256_CBLOCK = (SHA_LBLOCK * 4)
SHA256_192_DIGEST_LENGTH = 24
SHA224_DIGEST_LENGTH = 28
SHA256_DIGEST_LENGTH = 32
SHA384_DIGEST_LENGTH = 48
SHA512_DIGEST_LENGTH = 64
SHA512_CBLOCK = (SHA_LBLOCK * 8)
)
type SHA_LONG64 = c.UlongLong
type SHA_LONG = c.Uint
type SHA_CTX struct {
H0, H1, H2, H3, H4 SHA_LONG
Nl, Nh SHA_LONG
Data [SHA_LBLOCK]SHA_LONG
Num c.Uint
}
// OSSL_DEPRECATEDIN_3_0 int SHA1_Init(SHA_CTX *c);
//
// llgo:link (*SHA_CTX).Init C.SHA1_Init
func (c *SHA_CTX) Init() c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int SHA1_Update(SHA_CTX *c, const void *data, size_t len);
//
// llgo:link (*SHA_CTX).Update C.SHA1_Update
func (c *SHA_CTX) Update(data unsafe.Pointer, n uintptr) c.Int { return 0 }
func (c *SHA_CTX) UpdateBytes(data []byte) c.Int {
return c.Update(unsafe.Pointer(unsafe.SliceData(data)), uintptr(len(data)))
}
func (c *SHA_CTX) UpdateString(data string) c.Int {
return c.Update(unsafe.Pointer(unsafe.StringData(data)), uintptr(len(data)))
}
// OSSL_DEPRECATEDIN_3_0 int SHA1_Final(unsigned char *md, SHA_CTX *c);
//
//go:linkname sha1Final C.SHA1_Final
func sha1Final(md *byte, c *SHA_CTX) c.Int
func (c *SHA_CTX) Final(md *byte) c.Int {
return sha1Final(md, c)
}
// OSSL_DEPRECATEDIN_3_0 void SHA1_Transform(SHA_CTX *c, const unsigned char *data);
//
// llgo:link (*SHA_CTX).Transform C.SHA1_Transform
func (c *SHA_CTX) Transform(data *byte) {}
// unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md);
//
//go:linkname SHA1 C.SHA1
func SHA1(data unsafe.Pointer, n uintptr, md *byte) *byte
func SHA1Bytes(data []byte, md *byte) *byte {
return SHA1(unsafe.Pointer(unsafe.SliceData(data)), uintptr(len(data)), md)
}
func SHA1String(data string, md *byte) *byte {
return SHA1(unsafe.Pointer(unsafe.StringData(data)), uintptr(len(data)), md)
}

117
c/openssl/sha256.go Normal file
View File

@@ -0,0 +1,117 @@
/*
* 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 openssl
import (
"unsafe"
"github.com/goplus/llgo/c"
)
type SHA256_CTX struct {
H [8]SHA_LONG
Nl, Nh SHA_LONG
Data [SHA_LBLOCK]SHA_LONG
Num, MdLen c.Uint
}
type SHA224_CTX SHA256_CTX
// OSSL_DEPRECATEDIN_3_0 int SHA224_Init(SHA256_CTX *c);
//
// llgo:link (*SHA224_CTX).Init C.SHA224_Init
func (c *SHA224_CTX) Init() c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int SHA224_Update(SHA256_CTX *c, const void *data, size_t len);
//
// llgo:link (*SHA224_CTX).Update C.SHA224_Update
func (c *SHA224_CTX) Update(data unsafe.Pointer, n uintptr) c.Int { return 0 }
func (c *SHA224_CTX) UpdateBytes(data []byte) c.Int {
return c.Update(unsafe.Pointer(unsafe.SliceData(data)), uintptr(len(data)))
}
func (c *SHA224_CTX) UpdateString(data string) c.Int {
return c.Update(unsafe.Pointer(unsafe.StringData(data)), uintptr(len(data)))
}
// OSSL_DEPRECATEDIN_3_0 int SHA224_Final(unsigned char *md, SHA256_CTX *c);
//
//go:linkname sha224Final C.SHA224_Final
func sha224Final(md *byte, c *SHA224_CTX) c.Int
func (c *SHA224_CTX) Final(md *byte) c.Int {
return sha224Final(md, c)
}
// OSSL_DEPRECATEDIN_3_0 int SHA256_Init(SHA256_CTX *c);
//
// llgo:link (*SHA256_CTX).Init C.SHA256_Init
func (c *SHA256_CTX) Init() c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int SHA256_Update(SHA256_CTX *c, const void *data, size_t len);
//
// llgo:link (*SHA256_CTX).Update C.SHA256_Update
func (c *SHA256_CTX) Update(data unsafe.Pointer, n uintptr) c.Int { return 0 }
func (c *SHA256_CTX) UpdateBytes(data []byte) c.Int {
return c.Update(unsafe.Pointer(unsafe.SliceData(data)), uintptr(len(data)))
}
func (c *SHA256_CTX) UpdateString(data string) c.Int {
return c.Update(unsafe.Pointer(unsafe.StringData(data)), uintptr(len(data)))
}
// OSSL_DEPRECATEDIN_3_0 int SHA256_Final(unsigned char *md, SHA256_CTX *c);
//
//go:linkname sha256Final C.SHA256_Final
func sha256Final(md *byte, c *SHA256_CTX) c.Int
func (c *SHA256_CTX) Final(md *byte) c.Int {
return sha256Final(md, c)
}
// OSSL_DEPRECATEDIN_3_0 void SHA256_Transform(SHA256_CTX *c, const unsigned char *data);
//
// llgo:link (*SHA256_CTX).Transform C.SHA256_Transform
func (c *SHA256_CTX) Transform(data *byte) {}
// unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md);
//
//go:linkname SHA224 C.SHA224
func SHA224(data unsafe.Pointer, n uintptr, md *byte) *byte
func SHA224Bytes(data []byte, md *byte) *byte {
return SHA224(unsafe.Pointer(unsafe.SliceData(data)), uintptr(len(data)), md)
}
func SHA224String(data string, md *byte) *byte {
return SHA224(unsafe.Pointer(unsafe.StringData(data)), uintptr(len(data)), md)
}
// unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md);
//
//go:linkname SHA256 C.SHA256
func SHA256(data unsafe.Pointer, n uintptr, md *byte) *byte
func SHA256Bytes(data []byte, md *byte) *byte {
return SHA256(unsafe.Pointer(unsafe.SliceData(data)), uintptr(len(data)), md)
}
func SHA256String(data string, md *byte) *byte {
return SHA256(unsafe.Pointer(unsafe.StringData(data)), uintptr(len(data)), md)
}

115
c/openssl/sha512.go Normal file
View File

@@ -0,0 +1,115 @@
/*
* 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 openssl
import (
"unsafe"
"github.com/goplus/llgo/c"
)
type SHA512_CTX struct {
H [8]SHA_LONG64
N1, Nh SHA_LONG64
D [SHA_LBLOCK]SHA_LONG64
Num, MdLen c.Uint
}
type SHA384_CTX SHA512_CTX
// OSSL_DEPRECATEDIN_3_0 int SHA384_Init(SHA512_CTX *c);
//
// llgo:link (*SHA384_CTX).Init C.SHA384_Init
func (c *SHA384_CTX) Init() c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int SHA384_Update(SHA512_CTX *c, const void *data, size_t len);
//
// llgo:link (*SHA384_CTX).Update C.SHA384_Update
func (c *SHA384_CTX) Update(data unsafe.Pointer, n uintptr) c.Int { return 0 }
func (c *SHA384_CTX) UpdateBytes(data []byte) c.Int {
return c.Update(unsafe.Pointer(unsafe.SliceData(data)), uintptr(len(data)))
}
func (c *SHA384_CTX) UpdateString(data string) c.Int {
return c.Update(unsafe.Pointer(unsafe.StringData(data)), uintptr(len(data)))
}
// OSSL_DEPRECATEDIN_3_0 int SHA384_Final(unsigned char *md, SHA512_CTX *c);
//
//go:linkname sha384Final C.SHA384_Final
func sha384Final(md *byte, c *SHA384_CTX) c.Int
func (c *SHA384_CTX) Final(md *byte) c.Int {
return sha384Final(md, c)
}
// OSSL_DEPRECATEDIN_3_0 int SHA512_Init(SHA512_CTX *c);
//
// llgo:link (*SHA512_CTX).Init C.SHA512_Init
func (c *SHA512_CTX) Init() c.Int { return 0 }
// OSSL_DEPRECATEDIN_3_0 int SHA512_Update(SHA512_CTX *c, const void *data, size_t len);
//
// llgo:link (*SHA512_CTX).Update C.SHA512_Update
func (c *SHA512_CTX) Update(data unsafe.Pointer, n uintptr) c.Int { return 0 }
func (c *SHA512_CTX) UpdateBytes(data []byte) c.Int {
return c.Update(unsafe.Pointer(unsafe.SliceData(data)), uintptr(len(data)))
}
func (c *SHA512_CTX) UpdateString(data string) c.Int {
return c.Update(unsafe.Pointer(unsafe.StringData(data)), uintptr(len(data)))
}
// OSSL_DEPRECATEDIN_3_0 int SHA512_Final(unsigned char *md, SHA512_CTX *c);
//
//go:linkname sha512Final C.SHA512_Final
func sha512Final(md *byte, c *SHA512_CTX) c.Int
func (c *SHA512_CTX) Final(md *byte) c.Int {
return sha512Final(md, c)
}
// OSSL_DEPRECATEDIN_3_0 void SHA512_Transform(SHA512_CTX *c, const unsigned char *data);
//
// llgo:link (*SHA512_CTX).Transform C.SHA512_Transform
func (c *SHA512_CTX) Transform(data *byte) {}
// unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md);
//
//go:linkname SHA384 C.SHA384
func SHA384(data unsafe.Pointer, n uintptr, md *byte) *byte
func SHA384Bytes(data []byte, md *byte) *byte {
return SHA384(unsafe.Pointer(unsafe.SliceData(data)), uintptr(len(data)), md)
}
func SHA384String(data string, md *byte) *byte {
return SHA384(unsafe.Pointer(unsafe.StringData(data)), uintptr(len(data)), md)
}
// unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md);
//
//go:linkname SHA512 C.SHA512
func SHA512(data unsafe.Pointer, n uintptr, md *byte) *byte
func SHA512Bytes(data []byte, md *byte) *byte {
return SHA512(unsafe.Pointer(unsafe.SliceData(data)), uintptr(len(data)), md)
}
func SHA512String(data string, md *byte) *byte {
return SHA512(unsafe.Pointer(unsafe.StringData(data)), uintptr(len(data)), md)
}

9
c/os/_os/os.c Normal file
View File

@@ -0,0 +1,9 @@
#include <stdlib.h>
int llgoClearenv() {
extern char **environ;
if (environ != NULL) {
*environ = NULL;
}
return 0;
}

View File

@@ -27,10 +27,6 @@ import (
"github.com/goplus/llgo/c/syscall" "github.com/goplus/llgo/c/syscall"
) )
const (
LLGoPackage = "decl"
)
const ( const (
PATH_MAX = C.PATH_MAX PATH_MAX = C.PATH_MAX
) )
@@ -150,9 +146,6 @@ func Putenv(env *c.Char) c.Int
//go:linkname Unsetenv C.unsetenv //go:linkname Unsetenv C.unsetenv
func Unsetenv(name *c.Char) c.Int func Unsetenv(name *c.Char) c.Int
//go:linkname Clearenv C.clearenv
func Clearenv()
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
//go:linkname Fchdir C.fchdir //go:linkname Fchdir C.fchdir

28
c/os/os_linux.go Normal file
View File

@@ -0,0 +1,28 @@
//go:build linux
/*
* 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 os
import "C"
const (
LLGoPackage = "decl"
)
//go:linkname Clearenv C.clearenv
func Clearenv()

29
c/os/os_other.go Normal file
View File

@@ -0,0 +1,29 @@
//go:build !linux
/*
* 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 os
import "C"
const (
LLGoFiles = "_os/os.c"
LLGoPackage = "link"
)
//go:linkname Clearenv C.llgoClearenv
func Clearenv()

View File

@@ -5,3 +5,15 @@
pthread_once_t llgoSyncOnceInitVal = PTHREAD_ONCE_INIT; pthread_once_t llgoSyncOnceInitVal = PTHREAD_ONCE_INIT;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// wrap return type to void
void wrap_pthread_mutex_lock(pthread_mutex_t *mutex) {
pthread_mutex_lock(mutex);
}
// wrap return type to void
void wrap_pthread_mutex_unlock(pthread_mutex_t *mutex) {
pthread_mutex_unlock(mutex);
}
// -----------------------------------------------------------------------------

View File

@@ -76,18 +76,14 @@ func (m *Mutex) Init(attr *MutexAttr) c.Int { return 0 }
// llgo:link (*Mutex).Destroy C.pthread_mutex_destroy // llgo:link (*Mutex).Destroy C.pthread_mutex_destroy
func (m *Mutex) Destroy() {} func (m *Mutex) Destroy() {}
func (m *Mutex) Lock() { m.lockInternal() }
// llgo:link (*Mutex).lockInternal C.pthread_mutex_lock
func (m *Mutex) lockInternal() c.Int { return 0 }
// llgo:link (*Mutex).TryLock C.pthread_mutex_trylock // llgo:link (*Mutex).TryLock C.pthread_mutex_trylock
func (m *Mutex) TryLock() c.Int { return 0 } func (m *Mutex) TryLock() c.Int { return 0 }
func (m *Mutex) Unlock() { m.unlockInternal() } // llgo:link (*Mutex).Lock C.wrap_pthread_mutex_lock
func (m *Mutex) Lock() {}
// llgo:link (*Mutex).unlockInternal C.pthread_mutex_unlock // llgo:link (*Mutex).Unlock C.wrap_pthread_mutex_unlock
func (m *Mutex) unlockInternal() c.Int { return 0 } func (m *Mutex) Unlock() {}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@@ -44,9 +44,6 @@ func Longjmp(env *JmpBuf, val c.Int)
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
//go:linkname Sigsetjmp C.sigsetjmp
func Sigsetjmp(env *SigjmpBuf, savemask c.Int) c.Int
//go:linkname Siglongjmp C.siglongjmp //go:linkname Siglongjmp C.siglongjmp
func Siglongjmp(env *SigjmpBuf, val c.Int) func Siglongjmp(env *SigjmpBuf, val c.Int)

12
c/setjmp/setjmp_linux.go Normal file
View File

@@ -0,0 +1,12 @@
//go:build linux
package setjmp
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
//go:linkname Sigsetjmp C.__sigsetjmp
func Sigsetjmp(env *SigjmpBuf, savemask c.Int) c.Int

12
c/setjmp/setjmp_other.go Normal file
View File

@@ -0,0 +1,12 @@
//go:build !linux
package setjmp
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
//go:linkname Sigsetjmp C.sigsetjmp
func Sigsetjmp(env *SigjmpBuf, savemask c.Int) c.Int

View File

@@ -17,7 +17,7 @@
package syscall package syscall
const ( const (
LLGoPackage = "decl" LLGoPackage = "noinit"
) )
type Errno = uintptr type Errno = uintptr
@@ -25,3 +25,8 @@ type Errno = uintptr
// A Signal is a number describing a process signal. // A Signal is a number describing a process signal.
// It implements the os.Signal interface. // It implements the os.Signal interface.
type Signal = int type Signal = int
// Unix returns the time stored in ts as seconds plus nanoseconds.
func (ts *Timespec) Unix() (sec int64, nsec int64) {
return int64(ts.Sec), int64(ts.Nsec)
}

View File

@@ -0,0 +1,11 @@
package main
import (
"fmt"
"github.com/goplus/llgo/c/zlib"
)
func main() {
fmt.Printf("%08x\n", zlib.Crc32ZString(0, "Hello world"))
}

View File

@@ -17,7 +17,7 @@
package zlib package zlib
import ( import (
_ "unsafe" "unsafe"
"github.com/goplus/llgo/c" "github.com/goplus/llgo/c"
) )
@@ -76,17 +76,185 @@ const (
DEFLATED = 8 DEFLATED = 8
) )
// -----------------------------------------------------------------------------
/*
ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
compressBound() returns an upper bound on the compressed size after
compress() or compress2() on sourceLen bytes. It would be used before a
compress() or compress2() call to allocate the destination buffer.
*/
//go:linkname CompressBound C.compressBound //go:linkname CompressBound C.compressBound
func CompressBound(sourceLen c.Ulong) c.Ulong func CompressBound(sourceLen c.Ulong) c.Ulong
/*
ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen));
Compresses the source buffer into the destination buffer. sourceLen is
the byte length of the source buffer. Upon entry, destLen is the total size
of the destination buffer, which must be at least the value returned by
compressBound(sourceLen). Upon exit, destLen is the actual size of the
compressed data. compress() is equivalent to compress2() with a level
parameter of Z_DEFAULT_COMPRESSION.
compress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output
buffer.
*/
//go:linkname Compress C.compress //go:linkname Compress C.compress
func Compress(dest *byte, destLen *c.Ulong, source *byte, sourceLen c.Ulong) c.Int func Compress(dest *byte, destLen *c.Ulong, source *byte, sourceLen c.Ulong) c.Int
/*
ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen, int level));
Compresses the source buffer into the destination buffer. The level
parameter has the same meaning as in deflateInit. sourceLen is the byte
length of the source buffer. Upon entry, destLen is the total size of the
destination buffer, which must be at least the value returned by
compressBound(sourceLen). Upon exit, destLen is the actual size of the
compressed data.
compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_BUF_ERROR if there was not enough room in the output buffer,
Z_STREAM_ERROR if the level parameter is invalid.
*/
//go:linkname Compress2 C.compress2 //go:linkname Compress2 C.compress2
func Compress2(dest *byte, destLen *c.Ulong, source *byte, sourceLen c.Ulong, level c.Int) c.Int func Compress2(dest *byte, destLen *c.Ulong, source *byte, sourceLen c.Ulong, level c.Int) c.Int
/*
ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen));
Decompresses the source buffer into the destination buffer. sourceLen is
the byte length of the source buffer. Upon entry, destLen is the total size
of the destination buffer, which must be large enough to hold the entire
uncompressed data. (The size of the uncompressed data must have been saved
previously by the compressor and transmitted to the decompressor by some
mechanism outside the scope of this compression library.) Upon exit, destLen
is the actual size of the uncompressed data.
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output
buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In
the case where there is not enough room, uncompress() will fill the output
buffer with the uncompressed data up to that point.
*/
//go:linkname Uncompress C.uncompress //go:linkname Uncompress C.uncompress
func Uncompress(dest *byte, destLen *c.Ulong, source *byte, sourceLen c.Ulong) c.Int func Uncompress(dest *byte, destLen *c.Ulong, source *byte, sourceLen c.Ulong) c.Int
/*
ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong *sourceLen));
Same as uncompress, except that sourceLen is a pointer, where the
length of the source is *sourceLen. On return, *sourceLen is the number of
source bytes consumed.
*/
//go:linkname Uncompress2 C.uncompress2 //go:linkname Uncompress2 C.uncompress2
func Uncompress2(dest *byte, destLen *c.Ulong, source *byte, sourceLen *c.Ulong) c.Int func Uncompress2(dest *byte, destLen *c.Ulong, source *byte, sourceLen *c.Ulong) c.Int
// -----------------------------------------------------------------------------
/*
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
Update a running CRC-32 with the bytes buf[0..len-1] and return the
updated CRC-32. If buf is Z_NULL, this function returns the required
initial value for the crc. Pre- and post-conditioning (one's complement) is
performed within this function so it shouldn't be done by the application.
Usage example:
uLong crc = crc32(0L, Z_NULL, 0);
while (read_buffer(buffer, length) != EOF) {
crc = crc32(crc, buffer, length);
}
if (crc != original_crc) error();
*/
//go:linkname Crc32 C.crc32
func Crc32(crc c.Ulong, buf *byte, len c.Uint) c.Ulong
/*
ZEXTERN uLong ZEXPORT crc32_z OF((uLong adler, const Bytef *buf, z_size_t len));
Same as crc32(), but with a size_t length.
*/
//go:linkname Crc32Z C.crc32_z
func Crc32Z(crc c.Ulong, buf *byte, len uintptr) c.Ulong
func Crc32ZBytes(crc c.Ulong, buf []byte) c.Ulong {
return Crc32Z(crc, unsafe.SliceData(buf), uintptr(len(buf)))
}
func Crc32ZString(crc c.Ulong, buf string) c.Ulong {
return Crc32Z(crc, unsafe.StringData(buf), uintptr(len(buf)))
}
/*
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
Combine two CRC-32 check values into one. For two sequences of bytes,
seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
len2.
*/
//go:linkname Crc32Combine C.crc32_combine
func Crc32Combine(crc1 c.Ulong, crc2 c.Ulong, len2 int64) c.Ulong
/*
ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
Update a running Adler-32 checksum with the bytes buf[0..len-1] and
return the updated checksum. If buf is Z_NULL, this function returns the
required initial value for the checksum.
An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed
much faster.
Usage example:
uLong adler = adler32(0L, Z_NULL, 0);
while (read_buffer(buffer, length) != EOF) {
adler = adler32(adler, buffer, length);
}
if (adler != original_adler) error();
*/
//go:linkname Adler32 C.adler32
func Adler32(adler c.Ulong, buf *byte, len c.Uint) c.Ulong
/*
ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf, z_size_t len));
Same as adler32(), but with a size_t length.
*/
//go:linkname Adler32Z C.adler32_z
func Adler32Z(adler c.Ulong, buf *byte, len uintptr) c.Ulong
func Adler32ZBytes(adler c.Ulong, buf []byte) c.Ulong {
return Adler32Z(adler, unsafe.SliceData(buf), uintptr(len(buf)))
}
func Adler32ZString(adler c.Ulong, buf string) c.Ulong {
return Adler32Z(adler, unsafe.StringData(buf), uintptr(len(buf)))
}
/*
ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, z_off_t len2));
Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
that the z_off_t type (like off_t) is a signed integer. If len2 is
negative, the result has no meaning or utility.
*/
//go:linkname Adler32Combine C.adler32_combine
func Adler32Combine(adler1 c.Ulong, adler2 c.Ulong, len2 int64) c.Ulong
// -----------------------------------------------------------------------------

View File

@@ -0,0 +1,217 @@
package main
import (
"fmt"
"os"
"strings"
"unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/clang"
)
type Data struct {
Depth c.Uint
Unit *clang.TranslationUnit
}
var accessMap = map[clang.CXXAccessSpecifier]string{
clang.CXXInvalidAccessSpecifier: "invalid",
clang.CXXPublic: "public",
clang.CXXProtected: "protected",
clang.CXXPrivate: "private",
}
func printIndent(depth c.Uint) {
fmt.Print(strings.Repeat(" ", int(depth)))
}
func accessToString(spec clang.CXXAccessSpecifier) string {
if str, ok := accessMap[spec]; ok {
return str
}
return "unknown"
}
func visit(cursor, parent clang.Cursor, ClientData c.Pointer) clang.ChildVisitResult {
data := (*Data)(ClientData)
printAST(cursor, data)
return clang.ChildVisit_Continue
}
func printType(t clang.Type, data *Data) {
printIndent(data.Depth)
typeSpell := t.String()
typeKind := t.Kind.String()
if t.Kind == clang.TypeInvalid {
} else if t.Kind == clang.TypeUnexposed {
c.Printf(c.Str("<UnexposedType|%s>: %s\n"), typeKind.CStr(), typeSpell.CStr())
} else if t.Kind >= clang.TypeFirstBuiltin && t.Kind <= clang.TypeLastBuiltin {
c.Printf(c.Str("<BuiltinType|%s>: %s\n"), typeKind.CStr(), typeSpell.CStr())
} else if t.Kind > clang.TypeComplex {
c.Printf(c.Str("<ComplexType|%s>: %s\n"), typeKind.CStr(), typeSpell.CStr())
}
data.Depth++
switch t.Kind {
case clang.TypePointer:
printType(t.PointeeType(), data)
case clang.TypeIncompleteArray, clang.TypeVariableArray, clang.TypeDependentSizedArray, clang.TypeConstantArray:
printType(t.ArrayElementType(), data)
case clang.TypeTypedef:
printType(t.CanonicalType(), data)
case clang.TypeFunctionProto:
printType(t.ResultType(), data)
for i := 0; i < int(t.NumArgTypes()); i++ {
printType(t.ArgType(c.Uint(i)), data)
}
}
data.Depth--
typeKind.Dispose()
typeSpell.Dispose()
}
func printLocation(cursor clang.Cursor) {
loc := cursor.Location()
var file clang.File
var line, column c.Uint
loc.SpellingLocation(&file, &line, &column, nil)
filename := file.FileName()
defer filename.Dispose()
c.Printf(c.Str("(Loc:%s:%d:%d)\n"), filename.CStr(), line, column)
}
func printAccess(cursor clang.Cursor) {
kind := cursor.Kind.String()
spell := cursor.String()
defer kind.Dispose()
defer spell.Dispose()
c.Printf(c.Str("%s: %s %s"), kind.CStr(), spell.CStr(), c.AllocaCStr(accessToString(cursor.CXXAccessSpecifier())))
printLocation(cursor)
}
func printMacro(cursor clang.Cursor, unit *clang.TranslationUnit) {
kind := cursor.Kind.String()
defer kind.Dispose()
c.Printf(c.Str("%s: "), kind.CStr())
ran := cursor.Extent()
var numTokens c.Uint
var tokens *clang.Token
unit.Tokenize(ran, &tokens, &numTokens)
tokensSlice := unsafe.Slice(tokens, int(numTokens))
for _, tok := range tokensSlice {
tokStr := unit.Token(tok)
c.Printf(c.Str("%s "), tokStr.CStr())
tokStr.Dispose()
}
printLocation(cursor)
}
func printFunc(cursor clang.Cursor, data *Data) {
kind := cursor.Kind.String()
spell := cursor.String()
symbol := cursor.Mangling()
defer symbol.Dispose()
defer kind.Dispose()
defer spell.Dispose()
c.Printf(c.Str("%s: %s (Symbol: %s)"), kind.CStr(), spell.CStr(), symbol.CStr())
printLocation(cursor)
printType(cursor.Type(), data)
}
func printEnumConstant(cursor clang.Cursor) {
kind := cursor.Kind.String()
spell := cursor.String()
defer kind.Dispose()
defer spell.Dispose()
c.Printf(c.Str("%s: %s:%lld"), kind.CStr(), spell.CStr(), cursor.EnumConstantDeclValue())
printLocation(cursor)
}
func printDefault(cursor clang.Cursor, data *Data) {
kind := cursor.Kind.String()
spell := cursor.String()
defer kind.Dispose()
defer spell.Dispose()
// node which has type
if cursor.Type().Kind != clang.TypeInvalid {
c.Printf(c.Str("%s: %s"), kind.CStr(), spell.CStr())
printLocation(cursor)
printType(cursor.Type(), data)
} else {
c.Printf(c.Str("%s: %s\n"), kind.CStr(), spell.CStr())
}
}
func printAST(cursor clang.Cursor, data *Data) {
kind := cursor.Kind.String()
spell := cursor.String()
printIndent(data.Depth)
switch cursor.Kind {
case clang.CursorCXXAccessSpecifier:
printAccess(cursor)
case clang.CursorMacroDefinition:
printMacro(cursor, data.Unit)
case clang.CursorFunctionDecl, clang.CursorCXXMethod, clang.CursorConstructor, clang.CursorDestructor:
printFunc(cursor, data)
case clang.CursorEnumConstantDecl:
printEnumConstant(cursor)
default:
printDefault(cursor, data)
}
data.Depth++
clang.VisitChildren(cursor, visit, c.Pointer(data))
data.Depth--
kind.Dispose()
spell.Dispose()
}
func main() {
if c.Argc != 2 {
fmt.Fprintln(os.Stderr, "Usage: castdump <headerFile>")
return
}
args := make([]*c.Char, 3)
args[0] = c.Str("-x")
args[1] = c.Str("c++")
args[2] = c.Str("-std=c++11")
sourceFile := *c.Advance(c.Argv, 1)
index := clang.CreateIndex(0, 0)
unit := index.ParseTranslationUnit(
sourceFile,
unsafe.SliceData(args), 3,
nil, 0,
clang.DetailedPreprocessingRecord,
)
defer index.Dispose()
defer unit.Dispose()
if unit == nil {
println("Unable to parse translation unit. Quitting.")
c.Exit(1)
}
cursor := unit.Cursor()
Data := &Data{
Depth: 0,
Unit: unit,
}
printAST(cursor, Data)
}

View File

@@ -0,0 +1,60 @@
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
}

View File

@@ -17,12 +17,21 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"io" "io"
"os" "os"
"path/filepath"
"strings"
"unsafe"
"github.com/goplus/llgo/c" "github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/cjson" "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() { func main() {
@@ -40,14 +49,25 @@ func main() {
} }
check(err) check(err)
conf := cjson.ParseBytes(data) conf, err := config.GetConf(data)
if conf == nil { check(err)
fmt.Fprintln(os.Stderr, "Failed to parse config file:", cfgFile)
os.Exit(1)
}
defer conf.Delete() defer conf.Delete()
c.Printf(c.Str("%s"), conf.Print()) 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) { func check(err error) {
@@ -55,3 +75,159 @@ func check(err error) {
panic(err) 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
}

View File

@@ -0,0 +1,167 @@
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
}

292
chore/llcppg/ast/ast.go Normal file
View File

@@ -0,0 +1,292 @@
/*
* 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 ast
// =============================================================================
type Node interface {
}
type Expr interface {
Node
exprNode()
}
type Decl interface {
Node
declNode()
}
type Stmt interface {
Node
stmtNode()
}
type PPD interface { // preprocessing directive
Node
ppdNode()
}
// =============================================================================
// Expressions (Types are also expressions)
type TypeKind uint
const (
Int TypeKind = iota
Char
Float
Complex
Bool
)
type TypeFlag uint
const (
Signed TypeFlag = 1 << iota
Unsigned
Long
LongLong
Double
Short
)
// [signed/unsigned/short/long/long long/double] [int]/char/float/complex/bool
type BuiltinType struct {
Kind TypeKind
Flags TypeFlag
}
func (*BuiltinType) exprNode() {}
// ------------------------------------------------
// Name
type Ident struct {
Name string
}
func (*Ident) exprNode() {}
// ------------------------------------------------
type Tag int
const (
Struct Tag = iota
Union
Enum
Class
)
// struct/union/enum/class Name
type TagExpr struct {
Tag Tag
Name *Ident
}
func (*TagExpr) exprNode() {}
// ------------------------------------------------
// (X)
type ParenExpr struct {
X Expr
}
func (*ParenExpr) exprNode() {}
// ------------------------------------------------
// Parent::X
type ScopingExpr struct {
Parent Expr
X Expr
}
func (*ScopingExpr) exprNode() {}
// ------------------------------------------------
// X*
type PointerType struct {
X Expr
}
func (*PointerType) exprNode() {}
// ------------------------------------------------
// X&
type ReferenceType struct {
X Expr
}
func (*ReferenceType) exprNode() {}
// ------------------------------------------------
// Elt[Len]
// Elt[]
type ArrayType struct {
Elt Expr
Len Expr // optional
}
func (*ArrayType) exprNode() {}
// ------------------------------------------------
type Comment struct {
Text string // comment text (excluding '\n' for //-style comments)
}
func (*Comment) exprNode() {}
type CommentGroup struct {
List []*Comment // len(List) > 0
}
func (*CommentGroup) exprNode() {}
// ------------------------------------------------
type Field struct {
Doc *CommentGroup // associated documentation; or nil
Type Expr // field/method/parameter type; or nil
Names []*Ident // field/method/(type) parameter names; or nil
Comment *CommentGroup // line comments; or nil
}
func (*Field) exprNode() {}
type FieldList struct {
List []*Field // field list; or nil
}
func (*FieldList) exprNode() {}
// ------------------------------------------------
// Ret (*)(Params)
type FuncType struct {
Params *FieldList
Ret Expr
}
func (*FuncType) exprNode() {}
// ------------------------------------------------
// Template<Arg1, Arg2, ...>
type InstantiationType struct {
Template Expr
Args *FieldList
}
func (*InstantiationType) exprNode() {}
// =============================================================================
// Declarations
type Location struct {
File string
}
type DeclBase struct {
Doc *CommentGroup // associated documentation; or nil
Loc *Location
Parent Expr // namespace or class
}
// ------------------------------------------------
// typedef Type Name;
type TypedefDecl struct {
DeclBase
Type Expr
Name *Ident
}
func (*TypedefDecl) declNode() {}
// ------------------------------------------------
type EnumItem struct {
Name *Ident
Value Expr // optional
}
func (*EnumItem) exprNode() {}
// enum Name { Item1, Item2, ... };
type EnumTypeDecl struct {
DeclBase
Name *Ident
Items []*EnumItem
}
func (*EnumTypeDecl) declNode() {}
// ------------------------------------------------
// Ret Name(Params);
type FuncDecl struct {
DeclBase
Name *Ident
Type *FuncType
}
func (*FuncDecl) declNode() {}
// ------------------------------------------------
// struct/union/class Name { Field1, Field2, ... };
type TypeDecl struct {
DeclBase
Tag Tag
Fields *FieldList
Methods []*FuncDecl
}
func (*TypeDecl) declNode() {}
// =============================================================================
// AST File
type Include struct {
Path string `json:"path"`
}
func (*Include) ppdNode() {}
// ------------------------------------------------
type Macro struct {
}
func (*Macro) ppdNode() {}
// ------------------------------------------------
type File struct {
Decls []Decl `json:"decls"`
Includes []*Include `json:"includes,omitempty"`
Macros []*Macro `json:"macros,omitempty"`
}
// =============================================================================

View File

@@ -59,8 +59,21 @@ llcppsigfetch - # read config from stdin
It fetches information of C/C++ symbols and print to stdout. Its format is as follows: It fetches information of C/C++ symbols and print to stdout. Its format is as follows:
``` ```json
TODO: see llgo/xtool/clang/ast [
{
"path": "/path/to/file.h",
"doc": {
"decls": [],
"macros": [],
"includes": [
{
"path": "incfile.h"
}
]
}
}
]
``` ```
### gogensig ### gogensig
@@ -69,252 +82,3 @@ TODO: see llgo/xtool/clang/ast
gogensig ast-file gogensig ast-file
gogensig - # read AST from stdin gogensig - # read AST from stdin
``` ```
## Overall
### Process
1. The Parsing Module reads `llcppg.cfg` to obtain dynamic libraries, header files, and the package name. After parsing, it writes the generated `llcppg.symb.json` path into `llcppg.cfg`.
2. The Function Declaration Generation Module reads `llcppg.cfg` to get the package name, header files, and the previously generated `llcppg.symb.json`. After parsing, it generates the function prototype `llcppg.function.json`.
3. Reads the previously generated `llcppg.information.json`, stores it as a structure, and uses gogen to generate code based on the structure.
## Parsing Module
### Input
Obtains the paths to header files and dynamic library files by reading the JSON file `llcppg.cfg`.
```json
{
"name": "inih",
"cflags": "$(pkg-config --cflags INIReader)",
"include": [
"INIReader.h",
"AnotherHeaderFile.h"
],
"libs": "$(pkg-config --libs INIReader)",
"trimPrefixes": ["Ini", "INI"]
}
```
```bash
llcppsymg config-file
```
### Implementation Steps
1. Parse dylib and store:
```go
// types.go
type CPPSymbol struct {
Symbol string `json:"symbol"`
Type string `json:"type"`
Name string `json:"name"`
}
// parser_dylib.go
func parseDylibSymbols(lib string) ([]common.CPPSymbol, error)
```
2. Parse header files and store:
```go
// common.go
type ASTInformation struct {
Namespace string `json:"namespace"`
Class string `json:"class"`
Name string `json:"name"`
BaseClasses []string `json:"baseClasses"`
ReturnType string `json:"returnType"`
Location string `json:"location"`
Parameters []Parameter `json:"parameters"`
Symbol string `json:"symbol"`
}
type Parameter struct {
Name string `json:"name"`
Type string `json:"type"`
}
// parser_ast.go
func parseHeaderFile(config types.Config) ([]common.ASTInformation, error)
```
3. Cross-reference data from the first two steps to get the final output
```go
// common.go
type SymbolInfo struct {
Mangle string `json:"mangle"` // C++ Symbol
CPP string `json:"c++"` // C++ function name
Go string `json:"go"` // Go function name
}
// common_symbols.go
func getCommonSymbols(dylibSymbols []common.CPPSymbol, astInfoList []common.ASTInformation) []common.SymbolInfo {
```
4. Generate `llcppg.symb.json` file and store the JSON file path into `llcppg.cfg`
```go
func generateJSON([]CommonSymbolInfo)
```
5. Example `llcppg.symb.json` file
```json
{
"FunctionName": "A::B::C",
"Symbol": "_ZN9INIReaderC1ERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE",
"Location": "a.h",
"UserFunctionName": "CFromA"
}
```
## Function Declaration Generation Module
### Input
No input required, directly reads the `llcppg.cfg` file
### Implementation Steps
1. Execute the executable
```bash
llcppsigfetch config-file
```
2. Parse header files
```go
// common.go
type ASTInformation struct {
Namespace string `json:"namespace"`
Class string `json:"class"`
Name string `json:"name"`
BaseClasses []string `json:"baseClasses"`
ReturnType string `json:"returnType"`
Location string `json:"location"`
Parameters []Parameter `json:"parameters"`
Symbol string `json:"symbol"`
}
type Parameter struct {
Name string `json:"name"`
Type string `json:"type"`
}
// parser_ast.go
func ParseHeaderFile(filePath string) ([]common.ASTInformation, error)
```
3. Generate the final JSON mapping file `llcppg.information.json`
```go
func GenerateJSONFile(info []common.ASTInformation)
```
```json
{
"functionName": "A::B::C",
"symbol": "_ZN9INIReaderC1ERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE",
"location": "a.h",
"returnType": "int",
"userFunctionName": "CFromA",
"parameters": [
{
"arg1": "int"
},
{
"arg2": "*char"
}
]
}
```
## Code Generation Module
### Input
No input required, directly reads `llcppg.information.json` file
### Implementation Steps
1. Execute the executable
```bash
gogensig ast-file
```
2. Parse JSON file
```go
// common.go
type HeaderFileInfo struct {
FunctionName string `json:"functionName"`
Symbol string `json:"symbol"`
Location string `json:"location"`
UserFunctionName string `json:"userFunctionName"`
Parameters map[string]string `json:"parameters"`
}
// parse_json.go
func ParseJSON(jsonFilePath string) ([]common.HeaderFileInfo, error)
```
3. Generate code using the parsed structure with gogen
```go
// generator.go
func GenerateCode(info []common.HeaderFileInfo) {
pkg := gogen.NewPackage("", PackageName, nil)
cm := comment(fmt.Sprintf("llgo:link %s %s", funcName1, symbol1))
pkg.NewFunc(recv, funcName, params, results, variadic).SetComments(pkg, cm).BodyStart(pkg).End()
}
```
### Output
1. Directory structure
```bash
package_name/
├── _demo
├── demo1.go
└── llgo_link.go
└── a.go
└── b.go
└── c.go
```
Note that `demo1.go` file needs to be written by the user
2. `llgo_link.go` is responsible for linking configuration
```go
package inih
const (
LLGoFiles = "$(pkg-config --cflags INIReader): _wrap/reader.cpp"
LLGoPackage = "link: $(pkg-config --libs inih INIReader); -linih -lINIReader"
)
```
3. Example content for `a.go`
```go
package inih
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
//go:linkname Parse C.ini_parse
func Parse(filename *c.Char, handler func(user c.Pointer, section *c.Char, name *c.Char, value *c.Char) c.Int, user c.Pointer) c.Int
//go:linkname ParseFile C.ini_parse_file
func ParseFile(file c.FilePtr, handler func(user c.Pointer, section *c.Char, name *c.Char, value *c.Char) c.Int, user c.Pointer) c.Int
//go:linkname ParseString C.ini_parse_string
func ParseString(str *c.Char, handler func(user c.Pointer, section *c.Char, name *c.Char, value *c.Char) c.Int, user c.Pointer) c.Int
```

View File

@@ -24,3 +24,9 @@ type Config struct {
Include []string `json:"include"` Include []string `json:"include"`
TrimPrefixes []string `json:"trimPrefixes"` TrimPrefixes []string `json:"trimPrefixes"`
} }
type SymbolInfo struct {
Mangle string `json:"mangle"` // C++ Symbol
CPP string `json:"c++"` // C++ function name
Go string `json:"go"` // Go function name
}

View File

@@ -21,7 +21,7 @@ import (
"os" "os"
"github.com/goplus/llgo/xtool/env/llvm" "github.com/goplus/llgo/xtool/env/llvm"
"github.com/goplus/llgo/xtool/nm" "github.com/goplus/llgo/xtool/nm/nmindex"
) )
func main() { func main() {
@@ -58,7 +58,7 @@ func makeIndex() {
idxDir := indexDir() idxDir := indexDir()
os.MkdirAll(idxDir, 0755) os.MkdirAll(idxDir, 0755)
b := nm.NewIndexBuilder(env.Nm()) b := nmindex.NewIndexBuilder(env.Nm())
libDirs := []string{ libDirs := []string{
usrLib(false), usrLib(false),
usrLib(true), usrLib(true),
@@ -78,7 +78,7 @@ func query(q string) {
q = "_" + q q = "_" + q
} }
} }
files, err := nm.Query(indexDir(), q) files, err := nmindex.Query(indexDir(), q)
check(err) check(err)
for _, f := range files { for _, f := range files {
fmt.Printf("%s:\n", f.ArFile) fmt.Printf("%s:\n", f.ArFile)

View File

@@ -2,6 +2,7 @@
source_filename = "main" source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } %"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
%main.T = type { ptr, ptr }
@"main.init$guard" = global i1 false, align 1 @"main.init$guard" = global i1 false, align 1
@__llgo_argc = global i32 0, align 4 @__llgo_argc = global i32 0, align 4
@@ -37,12 +38,12 @@ _llgo_0:
store i64 3, ptr %5, align 4 store i64 3, ptr %5, align 4
%6 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %3, align 8 %6 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %3, align 8
store %"github.com/goplus/llgo/internal/runtime.String" %6, ptr %2, align 8 store %"github.com/goplus/llgo/internal/runtime.String" %6, ptr %2, align 8
%7 = alloca { ptr, ptr }, align 8 %7 = alloca %main.T, align 8
%8 = getelementptr inbounds { ptr, ptr }, ptr %7, i32 0, i32 0 %8 = getelementptr inbounds %main.T, ptr %7, i32 0, i32 0
store ptr @"__llgo_stub.main.main$1", ptr %8, align 8 store ptr @"__llgo_stub.main.main$1", ptr %8, align 8
%9 = getelementptr inbounds { ptr, ptr }, ptr %7, i32 0, i32 1 %9 = getelementptr inbounds %main.T, ptr %7, i32 0, i32 1
store ptr null, ptr %9, align 8 store ptr null, ptr %9, align 8
%10 = load { ptr, ptr }, ptr %7, align 8 %10 = load %main.T, ptr %7, align 8
%11 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8) %11 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8)
%12 = getelementptr inbounds { ptr }, ptr %11, i32 0, i32 0 %12 = getelementptr inbounds { ptr }, ptr %11, i32 0, i32 0
store ptr %2, ptr %12, align 8 store ptr %2, ptr %12, align 8
@@ -52,12 +53,15 @@ _llgo_0:
%15 = getelementptr inbounds { ptr, ptr }, ptr %13, i32 0, i32 1 %15 = getelementptr inbounds { ptr, ptr }, ptr %13, i32 0, i32 1
store ptr %11, ptr %15, align 8 store ptr %11, ptr %15, align 8
%16 = load { ptr, ptr }, ptr %13, align 8 %16 = load { ptr, ptr }, ptr %13, align 8
%17 = extractvalue { ptr, ptr } %10, 1 %17 = alloca %main.T, align 8
%18 = extractvalue { ptr, ptr } %10, 0 store { ptr, ptr } %16, ptr %17, align 8
call void %18(ptr %17, i64 100) %18 = load %main.T, ptr %17, align 8
%19 = extractvalue { ptr, ptr } %16, 1 %19 = extractvalue %main.T %10, 1
%20 = extractvalue { ptr, ptr } %16, 0 %20 = extractvalue %main.T %10, 0
call void %20(ptr %19, i64 200) call void %20(ptr %19, i64 100)
%21 = extractvalue %main.T %18, 1
%22 = extractvalue %main.T %18, 0
call void %22(ptr %21, i64 200)
ret i32 0 ret i32 0
} }

17
cl/_testgo/defer5/in.go Normal file
View File

@@ -0,0 +1,17 @@
package main
func main() {
defer println("A")
defer func() {
if e := recover(); e != nil {
println("in defer 1")
panic("panic in defer 1")
}
}()
defer func() {
println("in defer 2")
panic("panic in defer 2")
}()
defer println("B")
panic("panic in main")
}

1
cl/_testgo/defer5/out.ll Normal file
View File

@@ -0,0 +1 @@
;

View File

@@ -543,10 +543,12 @@ _llgo_0:
define void @"main.init#7"() { define void @"main.init#7"() {
_llgo_0: _llgo_0:
%0 = load ptr, ptr @"map[_llgo_int]_llgo_string", align 8 %0 = load ptr, ptr @_llgo_int, align 8
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.MakeMap"(ptr %0, i64 0) %1 = load ptr, ptr @_llgo_string, align 8
%2 = icmp ne ptr %1, null %2 = load ptr, ptr @"map[_llgo_int]_llgo_string", align 8
call void @main.assert(i1 %2) %3 = call ptr @"github.com/goplus/llgo/internal/runtime.MakeMap"(ptr %2, i64 0)
%4 = icmp ne ptr %3, null
call void @main.assert(i1 %4)
call void @main.assert(i1 true) call void @main.assert(i1 true)
ret void ret void
} }

View File

@@ -304,13 +304,13 @@ _llgo_0:
%14 = getelementptr inbounds %main.T5, ptr %13, i32 0, i32 0 %14 = getelementptr inbounds %main.T5, ptr %13, i32 0, i32 0
store i64 300, ptr %14, align 4 store i64 300, ptr %14, align 4
%15 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 16) %15 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 16)
%16 = alloca { ptr, ptr }, align 8 %16 = alloca %main.T6, align 8
%17 = getelementptr inbounds { ptr, ptr }, ptr %16, i32 0, i32 0 %17 = getelementptr inbounds %main.T6, ptr %16, i32 0, i32 0
store ptr @"__llgo_stub.main.main$1", ptr %17, align 8 store ptr @"__llgo_stub.main.main$1", ptr %17, align 8
%18 = getelementptr inbounds { ptr, ptr }, ptr %16, i32 0, i32 1 %18 = getelementptr inbounds %main.T6, ptr %16, i32 0, i32 1
store ptr null, ptr %18, align 8 store ptr null, ptr %18, align 8
%19 = load { ptr, ptr }, ptr %16, align 8 %19 = load %main.T6, ptr %16, align 8
store { ptr, ptr } %19, ptr %15, align 8 store %main.T6 %19, ptr %15, align 8
%20 = load %main.T, ptr %2, align 8 %20 = load %main.T, ptr %2, align 8
%21 = load ptr, ptr @_llgo_main.T, align 8 %21 = load ptr, ptr @_llgo_main.T, align 8
%22 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16) %22 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16)

View File

@@ -0,0 +1,63 @@
package main
type Func func(a int, b int) int
type Func2 func(a int, b int) int
type Call struct {
fn Func
n int
}
func (c *Call) add(a int, b int) int {
return a + b + c.n
}
func add(a int, b int) int {
return a + b
}
func demo1(n int) Func {
m := &Call{n: n}
m.fn = m.add
return m.fn
}
func demo2() Func {
m := &Call{}
return m.add
}
func demo3() Func {
return add
}
func demo4() Func {
return func(a, b int) int { return a + b }
}
func demo5(n int) Func {
return func(a, b int) int { return a + b + n }
}
func main() {
n1 := demo1(1)(99, 200)
println(n1)
n2 := demo2()(100, 200)
println(n2)
n3 := demo3()(100, 200)
println(n3)
n4 := demo4()(100, 200)
println(n4)
n5 := demo5(1)(99, 200)
println(n5)
var fn func(a int, b int) int = demo5(1)
println(fn(99, 200))
var fn2 Func2 = (Func2)(demo5(1))
println(fn2(99, 200))
}

View File

@@ -0,0 +1,220 @@
; ModuleID = 'main'
source_filename = "main"
%main.Call = type { %main.Func, i64 }
%main.Func = type { ptr, ptr }
@"main.init$guard" = global i1 false, align 1
@__llgo_argc = global i32 0, align 4
@__llgo_argv = global ptr null, align 8
define i64 @"main.(*Call).add"(ptr %0, i64 %1, i64 %2) {
_llgo_0:
%3 = add i64 %1, %2
%4 = getelementptr inbounds %main.Call, ptr %0, i32 0, i32 1
%5 = load i64, ptr %4, align 4
%6 = add i64 %3, %5
ret i64 %6
}
define i64 @main.add(i64 %0, i64 %1) {
_llgo_0:
%2 = add i64 %0, %1
ret i64 %2
}
define %main.Func @main.demo1(i64 %0) {
_llgo_0:
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 24)
%2 = getelementptr inbounds %main.Call, ptr %1, i32 0, i32 1
store i64 %0, ptr %2, align 4
%3 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8)
%4 = getelementptr inbounds { ptr }, ptr %3, i32 0, i32 0
store ptr %1, ptr %4, align 8
%5 = alloca { ptr, ptr }, align 8
%6 = getelementptr inbounds { ptr, ptr }, ptr %5, i32 0, i32 0
store ptr @"main.add$bound", ptr %6, align 8
%7 = getelementptr inbounds { ptr, ptr }, ptr %5, i32 0, i32 1
store ptr %3, ptr %7, align 8
%8 = load { ptr, ptr }, ptr %5, align 8
%9 = getelementptr inbounds %main.Call, ptr %1, i32 0, i32 0
%10 = alloca %main.Func, align 8
store { ptr, ptr } %8, ptr %10, align 8
%11 = load %main.Func, ptr %10, align 8
store %main.Func %11, ptr %9, align 8
%12 = getelementptr inbounds %main.Call, ptr %1, i32 0, i32 0
%13 = load %main.Func, ptr %12, align 8
ret %main.Func %13
}
define %main.Func @main.demo2() {
_llgo_0:
%0 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 24)
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8)
%2 = getelementptr inbounds { ptr }, ptr %1, i32 0, i32 0
store ptr %0, ptr %2, align 8
%3 = alloca { ptr, ptr }, align 8
%4 = getelementptr inbounds { ptr, ptr }, ptr %3, i32 0, i32 0
store ptr @"main.add$bound", ptr %4, align 8
%5 = getelementptr inbounds { ptr, ptr }, ptr %3, i32 0, i32 1
store ptr %1, ptr %5, align 8
%6 = load { ptr, ptr }, ptr %3, align 8
%7 = alloca %main.Func, align 8
store { ptr, ptr } %6, ptr %7, align 8
%8 = load %main.Func, ptr %7, align 8
ret %main.Func %8
}
define %main.Func @main.demo3() {
_llgo_0:
%0 = alloca %main.Func, align 8
%1 = getelementptr inbounds %main.Func, ptr %0, i32 0, i32 0
store ptr @__llgo_stub.main.add, ptr %1, align 8
%2 = getelementptr inbounds %main.Func, ptr %0, i32 0, i32 1
store ptr null, ptr %2, align 8
%3 = load %main.Func, ptr %0, align 8
ret %main.Func %3
}
define %main.Func @main.demo4() {
_llgo_0:
%0 = alloca %main.Func, align 8
%1 = getelementptr inbounds %main.Func, ptr %0, i32 0, i32 0
store ptr @"__llgo_stub.main.demo4$1", ptr %1, align 8
%2 = getelementptr inbounds %main.Func, ptr %0, i32 0, i32 1
store ptr null, ptr %2, align 8
%3 = load %main.Func, ptr %0, align 8
ret %main.Func %3
}
define i64 @"main.demo4$1"(i64 %0, i64 %1) {
_llgo_0:
%2 = add i64 %0, %1
ret i64 %2
}
define %main.Func @main.demo5(i64 %0) {
_llgo_0:
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 8)
store i64 %0, ptr %1, align 4
%2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8)
%3 = getelementptr inbounds { ptr }, ptr %2, i32 0, i32 0
store ptr %1, ptr %3, align 8
%4 = alloca { ptr, ptr }, align 8
%5 = getelementptr inbounds { ptr, ptr }, ptr %4, i32 0, i32 0
store ptr @"main.demo5$1", ptr %5, align 8
%6 = getelementptr inbounds { ptr, ptr }, ptr %4, i32 0, i32 1
store ptr %2, ptr %6, align 8
%7 = load { ptr, ptr }, ptr %4, align 8
%8 = alloca %main.Func, align 8
store { ptr, ptr } %7, ptr %8, align 8
%9 = load %main.Func, ptr %8, align 8
ret %main.Func %9
}
define i64 @"main.demo5$1"(ptr %0, i64 %1, i64 %2) {
_llgo_0:
%3 = add i64 %1, %2
%4 = load { ptr }, ptr %0, align 8
%5 = extractvalue { ptr } %4, 0
%6 = load i64, ptr %5, align 4
%7 = add i64 %3, %6
ret i64 %7
}
define void @main.init() {
_llgo_0:
%0 = load i1, ptr @"main.init$guard", align 1
br i1 %0, label %_llgo_2, label %_llgo_1
_llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"main.init$guard", align 1
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void
}
define i32 @main(i32 %0, ptr %1) {
_llgo_0:
store i32 %0, ptr @__llgo_argc, align 4
store ptr %1, ptr @__llgo_argv, align 8
call void @"github.com/goplus/llgo/internal/runtime.init"()
call void @main.init()
%2 = call %main.Func @main.demo1(i64 1)
%3 = extractvalue %main.Func %2, 1
%4 = extractvalue %main.Func %2, 0
%5 = call i64 %4(ptr %3, i64 99, i64 200)
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %5)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
%6 = call %main.Func @main.demo2()
%7 = extractvalue %main.Func %6, 1
%8 = extractvalue %main.Func %6, 0
%9 = call i64 %8(ptr %7, i64 100, i64 200)
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %9)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
%10 = call %main.Func @main.demo3()
%11 = extractvalue %main.Func %10, 1
%12 = extractvalue %main.Func %10, 0
%13 = call i64 %12(ptr %11, i64 100, i64 200)
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %13)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
%14 = call %main.Func @main.demo4()
%15 = extractvalue %main.Func %14, 1
%16 = extractvalue %main.Func %14, 0
%17 = call i64 %16(ptr %15, i64 100, i64 200)
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %17)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
%18 = call %main.Func @main.demo5(i64 1)
%19 = extractvalue %main.Func %18, 1
%20 = extractvalue %main.Func %18, 0
%21 = call i64 %20(ptr %19, i64 99, i64 200)
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %21)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
%22 = call %main.Func @main.demo5(i64 1)
%23 = alloca { ptr, ptr }, align 8
store %main.Func %22, ptr %23, align 8
%24 = load { ptr, ptr }, ptr %23, align 8
%25 = extractvalue { ptr, ptr } %24, 1
%26 = extractvalue { ptr, ptr } %24, 0
%27 = call i64 %26(ptr %25, i64 99, i64 200)
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %27)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
%28 = call %main.Func @main.demo5(i64 1)
%29 = extractvalue %main.Func %28, 1
%30 = extractvalue %main.Func %28, 0
%31 = call i64 %30(ptr %29, i64 99, i64 200)
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %31)
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
ret i32 0
}
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
define i64 @"main.add$bound"(ptr %0, i64 %1, i64 %2) {
_llgo_0:
%3 = load { ptr }, ptr %0, align 8
%4 = extractvalue { ptr } %3, 0
%5 = call i64 @"main.(*Call).add"(ptr %4, i64 %1, i64 %2)
ret i64 %5
}
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64)
define linkonce i64 @__llgo_stub.main.add(ptr %0, i64 %1, i64 %2) {
_llgo_0:
%3 = tail call i64 @main.add(i64 %1, i64 %2)
ret i64 %3
}
define linkonce i64 @"__llgo_stub.main.demo4$1"(ptr %0, i64 %1, i64 %2) {
_llgo_0:
%3 = tail call i64 @"main.demo4$1"(i64 %1, i64 %2)
ret i64 %3
}
declare void @"github.com/goplus/llgo/internal/runtime.init"()
declare void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64)
declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8)

View File

@@ -7,6 +7,7 @@ func main() {
make4() make4()
make5() make5()
make6() make6()
make7()
} }
func make1() { func make1() {
@@ -113,3 +114,15 @@ func make6() {
println(k, v) println(k, v)
} }
} }
func make7() {
type N int
m := map[N]string{
1: "hello",
2: "world",
}
for k, v := range m {
println(k, v)
}
println(m[1])
}

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More