Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee0e0a5c51 | ||
|
|
7b2747ce0c | ||
|
|
578bc165c4 | ||
|
|
a1d46e905b | ||
|
|
9102ca6b1e | ||
|
|
835d6fee1e | ||
|
|
294abb5126 | ||
|
|
5fca8ebd4e | ||
|
|
d3df782fca | ||
|
|
b04ac8df30 | ||
|
|
bb03df7059 | ||
|
|
98072f3f4b | ||
|
|
3bf0780a67 | ||
|
|
a1fdc05e26 | ||
|
|
93bff83e3d | ||
|
|
e470bc2069 | ||
|
|
efa771f3ff | ||
|
|
806193fc6e | ||
|
|
cdfa0166bd | ||
|
|
0687efaec6 | ||
|
|
0d3e78ad94 | ||
|
|
375b2b579e | ||
|
|
a578155dcb | ||
|
|
df5f1afb74 | ||
|
|
b2a2b2f29d | ||
|
|
91df9957f5 | ||
|
|
08e0ace9a2 | ||
|
|
a4286dbd4b | ||
|
|
f2e15a6846 |
74
.github/workflows/doc.yml
vendored
74
.github/workflows/doc.yml
vendored
@@ -1,74 +0,0 @@
|
|||||||
name: Docs
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ "**" ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ "**" ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
doc_verify:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Set up Node.js
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: '20'
|
|
||||||
|
|
||||||
- name: Install embedme
|
|
||||||
run: npm install -g embedme
|
|
||||||
|
|
||||||
- name: Verify README.md embedded code
|
|
||||||
run: npx embedme --verify README.md
|
|
||||||
|
|
||||||
doc_test:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os:
|
|
||||||
- macos-latest
|
|
||||||
- ubuntu-24.04
|
|
||||||
runs-on: ${{matrix.os}}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Set up Go
|
|
||||||
uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: '1.20'
|
|
||||||
|
|
||||||
- name: Install dependencies on macOS
|
|
||||||
if: startsWith(matrix.os, 'macos')
|
|
||||||
run: |
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
source doc/_readme/scripts/install_macos.sh
|
|
||||||
|
|
||||||
- name: Install dependencies on Ubuntu
|
|
||||||
if: startsWith(matrix.os, 'ubuntu')
|
|
||||||
run: |
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
source doc/_readme/scripts/install_ubuntu.sh
|
|
||||||
|
|
||||||
- name: Install llgo
|
|
||||||
run: |
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
git() {
|
|
||||||
if [ "$1" = "clone" ]; then
|
|
||||||
# do nothing because we already have the branch
|
|
||||||
cd ..
|
|
||||||
else
|
|
||||||
command git "$@"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
source doc/_readme/scripts/install_llgo.sh
|
|
||||||
|
|
||||||
- name: Test doc code blocks
|
|
||||||
run: |
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
source doc/_readme/scripts/run.sh
|
|
||||||
|
|
||||||
61
.github/workflows/go.yml
vendored
61
.github/workflows/go.yml
vendored
@@ -5,27 +5,11 @@ name: Go
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ "**" ]
|
branches: [ "*" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "**" ]
|
branches: [ "*" ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
fmt:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Set up Go
|
|
||||||
uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: '1.20'
|
|
||||||
|
|
||||||
- name: Check formatting
|
|
||||||
run: |
|
|
||||||
if [ -n "$(go fmt ./...)" ]; then
|
|
||||||
echo "Some files are not properly formatted. Please run 'go fmt ./...'"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
test:
|
test:
|
||||||
strategy:
|
strategy:
|
||||||
@@ -42,8 +26,7 @@ jobs:
|
|||||||
if: startsWith(matrix.os, 'macos')
|
if: startsWith(matrix.os, 'macos')
|
||||||
run: |
|
run: |
|
||||||
brew update
|
brew update
|
||||||
brew install llvm@${{matrix.llvm}} bdw-gc openssl libffi
|
brew install llvm@${{matrix.llvm}} pkg-config bdw-gc openssl
|
||||||
brew link --force libffi
|
|
||||||
echo "$(brew --prefix llvm@${{matrix.llvm}})/bin" >> $GITHUB_PATH
|
echo "$(brew --prefix llvm@${{matrix.llvm}})/bin" >> $GITHUB_PATH
|
||||||
|
|
||||||
# Install optional deps for demos.
|
# Install optional deps for demos.
|
||||||
@@ -62,7 +45,7 @@ jobs:
|
|||||||
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}} libclang-${{matrix.llvm}}-dev lld-${{matrix.llvm}} pkg-config libgc-dev libssl-dev zlib1g-dev libffi-dev libcjson-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.
|
# Install optional deps for demos.
|
||||||
@@ -82,7 +65,7 @@ jobs:
|
|||||||
numpy # for github.com/goplus/llgo/py/numpy
|
numpy # for github.com/goplus/llgo/py/numpy
|
||||||
torch # for github.com/goplus/llgo/py/torch
|
torch # for github.com/goplus/llgo/py/torch
|
||||||
)
|
)
|
||||||
pip3.12 install --break-system-packages "${py_deps[@]}"
|
pip3 install --break-system-packages "${py_deps[@]}"
|
||||||
|
|
||||||
- name: Clang information
|
- name: Clang information
|
||||||
run: |
|
run: |
|
||||||
@@ -98,9 +81,6 @@ jobs:
|
|||||||
- name: Build
|
- name: Build
|
||||||
run: go build -v ./...
|
run: go build -v ./...
|
||||||
|
|
||||||
- name: Install
|
|
||||||
run: go install ./...
|
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
if: ${{!startsWith(matrix.os, 'macos')}}
|
if: ${{!startsWith(matrix.os, 'macos')}}
|
||||||
run: go test -v ./...
|
run: go test -v ./...
|
||||||
@@ -109,48 +89,31 @@ jobs:
|
|||||||
if: startsWith(matrix.os, 'macos')
|
if: startsWith(matrix.os, 'macos')
|
||||||
run: go test -v -coverprofile="coverage.txt" -covermode=atomic ./...
|
run: go test -v -coverprofile="coverage.txt" -covermode=atomic ./...
|
||||||
|
|
||||||
|
- name: Install
|
||||||
|
run: go install ./...
|
||||||
|
|
||||||
- name: LLGO tests
|
- name: LLGO tests
|
||||||
if: ${{!startsWith(matrix.os, 'ubuntu')}}
|
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
|
||||||
bash .github/workflows/test_llgo.sh
|
bash .github/workflows/test_llgo.sh
|
||||||
|
|
||||||
- name: chore/_xtool build tests
|
|
||||||
run: |
|
|
||||||
cd chore/_xtool
|
|
||||||
llgo build -v ./...
|
|
||||||
|
|
||||||
- name: LLDB tests
|
|
||||||
if: ${{startsWith(matrix.os, 'macos')}}
|
|
||||||
run: |
|
|
||||||
echo "Test lldb with llgo plugin on ${{matrix.os}} with LLVM ${{matrix.llvm}}"
|
|
||||||
bash _lldb/runtest.sh -v
|
|
||||||
|
|
||||||
- name: Test demos
|
- name: Test demos
|
||||||
run: |
|
continue-on-error: true
|
||||||
# TODO(lijie): force python3-embed to be linked with python-3.12-embed
|
run: bash .github/workflows/test_demo.sh
|
||||||
# Currently, python3-embed is python-3.13-embed, doesn't work with pytorch
|
|
||||||
# Will remove this after pytorch is fixed.
|
|
||||||
pcdir=$HOME/pc
|
|
||||||
mkdir -p $pcdir
|
|
||||||
libdir=$(pkg-config --variable=libdir python-3.12-embed)
|
|
||||||
echo "libdir: $libdir"
|
|
||||||
ln -s $libdir/pkgconfig/python-3.12-embed.pc $pcdir/python3-embed.pc
|
|
||||||
export PKG_CONFIG_PATH=$pcdir
|
|
||||||
bash .github/workflows/test_demo.sh
|
|
||||||
|
|
||||||
- name: Show test result
|
- name: Show test result
|
||||||
run: cat result.md
|
run: cat result.md
|
||||||
|
|
||||||
- name: PR comment with test result
|
- name: PR comment with test result
|
||||||
uses: thollander/actions-comment-pull-request@v3
|
uses: thollander/actions-comment-pull-request@v2
|
||||||
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@v5
|
uses: codecov/codecov-action@v4
|
||||||
with:
|
with:
|
||||||
token: ${{secrets.CODECOV_TOKEN}}
|
token: ${{secrets.CODECOV_TOKEN}}
|
||||||
slug: goplus/llgo
|
slug: goplus/llgo
|
||||||
|
|||||||
2
.github/workflows/populate_darwin_sysroot.sh
vendored
2
.github/workflows/populate_darwin_sysroot.sh
vendored
@@ -11,7 +11,7 @@ DARWIN_ARM64_LLVM_PREFIX=.sysroot/darwin/arm64/opt/homebrew/opt/llvm@18
|
|||||||
mkdir -p "${DARWIN_AMD64_LLVM_PREFIX}" "${DARWIN_ARM64_LLVM_PREFIX}"
|
mkdir -p "${DARWIN_AMD64_LLVM_PREFIX}" "${DARWIN_ARM64_LLVM_PREFIX}"
|
||||||
|
|
||||||
BREW_LLVM_FORMULA_JSON="$(mktemp)"
|
BREW_LLVM_FORMULA_JSON="$(mktemp)"
|
||||||
curl -fsSL https://formulae.brew.sh/api/formula/llvm@18.json > "${BREW_LLVM_FORMULA_JSON}"
|
curl -fsSL https://formulae.brew.sh/api/formula/llvm.json > "${BREW_LLVM_FORMULA_JSON}"
|
||||||
BREW_LLVM_AMD64_BOTTLE_URL=$(jq -r '.bottle.stable.files.sonoma.url' "${BREW_LLVM_FORMULA_JSON}")
|
BREW_LLVM_AMD64_BOTTLE_URL=$(jq -r '.bottle.stable.files.sonoma.url' "${BREW_LLVM_FORMULA_JSON}")
|
||||||
BREW_LLVM_ARM64_BOTTLE_URL=$(jq -r '.bottle.stable.files.arm64_sonoma.url' "${BREW_LLVM_FORMULA_JSON}")
|
BREW_LLVM_ARM64_BOTTLE_URL=$(jq -r '.bottle.stable.files.arm64_sonoma.url' "${BREW_LLVM_FORMULA_JSON}")
|
||||||
curl -fsSL -H "Authorization: Bearer QQ==" "${BREW_LLVM_AMD64_BOTTLE_URL}" | tar -xzf - --strip-components=2 -C "${DARWIN_AMD64_LLVM_PREFIX}"
|
curl -fsSL -H "Authorization: Bearer QQ==" "${BREW_LLVM_AMD64_BOTTLE_URL}" | tar -xzf - --strip-components=2 -C "${DARWIN_AMD64_LLVM_PREFIX}"
|
||||||
|
|||||||
4
.github/workflows/test_demo.sh
vendored
4
.github/workflows/test_demo.sh
vendored
@@ -1,13 +1,13 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# llgo run subdirectories under _demo and _pydemo that contain *.go files
|
# llgo run subdirectories under _demo and _pydemo
|
||||||
total=0
|
total=0
|
||||||
failed=0
|
failed=0
|
||||||
failed_cases=""
|
failed_cases=""
|
||||||
for d in ./_demo/* ./_pydemo/*; do
|
for d in ./_demo/* ./_pydemo/*; do
|
||||||
if [ -d "$d" ] && [ -n "$(ls "$d"/*.go 2>/dev/null)" ]; then
|
|
||||||
total=$((total+1))
|
total=$((total+1))
|
||||||
|
if [ -d "$d" ]; then
|
||||||
echo "Testing $d"
|
echo "Testing $d"
|
||||||
if ! (cd "$d" && llgo run .); then
|
if ! (cd "$d" && llgo run .); then
|
||||||
echo "FAIL"
|
echo "FAIL"
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -26,9 +26,6 @@ build.dir/
|
|||||||
# Test binary, built with `go test -c`
|
# Test binary, built with `go test -c`
|
||||||
*.test
|
*.test
|
||||||
|
|
||||||
# Debug symbols
|
|
||||||
*.dSYM
|
|
||||||
|
|
||||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
*.out
|
*.out
|
||||||
*.swp
|
*.swp
|
||||||
|
|||||||
52
README.md
52
README.md
@@ -47,8 +47,6 @@ You can import a C/C++ standard library in LLGo!
|
|||||||
|
|
||||||
Here is a simple example:
|
Here is a simple example:
|
||||||
|
|
||||||
<!-- embedme doc/_readme/llgo_simple/simple.go -->
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@@ -79,8 +77,6 @@ llgo run .
|
|||||||
|
|
||||||
LLGo use `go:linkname` to link an extern symbol througth its ABI:
|
LLGo use `go:linkname` to link an extern symbol througth its ABI:
|
||||||
|
|
||||||
<!-- embedme doc/_readme/llgo_call_c/call_c.go#L3-L6 -->
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import _ "unsafe" // for go:linkname
|
import _ "unsafe" // for go:linkname
|
||||||
|
|
||||||
@@ -90,8 +86,6 @@ func Sqrt(x float64) float64
|
|||||||
|
|
||||||
You can directly integrate it into [your own code](_demo/linkname/linkname.go):
|
You can directly integrate it into [your own code](_demo/linkname/linkname.go):
|
||||||
|
|
||||||
<!-- embedme doc/_readme/llgo_call_c/call_c.go -->
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@@ -107,8 +101,6 @@ func main() {
|
|||||||
|
|
||||||
Or put it into a package (see [c/math](c/math/math.go)):
|
Or put it into a package (see [c/math](c/math/math.go)):
|
||||||
|
|
||||||
<!-- embedme doc/_readme/llgo_call_cmath/call_cmath.go -->
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@@ -143,8 +135,6 @@ Note: For third-party libraries (such as pandas and pytorch), you still need to
|
|||||||
|
|
||||||
Here is an example:
|
Here is an example:
|
||||||
|
|
||||||
<!-- embedme doc/_readme/llgo_call_py/call_py.go -->
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@@ -162,8 +152,6 @@ func main() {
|
|||||||
|
|
||||||
It is equivalent to the following Python code:
|
It is equivalent to the following Python code:
|
||||||
|
|
||||||
<!-- embedme doc/_readme/llgo_call_py/call_math.py -->
|
|
||||||
|
|
||||||
```py
|
```py
|
||||||
import math
|
import math
|
||||||
|
|
||||||
@@ -175,8 +163,6 @@ Here, We call `py.Float(2)` to create a Python number 2, and pass it to Python
|
|||||||
|
|
||||||
Let's look at a slightly more complex example. For example, we use `numpy` to calculate:
|
Let's look at a slightly more complex example. For example, we use `numpy` to calculate:
|
||||||
|
|
||||||
<!-- embedme doc/_readme/llgo_py_list/py_list.go -->
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@@ -228,7 +214,6 @@ The currently supported libraries include:
|
|||||||
* [c/bdwgc](https://pkg.go.dev/github.com/goplus/llgo/c/bdwgc)
|
* [c/bdwgc](https://pkg.go.dev/github.com/goplus/llgo/c/bdwgc)
|
||||||
* [c/cjson](https://pkg.go.dev/github.com/goplus/llgo/c/cjson)
|
* [c/cjson](https://pkg.go.dev/github.com/goplus/llgo/c/cjson)
|
||||||
* [c/clang](https://pkg.go.dev/github.com/goplus/llgo/c/clang)
|
* [c/clang](https://pkg.go.dev/github.com/goplus/llgo/c/clang)
|
||||||
* [c/ffi](https://pkg.go.dev/github.com/goplus/llgo/c/ffi)
|
|
||||||
* [c/libuv](https://pkg.go.dev/github.com/goplus/llgo/c/libuv)
|
* [c/libuv](https://pkg.go.dev/github.com/goplus/llgo/c/libuv)
|
||||||
* [c/llama2](https://pkg.go.dev/github.com/goplus/llgo/c/llama2)
|
* [c/llama2](https://pkg.go.dev/github.com/goplus/llgo/c/llama2)
|
||||||
* [c/lua](https://pkg.go.dev/github.com/goplus/llgo/c/lua)
|
* [c/lua](https://pkg.go.dev/github.com/goplus/llgo/c/lua)
|
||||||
@@ -250,7 +235,7 @@ Here are some examples related to them:
|
|||||||
|
|
||||||
## Go syntax support
|
## Go syntax support
|
||||||
|
|
||||||
All Go syntax (including `cgo`) is already supported. Here are some examples:
|
All Go syntax (not including `cgo`) is already supported. Here are some examples:
|
||||||
|
|
||||||
* [concat](_demo/concat/concat.go): define a variadic function
|
* [concat](_demo/concat/concat.go): define a variadic function
|
||||||
* [genints](_demo/genints/genints.go): various forms of closure usage (including C function, recv.method and anonymous function)
|
* [genints](_demo/genints/genints.go): various forms of closure usage (including C function, recv.method and anonymous function)
|
||||||
@@ -318,7 +303,6 @@ Here are the Go packages that can be imported correctly:
|
|||||||
* [encoding/base32](https://pkg.go.dev/encoding/base32)
|
* [encoding/base32](https://pkg.go.dev/encoding/base32)
|
||||||
* [encoding/base64](https://pkg.go.dev/encoding/base64)
|
* [encoding/base64](https://pkg.go.dev/encoding/base64)
|
||||||
* [encoding/csv](https://pkg.go.dev/encoding/csv)
|
* [encoding/csv](https://pkg.go.dev/encoding/csv)
|
||||||
* [net/textproto](https://pkg.go.dev/net/textproto)
|
|
||||||
* [hash](https://pkg.go.dev/hash)
|
* [hash](https://pkg.go.dev/hash)
|
||||||
* [hash/adler32](https://pkg.go.dev/hash/adler32)
|
* [hash/adler32](https://pkg.go.dev/hash/adler32)
|
||||||
* [hash/crc32](https://pkg.go.dev/hash/crc32) (partially)
|
* [hash/crc32](https://pkg.go.dev/hash/crc32) (partially)
|
||||||
@@ -328,9 +312,7 @@ Here are the Go packages that can be imported correctly:
|
|||||||
* [crypto/sha1](https://pkg.go.dev/crypto/sha1)
|
* [crypto/sha1](https://pkg.go.dev/crypto/sha1)
|
||||||
* [crypto/sha256](https://pkg.go.dev/crypto/sha256)
|
* [crypto/sha256](https://pkg.go.dev/crypto/sha256)
|
||||||
* [crypto/sha512](https://pkg.go.dev/crypto/sha512) (partially)
|
* [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/rand](https://pkg.go.dev/crypto/rand) (partially)
|
||||||
* [crypto/subtle](https://pkg.go.dev/crypto/subtle) (partially)
|
|
||||||
* [regexp](https://pkg.go.dev/regexp)
|
* [regexp](https://pkg.go.dev/regexp)
|
||||||
* [regexp/syntax](https://pkg.go.dev/regexp/syntax)
|
* [regexp/syntax](https://pkg.go.dev/regexp/syntax)
|
||||||
* [go/token](https://pkg.go.dev/go/token)
|
* [go/token](https://pkg.go.dev/go/token)
|
||||||
@@ -341,8 +323,8 @@ Here are the Go packages that can be imported correctly:
|
|||||||
|
|
||||||
- [Go 1.20+](https://go.dev)
|
- [Go 1.20+](https://go.dev)
|
||||||
- [LLVM 18](https://llvm.org)
|
- [LLVM 18](https://llvm.org)
|
||||||
- [Clang 18](https://clang.llvm.org)
|
|
||||||
- [LLD 18](https://lld.llvm.org)
|
- [LLD 18](https://lld.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/)
|
||||||
- [OpenSSL 3.0+](https://www.openssl.org/)
|
- [OpenSSL 3.0+](https://www.openssl.org/)
|
||||||
@@ -355,45 +337,24 @@ Follow these steps to generate the `llgo` command (its usage is the same as the
|
|||||||
|
|
||||||
### on macOS
|
### on macOS
|
||||||
|
|
||||||
<!-- embedme doc/_readme/scripts/install_macos.sh#L2-L1000 -->
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
brew update
|
brew update
|
||||||
brew install llvm@18 bdw-gc openssl cjson libffi
|
brew install llvm@18 pkg-config bdw-gc openssl
|
||||||
brew install python@3.12 # optional
|
brew install python@3.12 # optional
|
||||||
brew link --force libffi
|
|
||||||
go install -v github.com/goplus/llgo/cmd/llgo@latest
|
go install -v github.com/goplus/llgo/cmd/llgo@latest
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### on Linux
|
### on Linux (Debian/Ubuntu)
|
||||||
|
|
||||||
#### Debian/Ubuntu
|
|
||||||
|
|
||||||
<!-- embedme doc/_readme/scripts/install_ubuntu.sh#L2-L1000 -->
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-18 main" | sudo tee /etc/apt/sources.list.d/llvm.list
|
echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-18 main" | sudo tee /etc/apt/sources.list.d/llvm.list
|
||||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y llvm-18-dev clang-18 libclang-18-dev lld-18 pkg-config libgc-dev libssl-dev zlib1g-dev libcjson-dev libsqlite3-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 python3.12-dev # optional
|
sudo apt-get install -y python3.12-dev # optional
|
||||||
go install -v github.com/goplus/llgo/cmd/llgo@latest
|
go install -v github.com/goplus/llgo/cmd/llgo@latest
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Alpine Linux
|
|
||||||
|
|
||||||
```sh
|
|
||||||
apk add go llvm18-dev clang18-dev lld18 pkgconf gc-dev openssl-dev zlib-dev
|
|
||||||
apk add python3-dev # optional
|
|
||||||
apk add g++ # build only
|
|
||||||
export LLVM_CONFIG=/usr/lib/llvm18/bin/llvm-config
|
|
||||||
export CGO_CPPFLAGS="$($LLVM_CONFIG --cppflags)"
|
|
||||||
export CGO_CXXFLAGS=-std=c++17
|
|
||||||
export CGO_LDFLAGS="$($LLVM_CONFIG --ldflags) $($LLVM_CONFIG --libs all)"
|
|
||||||
go install -v -tags=byollvm -ldflags="-X github.com/goplus/llgo/xtool/env/llvm.ldLLVMConfigBin=$LLVM_CONFIG" github.com/goplus/llgo/cmd/llgo@latest
|
|
||||||
```
|
|
||||||
|
|
||||||
### on Windows
|
### on Windows
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
@@ -409,12 +370,9 @@ TODO
|
|||||||
|
|
||||||
How do I generate these tools?
|
How do I generate these tools?
|
||||||
|
|
||||||
<!-- embedme doc/_readme/scripts/install_llgo.sh#L2-L1000 -->
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone https://github.com/goplus/llgo.git
|
git clone https://github.com/goplus/llgo.git
|
||||||
cd llgo
|
cd llgo
|
||||||
go install -v ./cmd/...
|
|
||||||
go install -v ./chore/... # compile all tools except pydump
|
go install -v ./chore/... # compile all tools except pydump
|
||||||
cd chore/_xtool
|
cd chore/_xtool
|
||||||
llgo install ./... # compile pydump
|
llgo install ./... # compile pydump
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
func fib() {
|
func main() {
|
||||||
// Initialize two big ints with the first two numbers in the sequence.
|
// Initialize two big ints with the first two numbers in the sequence.
|
||||||
a := big.NewInt(0)
|
a := big.NewInt(0)
|
||||||
b := big.NewInt(1)
|
b := big.NewInt(1)
|
||||||
@@ -23,41 +23,3 @@ func fib() {
|
|||||||
}
|
}
|
||||||
fmt.Println(a) // 100-digit Fibonacci number
|
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()
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
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))
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
package async
|
|
||||||
|
|
||||||
import (
|
|
||||||
_ "unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Void = [0]byte
|
|
||||||
|
|
||||||
type Future[T any] interface {
|
|
||||||
Then(cb func(T))
|
|
||||||
}
|
|
||||||
|
|
||||||
type future[T any] struct {
|
|
||||||
cb func(func(T))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *future[T]) Then(cb func(T)) {
|
|
||||||
f.cb(cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Async[T any](fn func(func(T))) Future[T] {
|
|
||||||
return &future[T]{fn}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Run[T any](future Future[T]) T {
|
|
||||||
var ret T
|
|
||||||
future.Then(func(v T) {
|
|
||||||
ret = v
|
|
||||||
})
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/_demo/async/async"
|
|
||||||
"github.com/goplus/llgo/_demo/async/timeout"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Sleep(i int, d time.Duration) async.Future[int] {
|
|
||||||
return async.Async(func(resolve func(int)) {
|
|
||||||
timeout.Timeout(d).Then(func(async.Void) {
|
|
||||||
resolve(i)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
async.Run(async.Async(func(resolve func(async.Void)) {
|
|
||||||
println("read file")
|
|
||||||
defer resolve(async.Void{})
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package timeout
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/_demo/async/async"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Timeout(d time.Duration) async.Future[async.Void] {
|
|
||||||
return async.Async(func(resolve func(async.Void)) {
|
|
||||||
go func() {
|
|
||||||
time.Sleep(d)
|
|
||||||
resolve(async.Void{})
|
|
||||||
}()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../cl/_testgo/cgobasic
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../cl/_testgo/cgocfiles
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../cl/_testgo/cgodefer
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../cl/_testgo/cgofull
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../cl/_testgo/cgomacro
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../cl/_testgo/cgopython
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
tempDir := os.TempDir()
|
|
||||||
noexist := filepath.Join(tempDir, "noexist.txt")
|
|
||||||
|
|
||||||
if _, err := os.Stat(noexist); err != nil {
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
fmt.Println("noexist:", err.Error())
|
|
||||||
} else {
|
|
||||||
fmt.Println("exist,other err:", err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := os.Open(noexist); err != nil {
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
fmt.Println("noexist:", err.Error())
|
|
||||||
} else {
|
|
||||||
fmt.Println("exist,other err:", err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import "net/textproto"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
h := make(textproto.MIMEHeader)
|
|
||||||
h.Set("host", "www.example.com")
|
|
||||||
println(h.Get("Host"))
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Expected output:
|
|
||||||
www.example.com
|
|
||||||
*/
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
tempDir, err := os.MkdirTemp("", "example*")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Failed to create temp directory:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer os.Remove(tempDir)
|
|
||||||
fmt.Println("Temp directory:", tempDir)
|
|
||||||
|
|
||||||
tempFile, err := os.CreateTemp("", "example*.txt")
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Failed to create temp file:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer tempFile.Close()
|
|
||||||
defer os.Remove(tempFile.Name())
|
|
||||||
fmt.Println("Temp file:", tempFile.Name())
|
|
||||||
|
|
||||||
nestedDir := filepath.Join("nested", "directory")
|
|
||||||
err = os.MkdirAll(nestedDir, 0755)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Failed to create nested directory:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fmt.Println("Nest directory:", nestedDir)
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
func add(a, b int) int {
|
|
||||||
return a + b
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
fn := func(a, b int) int {
|
|
||||||
return a + b
|
|
||||||
}
|
|
||||||
var i int
|
|
||||||
fn1 := func() {
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
fn2 := func() func() {
|
|
||||||
return func() {
|
|
||||||
println("closure", i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fns := []any{add, fn, fn1, fn2}
|
|
||||||
for _, fn := range fns {
|
|
||||||
v := reflect.ValueOf(fn)
|
|
||||||
fmt.Println(v.Type())
|
|
||||||
fmt.Println(v.Kind())
|
|
||||||
if v.Kind() != reflect.Func {
|
|
||||||
panic(fmt.Sprintf("not func: %T", fn))
|
|
||||||
}
|
|
||||||
|
|
||||||
t := v.Type()
|
|
||||||
fmt.Println(t)
|
|
||||||
fmt.Println(t.Kind())
|
|
||||||
if t.Kind() != reflect.Func {
|
|
||||||
panic(fmt.Sprintf("not func: %T", fn))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"sync"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
llsync "github.com/goplus/llgo/c/pthread/sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
type L struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
s string
|
|
||||||
i int
|
|
||||||
w io.Writer
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
l := &L{s: "hello", i: 123, w: os.Stdout}
|
|
||||||
println("sizeof(L):", unsafe.Sizeof(L{}))
|
|
||||||
println("sizeof(sync.Mutex):", unsafe.Sizeof(sync.Mutex{}))
|
|
||||||
println("sizeof(llsync.Mutex):", unsafe.Sizeof(llsync.Mutex{}))
|
|
||||||
println("l:", l, "l.s:", l.s, "l.i:", l.i, "l.w:", l.w)
|
|
||||||
l.mu.Lock()
|
|
||||||
println("locked")
|
|
||||||
println("l:", l, "l.s:", l.s, "l.i:", l.i, "l.w:", l.w)
|
|
||||||
l.w.Write([]byte(l.s))
|
|
||||||
l.w.Write([]byte("\n"))
|
|
||||||
l.mu.Unlock()
|
|
||||||
}
|
|
||||||
115
_lldb/README.md
115
_lldb/README.md
@@ -1,115 +0,0 @@
|
|||||||
## LLGo Plugin of LLDB
|
|
||||||
|
|
||||||
### Build with debug info
|
|
||||||
|
|
||||||
```shell
|
|
||||||
LLGO_DEBUG=1 llgo build -o cl/_testdata/debug/out ./cl/_testdata/debug
|
|
||||||
```
|
|
||||||
|
|
||||||
### Debug with lldb
|
|
||||||
|
|
||||||
```shell
|
|
||||||
_lldb/runlldb.sh ./cl/_testdata/debug/out
|
|
||||||
```
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
```shell
|
|
||||||
/opt/homebrew/bin/lldb -O "command script import _lldb/llgo_plugin.py" ./cl/_testdata/debug/out
|
|
||||||
# github.com/goplus/llgo/cl/_testdata/debug
|
|
||||||
Breakpoint 1: no locations (pending).
|
|
||||||
Breakpoint set in dummy target, will get copied into future targets.
|
|
||||||
(lldb) command script import _lldb/llgo_plugin.py
|
|
||||||
(lldb) target create "./cl/_testdata/debug/out"
|
|
||||||
Current executable set to '/Users/lijie/source/goplus/llgo/cl/_testdata/debug/out' (arm64).
|
|
||||||
(lldb) r
|
|
||||||
Process 21992 launched: '/Users/lijie/source/goplus/llgo/cl/_testdata/debug/out' (arm64)
|
|
||||||
globalInt: 301
|
|
||||||
s: 0x100123e40
|
|
||||||
0x100123be0
|
|
||||||
5 8
|
|
||||||
called function with struct
|
|
||||||
1 2 3 4 5 6 7 8 9 10 +1.100000e+01 +1.200000e+01 true (+1.300000e+01+1.400000e+01i) (+1.500000e+01+1.600000e+01i) [3/3]0x1001129a0 [3/3]0x100112920 hello 0x1001149b0 0x100123ab0 0x100123d10 0x1001149e0 (0x100116810,0x1001149d0) 0x10011bf00 0x10010fa80 (0x100116840,0x100112940) 0x10001b4a4
|
|
||||||
9
|
|
||||||
1 (0x1001167e0,0x100112900)
|
|
||||||
called function with types
|
|
||||||
0x100123e40
|
|
||||||
0x1000343d0
|
|
||||||
Process 21992 stopped
|
|
||||||
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
|
|
||||||
frame #0: 0x000000010001b3b4 out`main at in.go:225:12
|
|
||||||
222 // s.i8: '\x01'
|
|
||||||
223 // s.i16: 2
|
|
||||||
224 s.i8 = 0x12
|
|
||||||
-> 225 println(s.i8)
|
|
||||||
226 // Expected:
|
|
||||||
227 // all variables: globalInt globalStruct globalStructPtr s i err
|
|
||||||
228 // s.i8: '\x12'
|
|
||||||
(lldb) v
|
|
||||||
var i int = <variable not available>
|
|
||||||
var s github.com/goplus/llgo/cl/_testdata/debug.StructWithAllTypeFields = {
|
|
||||||
i8 = '\x12',
|
|
||||||
i16 = 2,
|
|
||||||
i32 = 3,
|
|
||||||
i64 = 4,
|
|
||||||
i = 5,
|
|
||||||
u8 = '\x06',
|
|
||||||
u16 = 7,
|
|
||||||
u32 = 8,
|
|
||||||
u64 = 9,
|
|
||||||
u = 10,
|
|
||||||
f32 = 11,
|
|
||||||
f64 = 12,
|
|
||||||
b = true,
|
|
||||||
c64 = {real = 13, imag = 14},
|
|
||||||
c128 = {real = 15, imag = 16},
|
|
||||||
slice = []int{21, 22, 23},
|
|
||||||
arr = [3]int{24, 25, 26},
|
|
||||||
arr2 = [3]github.com/goplus/llgo/cl/_testdata/debug.E{{i = 27}, {i = 28}, {i = 29}},
|
|
||||||
s = "hello",
|
|
||||||
e = {i = 30},
|
|
||||||
pf = 0x0000000100123d10,
|
|
||||||
pi = 0x00000001001149e0,
|
|
||||||
intr = {type = 0x0000000100116810, data = 0x00000001001149d0},
|
|
||||||
m = {count = 4296130304},
|
|
||||||
c = {},
|
|
||||||
err = {type = 0x0000000100116840, data = 0x0000000100112940},
|
|
||||||
fn = {f = 0x000000010001b4a4, data = 0x00000001001149c0},
|
|
||||||
pad1 = 100,
|
|
||||||
pad2 = 200
|
|
||||||
}
|
|
||||||
var globalStructPtr *github.com/goplus/llgo/cl/_testdata/debug.StructWithAllTypeFields = <variable not available>
|
|
||||||
var globalStruct github.com/goplus/llgo/cl/_testdata/debug.StructWithAllTypeFields = {
|
|
||||||
i8 = '\x01',
|
|
||||||
i16 = 2,
|
|
||||||
i32 = 3,
|
|
||||||
i64 = 4,
|
|
||||||
i = 5,
|
|
||||||
u8 = '\x06',
|
|
||||||
u16 = 7,
|
|
||||||
u32 = 8,
|
|
||||||
u64 = 9,
|
|
||||||
u = 10,
|
|
||||||
f32 = 11,
|
|
||||||
f64 = 12,
|
|
||||||
b = true,
|
|
||||||
c64 = {real = 13, imag = 14},
|
|
||||||
c128 = {real = 15, imag = 16},
|
|
||||||
slice = []int{21, 22, 23},
|
|
||||||
arr = [3]int{24, 25, 26},
|
|
||||||
arr2 = [3]github.com/goplus/llgo/cl/_testdata/debug.E{{i = 27}, {i = 28}, {i = 29}},
|
|
||||||
s = "hello",
|
|
||||||
e = {i = 30},
|
|
||||||
pf = 0x0000000100123d10,
|
|
||||||
pi = 0x00000001001149e0,
|
|
||||||
intr = {type = 0x0000000100116810, data = 0x00000001001149d0},
|
|
||||||
m = {count = 4296130304},
|
|
||||||
c = {},
|
|
||||||
err = {type = 0x0000000100116840, data = 0x0000000100112940},
|
|
||||||
fn = {f = 0x000000010001b4a4, data = 0x00000001001149c0},
|
|
||||||
pad1 = 100,
|
|
||||||
pad2 = 200
|
|
||||||
}
|
|
||||||
var globalInt int = 301
|
|
||||||
var err error = {type = 0x0000000100112900, data = 0x000000000000001a}
|
|
||||||
```
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Function to find LLDB 18+
|
|
||||||
find_lldb() {
|
|
||||||
local lldb_paths=(
|
|
||||||
"/opt/homebrew/bin/lldb"
|
|
||||||
"/usr/local/bin/lldb"
|
|
||||||
"/usr/bin/lldb"
|
|
||||||
"lldb" # This will use the system PATH
|
|
||||||
)
|
|
||||||
|
|
||||||
for lldb_path in "${lldb_paths[@]}"; do
|
|
||||||
if command -v "$lldb_path" >/dev/null 2>&1; then
|
|
||||||
local version
|
|
||||||
version=$("$lldb_path" --version | grep -oE '[0-9]+' | head -1)
|
|
||||||
if [ "$version" -ge 18 ]; then
|
|
||||||
echo "$lldb_path"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Error: LLDB 18 or higher not found" >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Find LLDB 18+
|
|
||||||
LLDB_PATH=$(find_lldb)
|
|
||||||
echo "LLDB_PATH: $LLDB_PATH"
|
|
||||||
$LLDB_PATH --version
|
|
||||||
export LLDB_PATH
|
|
||||||
|
|
||||||
# Default package path
|
|
||||||
export DEFAULT_PACKAGE_PATH="./cl/_testdata/debug"
|
|
||||||
|
|
||||||
# Function to build the project
|
|
||||||
build_project() {
|
|
||||||
local package_path="$1"
|
|
||||||
LLGO_DEBUG=1 go run ./cmd/llgo build -o "${package_path}/debug.out" "${package_path}"
|
|
||||||
}
|
|
||||||
@@ -1,297 +0,0 @@
|
|||||||
# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring
|
|
||||||
|
|
||||||
from typing import List, Optional, Dict, Any, Tuple
|
|
||||||
import re
|
|
||||||
import lldb
|
|
||||||
|
|
||||||
|
|
||||||
def log(*args: Any, **kwargs: Any) -> None:
|
|
||||||
print(*args, **kwargs, flush=True)
|
|
||||||
|
|
||||||
|
|
||||||
def __lldb_init_module(debugger: lldb.SBDebugger, _: Dict[str, Any]) -> None:
|
|
||||||
debugger.HandleCommand(
|
|
||||||
'command script add -f llgo_plugin.print_go_expression p')
|
|
||||||
debugger.HandleCommand(
|
|
||||||
'command script add -f llgo_plugin.print_all_variables v')
|
|
||||||
|
|
||||||
|
|
||||||
def is_llgo_compiler(_target: lldb.SBTarget) -> bool:
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def get_indexed_value(value: lldb.SBValue, index: int) -> Optional[lldb.SBValue]:
|
|
||||||
if not value or not value.IsValid():
|
|
||||||
return None
|
|
||||||
|
|
||||||
type_name = value.GetType().GetName()
|
|
||||||
|
|
||||||
if type_name.startswith('[]'): # Slice
|
|
||||||
data_ptr = value.GetChildMemberWithName('data')
|
|
||||||
element_type = data_ptr.GetType().GetPointeeType()
|
|
||||||
element_size = element_type.GetByteSize()
|
|
||||||
ptr_value = int(data_ptr.GetValue(), 16)
|
|
||||||
element_address = ptr_value + index * element_size
|
|
||||||
target = value.GetTarget()
|
|
||||||
return target.CreateValueFromAddress(
|
|
||||||
f"element_{index}", lldb.SBAddress(element_address, target), element_type)
|
|
||||||
elif value.GetType().IsArrayType(): # Array
|
|
||||||
return value.GetChildAtIndex(index)
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def evaluate_expression(frame: lldb.SBFrame, expression: str) -> Optional[lldb.SBValue]:
|
|
||||||
parts = re.findall(r'\*|\w+|\(|\)|\[.*?\]|\.', expression)
|
|
||||||
|
|
||||||
def evaluate_part(i: int) -> Tuple[Optional[lldb.SBValue], int]:
|
|
||||||
nonlocal parts
|
|
||||||
value: Optional[lldb.SBValue] = None
|
|
||||||
while i < len(parts):
|
|
||||||
part = parts[i]
|
|
||||||
|
|
||||||
if part == '*':
|
|
||||||
sub_value, i = evaluate_part(i + 1)
|
|
||||||
if sub_value and sub_value.IsValid():
|
|
||||||
value = sub_value.Dereference()
|
|
||||||
else:
|
|
||||||
return None, i
|
|
||||||
elif part == '(':
|
|
||||||
depth = 1
|
|
||||||
j = i + 1
|
|
||||||
while j < len(parts) and depth > 0:
|
|
||||||
if parts[j] == '(':
|
|
||||||
depth += 1
|
|
||||||
elif parts[j] == ')':
|
|
||||||
depth -= 1
|
|
||||||
j += 1
|
|
||||||
value, i = evaluate_part(i + 1)
|
|
||||||
i = j - 1
|
|
||||||
elif part == ')':
|
|
||||||
return value, i + 1
|
|
||||||
elif part == '.':
|
|
||||||
if value is None:
|
|
||||||
value = frame.FindVariable(parts[i+1])
|
|
||||||
else:
|
|
||||||
value = value.GetChildMemberWithName(parts[i+1])
|
|
||||||
i += 2
|
|
||||||
elif part.startswith('['):
|
|
||||||
index = int(part[1:-1])
|
|
||||||
value = get_indexed_value(value, index)
|
|
||||||
i += 1
|
|
||||||
else:
|
|
||||||
if value is None:
|
|
||||||
value = frame.FindVariable(part)
|
|
||||||
else:
|
|
||||||
value = value.GetChildMemberWithName(part)
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
if not value or not value.IsValid():
|
|
||||||
return None, i
|
|
||||||
|
|
||||||
return value, i
|
|
||||||
|
|
||||||
value, _ = evaluate_part(0)
|
|
||||||
return value
|
|
||||||
|
|
||||||
|
|
||||||
def print_go_expression(debugger: lldb.SBDebugger, command: str, result: lldb.SBCommandReturnObject, _internal_dict: Dict[str, Any]) -> None:
|
|
||||||
frame = debugger.GetSelectedTarget().GetProcess(
|
|
||||||
).GetSelectedThread().GetSelectedFrame()
|
|
||||||
value = evaluate_expression(frame, command)
|
|
||||||
if value and value.IsValid():
|
|
||||||
result.AppendMessage(format_value(value, debugger))
|
|
||||||
else:
|
|
||||||
result.AppendMessage(
|
|
||||||
f"Error: Unable to evaluate expression '{command}'")
|
|
||||||
|
|
||||||
|
|
||||||
def print_all_variables(debugger: lldb.SBDebugger, _command: str, result: lldb.SBCommandReturnObject, _internal_dict: Dict[str, Any]) -> None:
|
|
||||||
target = debugger.GetSelectedTarget()
|
|
||||||
if not is_llgo_compiler(target):
|
|
||||||
result.AppendMessage("Not a LLGo compiled binary.")
|
|
||||||
return
|
|
||||||
|
|
||||||
frame = debugger.GetSelectedTarget().GetProcess(
|
|
||||||
).GetSelectedThread().GetSelectedFrame()
|
|
||||||
variables = frame.GetVariables(True, True, True, True)
|
|
||||||
|
|
||||||
output: List[str] = []
|
|
||||||
for var in variables:
|
|
||||||
type_name = map_type_name(var.GetType().GetName())
|
|
||||||
formatted = format_value(var, debugger, include_type=False, indent=0)
|
|
||||||
output.append(f"var {var.GetName()} {type_name} = {formatted}")
|
|
||||||
|
|
||||||
result.AppendMessage("\n".join(output))
|
|
||||||
|
|
||||||
|
|
||||||
def is_pointer(frame: lldb.SBFrame, var_name: str) -> bool:
|
|
||||||
var = frame.FindVariable(var_name)
|
|
||||||
return var.IsValid() and var.GetType().IsPointerType()
|
|
||||||
|
|
||||||
|
|
||||||
def format_value(var: lldb.SBValue, debugger: lldb.SBDebugger, include_type: bool = True, indent: int = 0) -> str:
|
|
||||||
if not var.IsValid():
|
|
||||||
return "<variable not available>"
|
|
||||||
|
|
||||||
var_type = var.GetType()
|
|
||||||
type_class = var_type.GetTypeClass()
|
|
||||||
type_name = map_type_name(var_type.GetName())
|
|
||||||
|
|
||||||
# Handle typedef types
|
|
||||||
original_type_name = type_name
|
|
||||||
while var_type.IsTypedefType():
|
|
||||||
var_type = var_type.GetTypedefedType()
|
|
||||||
type_name = map_type_name(var_type.GetName())
|
|
||||||
type_class = var_type.GetTypeClass()
|
|
||||||
|
|
||||||
if var_type.IsPointerType():
|
|
||||||
return format_pointer(var, debugger, indent, original_type_name)
|
|
||||||
|
|
||||||
if type_name.startswith('[]'): # Slice
|
|
||||||
return format_slice(var, debugger, indent)
|
|
||||||
elif var_type.IsArrayType():
|
|
||||||
return format_array(var, debugger, indent)
|
|
||||||
elif type_name == 'string': # String
|
|
||||||
return format_string(var)
|
|
||||||
elif type_class in [lldb.eTypeClassStruct, lldb.eTypeClassClass]:
|
|
||||||
return format_struct(var, debugger, include_type, indent, original_type_name)
|
|
||||||
else:
|
|
||||||
value = var.GetValue()
|
|
||||||
summary = var.GetSummary()
|
|
||||||
if value is not None:
|
|
||||||
return f"{value}" if include_type else str(value)
|
|
||||||
elif summary is not None:
|
|
||||||
return f"{summary}" if include_type else summary
|
|
||||||
else:
|
|
||||||
return "<variable not available>"
|
|
||||||
|
|
||||||
|
|
||||||
def format_slice(var: lldb.SBValue, debugger: lldb.SBDebugger, indent: int) -> str:
|
|
||||||
length = var.GetChildMemberWithName('len').GetValue()
|
|
||||||
if length is None:
|
|
||||||
return "<variable not available>"
|
|
||||||
length = int(length)
|
|
||||||
data_ptr = var.GetChildMemberWithName('data')
|
|
||||||
elements: List[str] = []
|
|
||||||
|
|
||||||
ptr_value = int(data_ptr.GetValue(), 16)
|
|
||||||
element_type = data_ptr.GetType().GetPointeeType()
|
|
||||||
element_size = element_type.GetByteSize()
|
|
||||||
|
|
||||||
target = debugger.GetSelectedTarget()
|
|
||||||
indent_str = ' ' * indent
|
|
||||||
next_indent_str = ' ' * (indent + 1)
|
|
||||||
|
|
||||||
for i in range(length):
|
|
||||||
element_address = ptr_value + i * element_size
|
|
||||||
element = target.CreateValueFromAddress(
|
|
||||||
f"element_{i}", lldb.SBAddress(element_address, target), element_type)
|
|
||||||
value = format_value(
|
|
||||||
element, debugger, include_type=False, indent=indent+1)
|
|
||||||
elements.append(value)
|
|
||||||
|
|
||||||
type_name = var.GetType().GetName()
|
|
||||||
|
|
||||||
if len(elements) > 5: # 如果元素数量大于5,则进行折行显示
|
|
||||||
result = f"{type_name}{{\n{next_indent_str}" + \
|
|
||||||
f",\n{next_indent_str}".join(elements) + f"\n{indent_str}}}"
|
|
||||||
else:
|
|
||||||
result = f"{type_name}{{{', '.join(elements)}}}"
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def format_array(var: lldb.SBValue, debugger: lldb.SBDebugger, indent: int) -> str:
|
|
||||||
elements: List[str] = []
|
|
||||||
indent_str = ' ' * indent
|
|
||||||
next_indent_str = ' ' * (indent + 1)
|
|
||||||
|
|
||||||
for i in range(var.GetNumChildren()):
|
|
||||||
value = format_value(var.GetChildAtIndex(
|
|
||||||
i), debugger, include_type=False, indent=indent+1)
|
|
||||||
elements.append(value)
|
|
||||||
|
|
||||||
array_size = var.GetNumChildren()
|
|
||||||
element_type = map_type_name(var.GetType().GetArrayElementType().GetName())
|
|
||||||
type_name = f"[{array_size}]{element_type}"
|
|
||||||
|
|
||||||
if len(elements) > 5: # wrap line if too many elements
|
|
||||||
return f"{type_name}{{\n{next_indent_str}" + f",\n{next_indent_str}".join(elements) + f"\n{indent_str}}}"
|
|
||||||
else:
|
|
||||||
return f"{type_name}{{{', '.join(elements)}}}"
|
|
||||||
|
|
||||||
|
|
||||||
def format_string(var: lldb.SBValue) -> str:
|
|
||||||
summary = var.GetSummary()
|
|
||||||
if summary is not None:
|
|
||||||
return summary # Keep the quotes
|
|
||||||
else:
|
|
||||||
data = var.GetChildMemberWithName('data').GetValue()
|
|
||||||
length = var.GetChildMemberWithName('len').GetValue()
|
|
||||||
if data and length:
|
|
||||||
length = int(length)
|
|
||||||
error = lldb.SBError()
|
|
||||||
return '"%s"' % var.process.ReadCStringFromMemory(int(data, 16), length + 1, error)
|
|
||||||
return "<variable not available>"
|
|
||||||
|
|
||||||
|
|
||||||
def format_struct(var: lldb.SBValue, debugger: lldb.SBDebugger, include_type: bool = True, indent: int = 0, type_name: str = "") -> str:
|
|
||||||
children: List[str] = []
|
|
||||||
indent_str = ' ' * indent
|
|
||||||
next_indent_str = ' ' * (indent + 1)
|
|
||||||
|
|
||||||
for i in range(var.GetNumChildren()):
|
|
||||||
child = var.GetChildAtIndex(i)
|
|
||||||
child_name = child.GetName()
|
|
||||||
child_value = format_value(
|
|
||||||
child, debugger, include_type=False, indent=indent+1)
|
|
||||||
children.append(f"{child_name} = {child_value}")
|
|
||||||
|
|
||||||
if len(children) > 5: # 如果字段数量大于5,则进行折行显示
|
|
||||||
struct_content = "{\n" + ",\n".join(
|
|
||||||
[f"{next_indent_str}{child}" for child in children]) + f"\n{indent_str}}}"
|
|
||||||
else:
|
|
||||||
struct_content = f"{{{', '.join(children)}}}"
|
|
||||||
|
|
||||||
if include_type:
|
|
||||||
return f"{type_name}{struct_content}"
|
|
||||||
else:
|
|
||||||
return struct_content
|
|
||||||
|
|
||||||
|
|
||||||
def format_pointer(var: lldb.SBValue, _debugger: lldb.SBDebugger, _indent: int, _type_name: str) -> str:
|
|
||||||
if not var.IsValid() or var.GetValueAsUnsigned() == 0:
|
|
||||||
return "<variable not available>"
|
|
||||||
return var.GetValue() # Return the address as a string
|
|
||||||
|
|
||||||
|
|
||||||
def map_type_name(type_name: str) -> str:
|
|
||||||
# Handle pointer types
|
|
||||||
if type_name.endswith('*'):
|
|
||||||
base_type = type_name[:-1].strip()
|
|
||||||
mapped_base_type = map_type_name(base_type)
|
|
||||||
return f"*{mapped_base_type}"
|
|
||||||
|
|
||||||
# Map other types
|
|
||||||
type_mapping: Dict[str, str] = {
|
|
||||||
'long': 'int',
|
|
||||||
'void': 'unsafe.Pointer',
|
|
||||||
'char': 'byte',
|
|
||||||
'short': 'int16',
|
|
||||||
'int': 'int32',
|
|
||||||
'long long': 'int64',
|
|
||||||
'unsigned char': 'uint8',
|
|
||||||
'unsigned short': 'uint16',
|
|
||||||
'unsigned int': 'uint32',
|
|
||||||
'unsigned long': 'uint',
|
|
||||||
'unsigned long long': 'uint64',
|
|
||||||
'float': 'float32',
|
|
||||||
'double': 'float64',
|
|
||||||
}
|
|
||||||
|
|
||||||
for c_type, go_type in type_mapping.items():
|
|
||||||
if type_name.startswith(c_type):
|
|
||||||
return type_name.replace(c_type, go_type, 1)
|
|
||||||
|
|
||||||
return type_name
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Source common functions and variables
|
|
||||||
# shellcheck source=./_lldb/common.sh
|
|
||||||
source "$(dirname "$0")/common.sh"
|
|
||||||
|
|
||||||
executable="$1"
|
|
||||||
|
|
||||||
# Get the directory of the current script
|
|
||||||
script_dir="$(dirname "$0")"
|
|
||||||
|
|
||||||
# Run LLDB with the LLGO plugin
|
|
||||||
"$LLDB_PATH" -O "command script import ${script_dir}/llgo_plugin.py" "$executable"
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Source common functions and variables
|
|
||||||
# shellcheck source=./_lldb/common.sh
|
|
||||||
# shellcheck disable=SC1091
|
|
||||||
source "$(dirname "$0")/common.sh" || exit 1
|
|
||||||
|
|
||||||
# Parse command-line arguments
|
|
||||||
package_path="$DEFAULT_PACKAGE_PATH"
|
|
||||||
verbose=False
|
|
||||||
interactive=False
|
|
||||||
plugin_path=None
|
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
case $1 in
|
|
||||||
-v|--verbose)
|
|
||||||
verbose=True
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
-i|--interactive)
|
|
||||||
interactive=True
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
-p|--plugin)
|
|
||||||
plugin_path="\"$2\""
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
package_path="$1"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
# Build the project
|
|
||||||
build_project "$package_path" || exit 1
|
|
||||||
|
|
||||||
# Set up the result file path
|
|
||||||
result_file="/tmp/lldb_exit_code"
|
|
||||||
|
|
||||||
# Prepare LLDB commands
|
|
||||||
lldb_commands=(
|
|
||||||
"command script import _lldb/llgo_plugin.py"
|
|
||||||
"command script import _lldb/test.py"
|
|
||||||
"script test.run_tests_with_result('${package_path}/debug.out', ['${package_path}/in.go'], $verbose, $interactive, $plugin_path, '$result_file')"
|
|
||||||
"quit"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Run LLDB with prepared commands
|
|
||||||
lldb_command_string=""
|
|
||||||
for cmd in "${lldb_commands[@]}"; do
|
|
||||||
lldb_command_string+=" -o \"$cmd\""
|
|
||||||
done
|
|
||||||
|
|
||||||
|
|
||||||
# Run LLDB with the test script
|
|
||||||
eval "$LLDB_PATH $lldb_command_string"
|
|
||||||
|
|
||||||
# Read the exit code from the result file
|
|
||||||
if [ -f "$result_file" ]; then
|
|
||||||
exit_code=$(cat "$result_file")
|
|
||||||
rm "$result_file"
|
|
||||||
exit "$exit_code"
|
|
||||||
else
|
|
||||||
echo "Error: Could not find exit code file"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
402
_lldb/test.py
402
_lldb/test.py
@@ -1,402 +0,0 @@
|
|||||||
# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import argparse
|
|
||||||
import signal
|
|
||||||
from dataclasses import dataclass, field
|
|
||||||
from typing import List, Optional, Set, Dict, Any
|
|
||||||
import lldb
|
|
||||||
import llgo_plugin
|
|
||||||
from llgo_plugin import log
|
|
||||||
|
|
||||||
|
|
||||||
class LLDBTestException(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Test:
|
|
||||||
source_file: str
|
|
||||||
line_number: int
|
|
||||||
variable: str
|
|
||||||
expected_value: str
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class TestResult:
|
|
||||||
test: Test
|
|
||||||
status: str
|
|
||||||
actual: Optional[str] = None
|
|
||||||
message: Optional[str] = None
|
|
||||||
missing: Optional[Set[str]] = None
|
|
||||||
extra: Optional[Set[str]] = None
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class TestCase:
|
|
||||||
source_file: str
|
|
||||||
start_line: int
|
|
||||||
end_line: int
|
|
||||||
tests: List[Test]
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class CaseResult:
|
|
||||||
test_case: TestCase
|
|
||||||
function: str
|
|
||||||
results: List[TestResult]
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class TestResults:
|
|
||||||
total: int = 0
|
|
||||||
passed: int = 0
|
|
||||||
failed: int = 0
|
|
||||||
case_results: List[CaseResult] = field(default_factory=list)
|
|
||||||
|
|
||||||
|
|
||||||
class LLDBDebugger:
|
|
||||||
def __init__(self, executable_path: str, plugin_path: Optional[str] = None) -> None:
|
|
||||||
self.executable_path: str = executable_path
|
|
||||||
self.plugin_path: Optional[str] = plugin_path
|
|
||||||
self.debugger: lldb.SBDebugger = lldb.SBDebugger.Create()
|
|
||||||
self.debugger.SetAsync(False)
|
|
||||||
self.target: Optional[lldb.SBTarget] = None
|
|
||||||
self.process: Optional[lldb.SBProcess] = None
|
|
||||||
self.type_mapping: Dict[str, str] = {
|
|
||||||
'long': 'int',
|
|
||||||
'unsigned long': 'uint',
|
|
||||||
}
|
|
||||||
|
|
||||||
def setup(self) -> None:
|
|
||||||
if self.plugin_path:
|
|
||||||
self.debugger.HandleCommand(
|
|
||||||
f'command script import "{self.plugin_path}"')
|
|
||||||
self.target = self.debugger.CreateTarget(self.executable_path)
|
|
||||||
if not self.target:
|
|
||||||
raise LLDBTestException(
|
|
||||||
f"Failed to create target for {self.executable_path}")
|
|
||||||
|
|
||||||
self.debugger.HandleCommand(
|
|
||||||
'command script add -f llgo_plugin.print_go_expression p')
|
|
||||||
self.debugger.HandleCommand(
|
|
||||||
'command script add -f llgo_plugin.print_all_variables v')
|
|
||||||
|
|
||||||
def set_breakpoint(self, file_spec: str, line_number: int) -> lldb.SBBreakpoint:
|
|
||||||
bp = self.target.BreakpointCreateByLocation(file_spec, line_number)
|
|
||||||
if not bp.IsValid():
|
|
||||||
raise LLDBTestException(
|
|
||||||
f"Failed to set breakpoint at {file_spec}: {line_number}")
|
|
||||||
return bp
|
|
||||||
|
|
||||||
def run_to_breakpoint(self) -> None:
|
|
||||||
if not self.process:
|
|
||||||
self.process = self.target.LaunchSimple(None, None, os.getcwd())
|
|
||||||
else:
|
|
||||||
self.process.Continue()
|
|
||||||
if self.process.GetState() != lldb.eStateStopped:
|
|
||||||
raise LLDBTestException("Process didn't stop at breakpoint")
|
|
||||||
|
|
||||||
def get_variable_value(self, var_expression: str) -> Optional[str]:
|
|
||||||
frame = self.process.GetSelectedThread().GetFrameAtIndex(0)
|
|
||||||
value = llgo_plugin.evaluate_expression(frame, var_expression)
|
|
||||||
if value and value.IsValid():
|
|
||||||
return llgo_plugin.format_value(value, self.debugger)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_all_variable_names(self) -> Set[str]:
|
|
||||||
frame = self.process.GetSelectedThread().GetFrameAtIndex(0)
|
|
||||||
return set(var.GetName() for var in frame.GetVariables(True, True, True, True))
|
|
||||||
|
|
||||||
def get_current_function_name(self) -> str:
|
|
||||||
frame = self.process.GetSelectedThread().GetFrameAtIndex(0)
|
|
||||||
return frame.GetFunctionName()
|
|
||||||
|
|
||||||
def cleanup(self) -> None:
|
|
||||||
if self.process and self.process.IsValid():
|
|
||||||
self.process.Kill()
|
|
||||||
lldb.SBDebugger.Destroy(self.debugger)
|
|
||||||
|
|
||||||
def run_console(self) -> bool:
|
|
||||||
log("\nEntering LLDB interactive mode.")
|
|
||||||
log("Type 'quit' to exit and continue with the next test case.")
|
|
||||||
log("Use Ctrl+D to exit and continue, or Ctrl+C to abort all tests.")
|
|
||||||
|
|
||||||
old_stdin, old_stdout, old_stderr = sys.stdin, sys.stdout, sys.stderr
|
|
||||||
sys.stdin, sys.stdout, sys.stderr = sys.__stdin__, sys.__stdout__, sys.__stderr__
|
|
||||||
|
|
||||||
self.debugger.SetAsync(True)
|
|
||||||
self.debugger.HandleCommand("settings set auto-confirm true")
|
|
||||||
self.debugger.HandleCommand("command script import lldb")
|
|
||||||
|
|
||||||
interpreter = self.debugger.GetCommandInterpreter()
|
|
||||||
continue_tests = True
|
|
||||||
|
|
||||||
def keyboard_interrupt_handler(_sig: Any, _frame: Any) -> None:
|
|
||||||
nonlocal continue_tests
|
|
||||||
log("\nTest execution aborted by user.")
|
|
||||||
continue_tests = False
|
|
||||||
raise KeyboardInterrupt
|
|
||||||
|
|
||||||
original_handler = signal.signal(
|
|
||||||
signal.SIGINT, keyboard_interrupt_handler)
|
|
||||||
|
|
||||||
try:
|
|
||||||
while continue_tests:
|
|
||||||
log("\n(lldb) ", end="")
|
|
||||||
try:
|
|
||||||
command = input().strip()
|
|
||||||
except EOFError:
|
|
||||||
log("\nExiting LLDB interactive mode. Continuing with next test case.")
|
|
||||||
break
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
break
|
|
||||||
|
|
||||||
if command.lower() == 'quit':
|
|
||||||
log("\nExiting LLDB interactive mode. Continuing with next test case.")
|
|
||||||
break
|
|
||||||
|
|
||||||
result = lldb.SBCommandReturnObject()
|
|
||||||
interpreter.HandleCommand(command, result)
|
|
||||||
log(result.GetOutput().rstrip() if result.Succeeded()
|
|
||||||
else result.GetError().rstrip())
|
|
||||||
|
|
||||||
finally:
|
|
||||||
signal.signal(signal.SIGINT, original_handler)
|
|
||||||
sys.stdin, sys.stdout, sys.stderr = old_stdin, old_stdout, old_stderr
|
|
||||||
|
|
||||||
return continue_tests
|
|
||||||
|
|
||||||
|
|
||||||
def parse_expected_values(source_files: List[str]) -> List[TestCase]:
|
|
||||||
test_cases: List[TestCase] = []
|
|
||||||
for source_file in source_files:
|
|
||||||
with open(source_file, 'r', encoding='utf-8') as f:
|
|
||||||
content = f.readlines()
|
|
||||||
i = 0
|
|
||||||
while i < len(content):
|
|
||||||
line = content[i].strip()
|
|
||||||
if line.startswith('// Expected:'):
|
|
||||||
start_line = i + 1
|
|
||||||
tests: List[Test] = []
|
|
||||||
i += 1
|
|
||||||
while i < len(content):
|
|
||||||
line = content[i].strip()
|
|
||||||
if not line.startswith('//'):
|
|
||||||
break
|
|
||||||
parts = line.lstrip('//').strip().split(':', 1)
|
|
||||||
if len(parts) == 2:
|
|
||||||
var, value = map(str.strip, parts)
|
|
||||||
tests.append(Test(source_file, i + 1, var, value))
|
|
||||||
i += 1
|
|
||||||
end_line = i
|
|
||||||
test_cases.append(
|
|
||||||
TestCase(source_file, start_line, end_line, tests))
|
|
||||||
else:
|
|
||||||
i += 1
|
|
||||||
return test_cases
|
|
||||||
|
|
||||||
|
|
||||||
def execute_tests(executable_path: str, test_cases: List[TestCase], verbose: bool, interactive: bool, plugin_path: Optional[str]) -> TestResults:
|
|
||||||
results = TestResults()
|
|
||||||
|
|
||||||
for test_case in test_cases:
|
|
||||||
debugger = LLDBDebugger(executable_path, plugin_path)
|
|
||||||
try:
|
|
||||||
if verbose:
|
|
||||||
log(
|
|
||||||
f"\nSetting breakpoint at {test_case.source_file}:{test_case.end_line}")
|
|
||||||
debugger.setup()
|
|
||||||
debugger.set_breakpoint(test_case.source_file, test_case.end_line)
|
|
||||||
debugger.run_to_breakpoint()
|
|
||||||
|
|
||||||
all_variable_names = debugger.get_all_variable_names()
|
|
||||||
|
|
||||||
case_result = execute_test_case(
|
|
||||||
debugger, test_case, all_variable_names)
|
|
||||||
|
|
||||||
results.total += len(case_result.results)
|
|
||||||
results.passed += sum(1 for r in case_result.results if r.status == 'pass')
|
|
||||||
results.failed += sum(1 for r in case_result.results if r.status != 'pass')
|
|
||||||
results.case_results.append(case_result)
|
|
||||||
|
|
||||||
case = case_result.test_case
|
|
||||||
loc = f"{case.source_file}:{case.start_line}-{case.end_line}"
|
|
||||||
if verbose or interactive or any(r.status != 'pass' for r in case_result.results):
|
|
||||||
log(f"\nTest case: {loc} in function '{case_result.function}'")
|
|
||||||
for result in case_result.results:
|
|
||||||
print_test_result(result, verbose=verbose)
|
|
||||||
|
|
||||||
if interactive and any(r.status != 'pass' for r in case_result.results):
|
|
||||||
log("\nTest case failed. Entering LLDB interactive mode.")
|
|
||||||
continue_tests = debugger.run_console()
|
|
||||||
if not continue_tests:
|
|
||||||
log("Aborting all tests.")
|
|
||||||
break
|
|
||||||
|
|
||||||
finally:
|
|
||||||
debugger.cleanup()
|
|
||||||
|
|
||||||
return results
|
|
||||||
|
|
||||||
|
|
||||||
def run_tests(executable_path: str, source_files: List[str], verbose: bool, interactive: bool, plugin_path: Optional[str]) -> int:
|
|
||||||
test_cases = parse_expected_values(source_files)
|
|
||||||
if verbose:
|
|
||||||
log(f"Running tests for {', '.join(source_files)} with {executable_path}")
|
|
||||||
log(f"Found {len(test_cases)} test cases")
|
|
||||||
|
|
||||||
results = execute_tests(executable_path, test_cases,
|
|
||||||
verbose, interactive, plugin_path)
|
|
||||||
print_test_results(results)
|
|
||||||
|
|
||||||
# Return 0 if all tests passed, 1 otherwise
|
|
||||||
return 0 if results.failed == 0 else 1
|
|
||||||
|
|
||||||
|
|
||||||
def execute_test_case(debugger: LLDBDebugger, test_case: TestCase, all_variable_names: Set[str]) -> CaseResult:
|
|
||||||
results: List[TestResult] = []
|
|
||||||
|
|
||||||
for test in test_case.tests:
|
|
||||||
if test.variable == "all variables":
|
|
||||||
result = execute_all_variables_test(test, all_variable_names)
|
|
||||||
else:
|
|
||||||
result = execute_single_variable_test(debugger, test)
|
|
||||||
results.append(result)
|
|
||||||
|
|
||||||
return CaseResult(test_case, debugger.get_current_function_name(), results)
|
|
||||||
|
|
||||||
|
|
||||||
def execute_all_variables_test(test: Test, all_variable_names: Set[str]) -> TestResult:
|
|
||||||
expected_vars = set(test.expected_value.split())
|
|
||||||
if expected_vars == all_variable_names:
|
|
||||||
return TestResult(
|
|
||||||
test=test,
|
|
||||||
status='pass',
|
|
||||||
actual=all_variable_names
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return TestResult(
|
|
||||||
test=test,
|
|
||||||
status='fail',
|
|
||||||
actual=all_variable_names,
|
|
||||||
missing=expected_vars - all_variable_names,
|
|
||||||
extra=all_variable_names - expected_vars
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def execute_single_variable_test(debugger: LLDBDebugger, test: Test) -> TestResult:
|
|
||||||
actual_value = debugger.get_variable_value(test.variable)
|
|
||||||
if actual_value is None:
|
|
||||||
return TestResult(
|
|
||||||
test=test,
|
|
||||||
status='error',
|
|
||||||
message=f'Unable to fetch value for {test.variable}'
|
|
||||||
)
|
|
||||||
|
|
||||||
actual_value = actual_value.strip()
|
|
||||||
expected_value = test.expected_value.strip()
|
|
||||||
|
|
||||||
if actual_value == expected_value:
|
|
||||||
return TestResult(
|
|
||||||
test=test,
|
|
||||||
status='pass',
|
|
||||||
actual=actual_value
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return TestResult(
|
|
||||||
test=test,
|
|
||||||
status='fail',
|
|
||||||
actual=actual_value
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def print_test_results(results: TestResults) -> None:
|
|
||||||
log("\nTest results:")
|
|
||||||
log(f" Total tests: {results.total}")
|
|
||||||
log(f" Passed tests: {results.passed}")
|
|
||||||
log(f" Failed tests: {results.failed}")
|
|
||||||
if results.total == results.passed:
|
|
||||||
log("All tests passed!")
|
|
||||||
else:
|
|
||||||
log("Some tests failed")
|
|
||||||
|
|
||||||
|
|
||||||
def print_test_result(result: TestResult, verbose: bool) -> None:
|
|
||||||
status_symbol = "✓" if result.status == 'pass' else "✗"
|
|
||||||
status_text = "Pass" if result.status == 'pass' else "Fail"
|
|
||||||
test = result.test
|
|
||||||
|
|
||||||
if result.status == 'pass':
|
|
||||||
if verbose:
|
|
||||||
log(f"{status_symbol} Line {test.line_number}, {test.variable}: {status_text}")
|
|
||||||
if test.variable == 'all variables':
|
|
||||||
log(f" Variables: {', '.join(sorted(result.actual))}")
|
|
||||||
else: # fail or error
|
|
||||||
log(f"{status_symbol} Line {test.line_number}, {test.variable}: {status_text}")
|
|
||||||
if test.variable == 'all variables':
|
|
||||||
if result.missing:
|
|
||||||
log(f" Missing variables: {', '.join(sorted(result.missing))}")
|
|
||||||
if result.extra:
|
|
||||||
log(f" Extra variables: {', '.join(sorted(result.extra))}")
|
|
||||||
log(f" Expected: {', '.join(sorted(test.expected_value.split()))}")
|
|
||||||
log(f" Actual: {', '.join(sorted(result.actual))}")
|
|
||||||
elif result.status == 'error':
|
|
||||||
log(f" Error: {result.message}")
|
|
||||||
else:
|
|
||||||
log(f" Expected: {test.expected_value}")
|
|
||||||
log(f" Actual: {result.actual}")
|
|
||||||
|
|
||||||
|
|
||||||
def run_tests_with_result(executable_path: str, source_files: List[str], verbose: bool, interactive: bool, plugin_path: Optional[str], result_path: str) -> int:
|
|
||||||
try:
|
|
||||||
exit_code = run_tests(executable_path, source_files,
|
|
||||||
verbose, interactive, plugin_path)
|
|
||||||
except Exception as e:
|
|
||||||
log(f"An error occurred during test execution: {str(e)}")
|
|
||||||
exit_code = 2 # Use a different exit code for unexpected errors
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(result_path, 'w', encoding='utf-8') as f:
|
|
||||||
f.write(str(exit_code))
|
|
||||||
except IOError as e:
|
|
||||||
log(f"Error writing result to file {result_path}: {str(e)}")
|
|
||||||
# If we can't write to the file, we should still return the exit code
|
|
||||||
|
|
||||||
return exit_code
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
|
||||||
log(sys.argv)
|
|
||||||
parser = argparse.ArgumentParser(
|
|
||||||
description="LLDB 18 Debug Script with DWARF 5 Support")
|
|
||||||
parser.add_argument("executable", help="Path to the executable")
|
|
||||||
parser.add_argument("sources", nargs='+', help="Paths to the source files")
|
|
||||||
parser.add_argument("-v", "--verbose", action="store_true",
|
|
||||||
help="Enable verbose output")
|
|
||||||
parser.add_argument("-i", "--interactive", action="store_true",
|
|
||||||
help="Enable interactive mode on test failure")
|
|
||||||
parser.add_argument("--plugin", help="Path to the LLDB plugin")
|
|
||||||
parser.add_argument("--result-path", help="Path to write the result")
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
plugin_path = args.plugin or os.path.join(os.path.dirname(
|
|
||||||
os.path.realpath(__file__)), "go_lldb_plugin.py")
|
|
||||||
|
|
||||||
try:
|
|
||||||
if args.result_path:
|
|
||||||
exit_code = run_tests_with_result(args.executable, args.sources,
|
|
||||||
args.verbose, args.interactive, plugin_path, args.result_path)
|
|
||||||
else:
|
|
||||||
exit_code = run_tests(args.executable, args.sources,
|
|
||||||
args.verbose, args.interactive, plugin_path)
|
|
||||||
except Exception as e:
|
|
||||||
log(f"An unexpected error occurred: {str(e)}")
|
|
||||||
exit_code = 2 # Use a different exit code for unexpected errors
|
|
||||||
|
|
||||||
sys.exit(exit_code)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
35
c/c.go
35
c/c.go
@@ -33,13 +33,9 @@ type (
|
|||||||
Float = float32
|
Float = float32
|
||||||
Double = float64
|
Double = float64
|
||||||
Pointer = unsafe.Pointer
|
Pointer = unsafe.Pointer
|
||||||
FilePtr = *FILE
|
FilePtr = unsafe.Pointer
|
||||||
)
|
)
|
||||||
|
|
||||||
type FILE struct {
|
|
||||||
Unused [8]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type (
|
type (
|
||||||
Int C.int
|
Int C.int
|
||||||
Uint C.uint
|
Uint C.uint
|
||||||
@@ -55,23 +51,6 @@ type integer interface {
|
|||||||
~int | ~uint | ~uintptr | ~int32 | ~uint32 | ~int64 | ~uint64
|
~int | ~uint | ~uintptr | ~int32 | ~uint32 | ~int64 | ~uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
type SizeT = uintptr
|
|
||||||
|
|
||||||
type IntptrT = uintptr
|
|
||||||
type UintptrT = uintptr
|
|
||||||
type Int8T = int8
|
|
||||||
type Int16T = int16
|
|
||||||
type Int32T = int32
|
|
||||||
type Int64T = int64
|
|
||||||
|
|
||||||
type Uint8T = uint8
|
|
||||||
type Uint16T = uint16
|
|
||||||
type Uint32T = uint32
|
|
||||||
type Uint64T = uint64
|
|
||||||
|
|
||||||
type IntmaxT = LongLong
|
|
||||||
type UintmaxT = UlongLong
|
|
||||||
|
|
||||||
//go:linkname Str llgo.cstr
|
//go:linkname Str llgo.cstr
|
||||||
func Str(string) *Char
|
func Str(string) *Char
|
||||||
|
|
||||||
@@ -100,15 +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)
|
||||||
|
|
||||||
//go:linkname Realloc C.realloc
|
|
||||||
func Realloc(ptr Pointer, size uintptr) Pointer
|
|
||||||
|
|
||||||
//go:linkname Memcpy C.memcpy
|
//go:linkname Memcpy C.memcpy
|
||||||
func Memcpy(dst, src Pointer, n uintptr) Pointer
|
func Memcpy(dst, src Pointer, n uintptr) Pointer
|
||||||
|
|
||||||
@@ -240,9 +213,6 @@ func Fputc(c Int, fp FilePtr) Int
|
|||||||
//go:linkname Fputs C.fputs
|
//go:linkname Fputs C.fputs
|
||||||
func Fputs(s *Char, fp FilePtr) Int
|
func Fputs(s *Char, fp FilePtr) Int
|
||||||
|
|
||||||
//go:linkname Fread C.fread
|
|
||||||
func Fread(data Pointer, size, count uintptr, fp FilePtr) uintptr
|
|
||||||
|
|
||||||
//go:linkname Fflush C.fflush
|
//go:linkname Fflush C.fflush
|
||||||
func Fflush(fp FilePtr) Int
|
func Fflush(fp FilePtr) Int
|
||||||
|
|
||||||
@@ -297,6 +267,3 @@ func GetoptLong(argc Int, argv **Char, optstring *Char, longopts *Option, longin
|
|||||||
func GetoptLongOnly(argc Int, argv **Char, optstring *Char, longopts *Option, longindex *Int) Int
|
func GetoptLongOnly(argc Int, argv **Char, optstring *Char, longopts *Option, longindex *Int) Int
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
//go:linkname Sysconf C.sysconf
|
|
||||||
func Sysconf(name Int) Long
|
|
||||||
|
|||||||
673
c/cjson/cjson.go
673
c/cjson/cjson.go
@@ -26,25 +26,87 @@ const (
|
|||||||
LLGoPackage = "link: $(pkg-config --libs libcjson); -lcjson"
|
LLGoPackage = "link: $(pkg-config --libs libcjson); -lcjson"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Bool c.Int
|
|
||||||
|
|
||||||
// llgo:type C
|
// llgo:type C
|
||||||
type JSON struct {
|
type JSON struct {
|
||||||
Unused [0]byte
|
Unused [0]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:linkname Parse C.cJSON_Parse
|
||||||
|
func Parse(value *c.Char) *JSON
|
||||||
|
|
||||||
|
//go:linkname ParseWithLength C.cJSON_ParseWithLength
|
||||||
|
func ParseWithLength(value *byte, valueLength uintptr) *JSON
|
||||||
|
|
||||||
func ParseBytes(value []byte) *JSON {
|
func ParseBytes(value []byte) *JSON {
|
||||||
return ParseWithLength((*c.Char)(unsafe.Pointer(unsafe.SliceData(value))), uintptr(len(value)))
|
return ParseWithLength(unsafe.SliceData(value), uintptr(len(value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseString(value string) *JSON {
|
func ParseString(value string) *JSON {
|
||||||
return ParseWithLength((*c.Char)(unsafe.Pointer(unsafe.StringData(value))), uintptr(len(value)))
|
return ParseWithLength(unsafe.StringData(value), uintptr(len(value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
//go:linkname Null C.cJSON_CreateNull
|
||||||
|
func Null() *JSON
|
||||||
|
|
||||||
|
//go:linkname True C.cJSON_CreateTrue
|
||||||
|
func True() *JSON
|
||||||
|
|
||||||
|
//go:linkname False C.cJSON_CreateFalse
|
||||||
|
func False() *JSON
|
||||||
|
|
||||||
|
//go:linkname Bool C.cJSON_CreateBool
|
||||||
|
func Bool(boolean c.Int) *JSON
|
||||||
|
|
||||||
|
//go:linkname Number C.cJSON_CreateNumber
|
||||||
|
func Number(num float64) *JSON
|
||||||
|
|
||||||
|
//go:linkname String C.cJSON_CreateString
|
||||||
|
func String(str *c.Char) *JSON
|
||||||
|
|
||||||
|
//go:linkname Array C.cJSON_CreateArray
|
||||||
|
func Array() *JSON
|
||||||
|
|
||||||
|
//go:linkname Object C.cJSON_CreateObject
|
||||||
|
func Object() *JSON
|
||||||
|
|
||||||
|
// raw json
|
||||||
//
|
//
|
||||||
// Render a cJSON entity to text for transfer/storage without any formatting.
|
//go:linkname Raw C.cJSON_CreateRaw
|
||||||
|
func Raw(raw *c.Char) *JSON
|
||||||
|
|
||||||
|
// Create a string where valuestring references a string so
|
||||||
|
// it will not be freed by Delete
|
||||||
//
|
//
|
||||||
|
//go:linkname StringRef C.cJSON_CreateStringReference
|
||||||
|
func StringRef(str *c.Char) *JSON
|
||||||
|
|
||||||
|
// Create an object that only references it's elements so
|
||||||
|
// they will not be freed by Delete
|
||||||
|
//
|
||||||
|
//go:linkname ObjectRef C.cJSON_CreateObjectReference
|
||||||
|
func ObjectRef(child *JSON) *JSON
|
||||||
|
|
||||||
|
// Create an array that only references it's elements so
|
||||||
|
// they will not be freed by Delete
|
||||||
|
//
|
||||||
|
//go:linkname ArrayRef C.cJSON_CreateArrayReference
|
||||||
|
func ArrayRef(child *JSON) *JSON
|
||||||
|
|
||||||
|
// Delete a JSON entity and all subentities.
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).Delete C.cJSON_Delete
|
||||||
|
func (o *JSON) Delete() {}
|
||||||
|
|
||||||
|
// Append item to the specified array.
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).AddItem C.cJSON_AddItemToArray
|
||||||
|
func (o *JSON) AddItem(item *JSON) c.Int { return 0 }
|
||||||
|
|
||||||
|
// Append item to the specified object.
|
||||||
|
//
|
||||||
|
// llgo:link (*JSON).SetItem C.cJSON_AddItemToObject
|
||||||
|
func (o *JSON) SetItem(key *c.Char, item *JSON) c.Int { return 0 }
|
||||||
|
|
||||||
// llgo:link (*JSON).CStr C.cJSON_PrintUnformatted
|
// llgo:link (*JSON).CStr C.cJSON_PrintUnformatted
|
||||||
func (o *JSON) CStr() *c.Char { return nil }
|
func (o *JSON) CStr() *c.Char { return nil }
|
||||||
|
|
||||||
@@ -53,618 +115,39 @@ func (o *JSON) CStr() *c.Char { return nil }
|
|||||||
// llgo:link (*JSON).Cstr C.cJSON_PrintUnformatted
|
// llgo:link (*JSON).Cstr C.cJSON_PrintUnformatted
|
||||||
func (o *JSON) Cstr() *c.Char { return nil }
|
func (o *JSON) Cstr() *c.Char { return nil }
|
||||||
|
|
||||||
// malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks
|
|
||||||
//
|
|
||||||
//go:linkname FreeCStr C.cJSON_free
|
|
||||||
func FreeCStr(*c.Char)
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(const char*) cJSON_Version(void);
|
|
||||||
//
|
|
||||||
// returns the version of cJSON as a string
|
|
||||||
//
|
|
||||||
//go:linkname Version C.cJSON_Version
|
|
||||||
func Version() *c.Char
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
|
||||||
//
|
|
||||||
// Memory Management: the caller is always responsible to free
|
|
||||||
// the results from all variants of cJSON_Parse (with cJSON_Delete)
|
|
||||||
// and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or
|
|
||||||
// cJSON_free as appropriate). The exception is cJSON_PrintPreallocated,
|
|
||||||
// where the caller has full responsibility of the buffer.
|
|
||||||
//
|
|
||||||
//go:linkname Parse C.cJSON_Parse
|
|
||||||
func Parse(value *c.Char) *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
|
|
||||||
//
|
|
||||||
// Memory Management: the caller is always responsible to free
|
|
||||||
// the results from all variants of cJSON_Parse (with cJSON_Delete)
|
|
||||||
// and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or
|
|
||||||
// cJSON_free as appropriate). The exception is cJSON_PrintPreallocated,
|
|
||||||
// where the caller has full responsibility of the buffer.
|
|
||||||
//
|
|
||||||
//go:linkname ParseWithLength C.cJSON_ParseWithLength
|
|
||||||
func ParseWithLength(value *c.Char, valueLength uintptr) *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_Bool require_null_terminated);
|
|
||||||
//
|
|
||||||
// ParseWithOpts allows you to require (and check) that the JSON is null terminated,
|
|
||||||
// and to retrieve the pointer to the final byte parsed.
|
|
||||||
// If you supply a ptr in return_parse_end and parsing fails, then
|
|
||||||
// return_parse_end will contain a pointer to the error so will match
|
|
||||||
// cJSON_GetErrorPtr().
|
|
||||||
//
|
|
||||||
//go:linkname ParseWithOpts C.cJSON_ParseWithOpts
|
|
||||||
func ParseWithOpts(value *c.Char, return_parse_end **c.Char, require_null_terminated Bool) *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_Bool require_null_terminated);
|
|
||||||
//
|
|
||||||
// ParseWithOpts allows you to require (and check) that the JSON is null terminated,
|
|
||||||
// and to retrieve the pointer to the final byte parsed.
|
|
||||||
// If you supply a ptr in return_parse_end and parsing fails, then
|
|
||||||
// return_parse_end will contain a pointer to the error so will match
|
|
||||||
// cJSON_GetErrorPtr().
|
|
||||||
//
|
|
||||||
//go:linkname ParseWithLengthOpts C.cJSON_ParseWithLengthOpts
|
|
||||||
func ParseWithLengthOpts(value *c.Char, buffer_length uintptr, return_parse_end **c.Char, require_null_terminated Bool) *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
|
||||||
// Render a JSON entity to text for transfer/storage.
|
// Render a JSON entity to text for transfer/storage.
|
||||||
//
|
//
|
||||||
// llgo:link (*JSON).Print C.cJSON_Print
|
// llgo:link (*JSON).Print C.cJSON_Print
|
||||||
func (o *JSON) Print() *c.Char { return nil }
|
func (o *JSON) Print() *c.Char { return nil }
|
||||||
|
|
||||||
// CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
|
||||||
// Render a JSON entity to text for transfer/storage without any formatting.
|
// Render a JSON entity to text for transfer/storage without any formatting.
|
||||||
//
|
//
|
||||||
// llgo:link (*JSON).PrintUnformatted C.cJSON_PrintUnformatted
|
// llgo:link (*JSON).PrintUnformatted C.cJSON_PrintUnformatted
|
||||||
func (o *JSON) PrintUnformatted() *c.Char { return nil }
|
func (o *JSON) PrintUnformatted() *c.Char { return nil }
|
||||||
|
|
||||||
// CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_Bool fmt);
|
|
||||||
//
|
|
||||||
// Render a JSON entity to text using a buffered strategy.
|
// Render a JSON entity to text using a buffered strategy.
|
||||||
|
//
|
||||||
// prebuffer is a guess at the final size. guessing well reduces reallocation.
|
// prebuffer is a guess at the final size. guessing well reduces reallocation.
|
||||||
|
//
|
||||||
// fmt=0 gives unformatted, =1 gives formatted.
|
// fmt=0 gives unformatted, =1 gives formatted.
|
||||||
//
|
//
|
||||||
// llgo:link (*JSON).PrintBuffered C.cJSON_PrintBuffered
|
// llgo:link (*JSON).PrintBuffered C.cJSON_PrintBuffered
|
||||||
func (o *JSON) PrintBuffered(prebuffer c.Int, fmt Bool) *c.Char { return nil }
|
func (o *JSON) PrintBuffered(prebuffer c.Int, fmt c.Int) *c.Char { return nil }
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_Bool format);
|
|
||||||
//
|
|
||||||
// Render a cJSON entity to text using a buffer already allocated in memory with given
|
|
||||||
// length. Returns 1 on success and 0 on failure.
|
|
||||||
// note that cJSON is not always 100% accurate in estimating how much memory it will use,
|
|
||||||
// so to be safe allocate 5 bytes more than you actually need
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).PrintPreallocated C.cJSON_PrintPreallocated
|
|
||||||
func (o *JSON) PrintPreallocated(buffer *c.Char, length c.Int, format Bool) Bool {
|
|
||||||
return Bool(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
|
|
||||||
// Delete a JSON entity and all subentities.
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).Delete C.cJSON_Delete
|
|
||||||
func (o *JSON) Delete() {}
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
|
||||||
//
|
|
||||||
// Returns the number of items in an array (or object).
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).GetArraySize C.cJSON_GetArraySize
|
|
||||||
func (o *JSON) GetArraySize() c.Int { return 0 }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
|
||||||
//
|
|
||||||
// Retrieve item number "index" from array "array". Returns NULL if unsuccessful.
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).GetArrayItem C.cJSON_GetArrayItem
|
|
||||||
func (o *JSON) GetArrayItem(index c.Int) *JSON { return nil }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
|
||||||
//
|
|
||||||
// Get item "string" from object. Case insensitive.
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).GetObjectItem C.cJSON_GetObjectItem
|
|
||||||
func (o *JSON) GetObjectItem(s *c.Char) *JSON { return nil }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
|
|
||||||
//
|
|
||||||
// Get item "string" from object. Case sensitive.
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).GetObjectItemCaseSensitive C.cJSON_GetObjectItemCaseSensitive
|
// llgo:link (*JSON).GetObjectItemCaseSensitive C.cJSON_GetObjectItemCaseSensitive
|
||||||
func (o *JSON) GetObjectItemCaseSensitive(key *c.Char) *JSON { return nil }
|
func (o *JSON) GetObjectItemCaseSensitive(key *c.Char) *JSON { return nil }
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
|
// llgo:link (*JSON).GetArraySize C.cJSON_GetArraySize
|
||||||
//
|
func (o *JSON) GetArraySize() c.Int { return 0 }
|
||||||
// llgo:link (*JSON).HasObjectItem C.cJSON_HasObjectItem
|
|
||||||
func (o *JSON) HasObjectItem(s *c.Char) Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
// llgo:link (*JSON).GetArrayItem C.cJSON_GetArrayItem
|
||||||
//
|
func (o *JSON) GetArrayItem(index c.Int) *JSON { return nil }
|
||||||
// For analysing failed parses. This returns a pointer to the parse error.
|
|
||||||
// You'll probably need to look a few chars back to make sense of it.
|
|
||||||
// Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds.
|
|
||||||
//
|
|
||||||
//go:linkname GetErrorPtr C.cJSON_GetErrorPtr
|
|
||||||
func GetErrorPtr() *c.Char
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
|
|
||||||
//
|
|
||||||
// Check item type and return its value
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).GetStringValue C.cJSON_GetStringValue
|
// llgo:link (*JSON).GetStringValue C.cJSON_GetStringValue
|
||||||
func (o *JSON) GetStringValue() *c.Char { return nil }
|
func (o *JSON) GetStringValue() *c.Char { return nil }
|
||||||
|
|
||||||
// CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item);
|
|
||||||
//
|
|
||||||
// Check item type and return its value
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).GetNumberValue C.cJSON_GetNumberValue
|
|
||||||
func (o *JSON) GetNumberValue() c.Double { return 0 }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsInvalid(const cJSON * const item);
|
|
||||||
//
|
|
||||||
// These functions check the type of an item
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).IsInvalid C.cJSON_IsInvalid
|
|
||||||
func (o *JSON) IsInvalid() Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsFalse(const cJSON * const item);
|
|
||||||
//
|
|
||||||
// These functions check the type of an item
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).IsFalse C.cJSON_IsFalse
|
|
||||||
func (o *JSON) IsFalse() Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsTrue(const cJSON * const item);
|
|
||||||
//
|
|
||||||
// These functions check the type of an item
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).IsTrue C.cJSON_IsTrue
|
|
||||||
func (o *JSON) IsTrue() Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsBool(const cJSON * const item);
|
|
||||||
//
|
|
||||||
// These functions check the type of an item
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).IsBool C.cJSON_IsBool
|
|
||||||
func (o *JSON) IsBool() Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsNull(const cJSON * const item);
|
|
||||||
//
|
|
||||||
// These functions check the type of an item
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).IsNull C.cJSON_IsNull
|
|
||||||
func (o *JSON) IsNull() Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsNumber(const cJSON * const item);
|
|
||||||
//
|
|
||||||
// These functions check the type of an item
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).IsNumber C.cJSON_IsNumber
|
|
||||||
func (o *JSON) IsNumber() Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsString(const cJSON * const item);
|
|
||||||
//
|
|
||||||
// These functions check the type of an item
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).IsString C.cJSON_IsString
|
|
||||||
func (o *JSON) IsString() Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsArray(const cJSON * const item);
|
|
||||||
//
|
|
||||||
// These functions check the type of an item
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).IsArray C.cJSON_IsArray
|
|
||||||
func (o *JSON) IsArray() Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsObject(const cJSON * const item);
|
|
||||||
//
|
|
||||||
// These functions check the type of an item
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).IsObject C.cJSON_IsObject
|
|
||||||
func (o *JSON) IsObject() Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_IsRaw(const cJSON * const item);
|
|
||||||
//
|
|
||||||
// These functions check the type of an item
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).IsRaw C.cJSON_IsRaw
|
|
||||||
func (o *JSON) IsRaw() Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
|
||||||
//
|
|
||||||
// These calls create a cJSON item of the appropriate type.
|
|
||||||
//
|
|
||||||
//go:linkname Null C.cJSON_CreateNull
|
|
||||||
func Null() *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
|
||||||
//
|
|
||||||
// same as Null func
|
|
||||||
//
|
|
||||||
//go:linkname CreateNull C.cJSON_CreateNull
|
|
||||||
func CreateNull() *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
|
||||||
//
|
|
||||||
//go:linkname True C.cJSON_CreateTrue
|
|
||||||
func True() *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
|
||||||
//
|
|
||||||
// same as True func
|
|
||||||
//
|
|
||||||
//go:linkname CreateTrue C.cJSON_CreateTrue
|
|
||||||
func CreateTrue() *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
|
||||||
//
|
|
||||||
//go:linkname False C.cJSON_CreateFalse
|
|
||||||
func False() *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
|
||||||
//
|
|
||||||
// same as False func
|
|
||||||
//
|
|
||||||
//go:linkname CreateFalse C.cJSON_CreateFalse
|
|
||||||
func CreateFalse() *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_Bool boolean);
|
|
||||||
//
|
|
||||||
// same as Bool func
|
|
||||||
//
|
|
||||||
//go:linkname CreateBool C.cJSON_CreateBool
|
|
||||||
func CreateBool(boolean c.Int) *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
|
||||||
//
|
|
||||||
//go:linkname Number C.cJSON_CreateNumber
|
|
||||||
func Number(num float64) *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
|
||||||
//
|
|
||||||
// same as Number func
|
|
||||||
//
|
|
||||||
//go:linkname CreateNumber C.cJSON_CreateNumber
|
|
||||||
func CreateNumber(num float64) *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
|
||||||
//
|
|
||||||
//go:linkname String C.cJSON_CreateString
|
|
||||||
func String(str *c.Char) *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
|
||||||
//
|
|
||||||
// same as String func
|
|
||||||
//
|
|
||||||
//go:linkname CreateString C.cJSON_CreateString
|
|
||||||
func CreateString(str *c.Char) *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
|
||||||
// raw json
|
|
||||||
//
|
|
||||||
//go:linkname Raw C.cJSON_CreateRaw
|
|
||||||
func Raw(raw *c.Char) *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
|
||||||
//
|
|
||||||
// same as Raw func
|
|
||||||
//
|
|
||||||
//go:linkname CreateRaw C.cJSON_CreateRaw
|
|
||||||
func CreateRaw(raw *c.Char) *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
|
||||||
//
|
|
||||||
//go:linkname Array C.cJSON_CreateArray
|
|
||||||
func Array() *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
|
||||||
//
|
|
||||||
// same as Array func
|
|
||||||
//
|
|
||||||
//go:linkname CreateArray C.cJSON_CreateArray
|
|
||||||
func CreateArray() *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
|
||||||
//
|
|
||||||
//go:linkname Object C.cJSON_CreateObject
|
|
||||||
func Object() *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
|
||||||
//
|
|
||||||
// same as Object func
|
|
||||||
//
|
|
||||||
//go:linkname CreateObject C.cJSON_CreateObject
|
|
||||||
func CreateObject() *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
|
||||||
//
|
|
||||||
// Create a string where valuestring references a string so
|
|
||||||
// it will not be freed by Delete
|
|
||||||
//
|
|
||||||
//go:linkname StringRef C.cJSON_CreateStringReference
|
|
||||||
func StringRef(str *c.Char) *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
|
||||||
//
|
|
||||||
// same as StringRef func
|
|
||||||
//
|
|
||||||
//go:linkname CreateStringReference C.cJSON_CreateStringReference
|
|
||||||
func CreateStringReference(str *c.Char) *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
|
||||||
//
|
|
||||||
// Create an object that only references it's elements so
|
|
||||||
// they will not be freed by Delete
|
|
||||||
//
|
|
||||||
//go:linkname ObjectRef C.cJSON_CreateObjectReference
|
|
||||||
func ObjectRef(child *JSON) *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
|
||||||
//
|
|
||||||
// same as ObjectRef func
|
|
||||||
//
|
|
||||||
//go:linkname CreateObjectReference C.cJSON_CreateObjectReference
|
|
||||||
func CreateObjectReference(child *JSON) *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
|
||||||
//
|
|
||||||
// Create an array that only references it's elements so
|
|
||||||
// they will not be freed by Delete
|
|
||||||
//
|
|
||||||
//go:linkname ArrayRef C.cJSON_CreateArrayReference
|
|
||||||
func ArrayRef(child *JSON) *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
|
||||||
//
|
|
||||||
// same as ArrayRef func
|
|
||||||
//
|
|
||||||
//go:linkname CreateArrayReference C.cJSON_CreateArrayReference
|
|
||||||
func CreateArrayReference(child *JSON) *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
|
||||||
//
|
|
||||||
//go:linkname CreateIntArray C.cJSON_CreateIntArray
|
|
||||||
func CreateIntArray(numbers *c.Int, count c.Int) *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
|
||||||
//
|
|
||||||
//go:linkname CreateFloatArray C.cJSON_CreateFloatArray
|
|
||||||
func CreateFloatArray(numbers *c.Float, count c.Int) *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
|
||||||
//
|
|
||||||
//go:linkname CreateDoubleArray C.cJSON_CreateDoubleArray
|
|
||||||
func CreateDoubleArray(numbers *c.Double, count c.Int) *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);
|
|
||||||
//
|
|
||||||
//go:linkname CreateStringArray C.cJSON_CreateStringArray
|
|
||||||
func CreateStringArray(strings *c.Char, count c.Int) *JSON
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
|
||||||
//
|
|
||||||
// Append item to the specified array.
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).AddItem C.cJSON_AddItemToArray
|
|
||||||
func (o *JSON) AddItem(item *JSON) Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
|
||||||
//
|
|
||||||
// same as AddItem func
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).AddItemToArray C.cJSON_AddItemToArray
|
|
||||||
func (o *JSON) AddItemToArray(item *JSON) Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
|
||||||
//
|
|
||||||
// Append item to the specified object.
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).SetItem C.cJSON_AddItemToObject
|
|
||||||
func (o *JSON) SetItem(key *c.Char, item *JSON) Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
|
||||||
//
|
|
||||||
// same as SetItem func
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).AddItemToObject C.cJSON_AddItemToObject
|
|
||||||
func (o *JSON) AddItemToObject(key *c.Char, item *JSON) Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
|
||||||
//
|
|
||||||
// Use this when string is definitely const (i.e. a literal, or as good as),
|
|
||||||
// and will definitely survive the cJSON object.
|
|
||||||
// warning that When this function was used, make sure to always check that
|
|
||||||
// (item->type & cJSON_StringIsConst) is zero before writing to `item->string`
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).AddItemToObjectCS C.cJSON_AddItemToObjectCS
|
|
||||||
func (o *JSON) AddItemToObjectCS(s *c.Char, item *JSON) Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
|
||||||
//
|
|
||||||
// Append reference to item to the specified array/object.
|
|
||||||
// Use this when you want to add an existing cJSON to a new cJSON,
|
|
||||||
// but don't want to corrupt your existing cJSON.
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).AddItemReferenceToArray C.cJSON_AddItemReferenceToArray
|
|
||||||
func (o *JSON) AddItemReferenceToArray(item *JSON) Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).AddItemReferenceToObject C.cJSON_AddItemReferenceToObject
|
|
||||||
func (o *JSON) AddItemReferenceToObject(s *c.Char, item *JSON) Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
|
|
||||||
//
|
|
||||||
// Remove/Detach items from Arrays/Objects.
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).DetachItemViaPointer C.cJSON_DetachItemViaPointer
|
|
||||||
func (o *JSON) DetachItemViaPointer(item *JSON) *JSON { return nil }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).DetachItemFromArray C.cJSON_DetachItemFromArray
|
|
||||||
func (o *JSON) DetachItemFromArray(which c.Int) *JSON { return nil }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).DeleteItemFromArray C.cJSON_DeleteItemFromArray
|
|
||||||
func (o *JSON) DeleteItemFromArray(which c.Int) {}
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).DetachItemFromObject C.cJSON_DetachItemFromObject
|
|
||||||
func (o *JSON) DetachItemFromObject(s *c.Char) *JSON { return nil }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).DetachItemFromObjectCaseSensitive C.cJSON_DetachItemFromObjectCaseSensitive
|
|
||||||
func (o *JSON) DetachItemFromObjectCaseSensitive(s *c.Char) *JSON { return nil }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).DeleteItemFromObject C.cJSON_DeleteItemFromObject
|
|
||||||
func (o *JSON) DeleteItemFromObject(s *c.Char) {}
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).DeleteItemFromObjectCaseSensitive C.cJSON_DeleteItemFromObjectCaseSensitive
|
|
||||||
func (o *JSON) DeleteItemFromObjectCaseSensitive(s *c.Char) {}
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem);
|
|
||||||
//
|
|
||||||
// Update array items.
|
|
||||||
// Shifts pre-existing items to the right.
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).InsertItemInArray C.cJSON_InsertItemInArray
|
|
||||||
func (o *JSON) InsertItemInArray(which c.Int, newitem *JSON) Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).ReplaceItemViaPointer C.cJSON_ReplaceItemViaPointer
|
|
||||||
func (o *JSON) ReplaceItemViaPointer(item *JSON, replacement *JSON) Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).ReplaceItemInArray C.cJSON_ReplaceItemInArray
|
|
||||||
func (o *JSON) ReplaceItemInArray(which c.Int, newitem *JSON) Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).ReplaceItemInObject C.cJSON_ReplaceItemInObject
|
|
||||||
func (o *JSON) ReplaceItemInObject(s *c.Char, newitem *JSON) Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).ReplaceItemInObjectCaseSensitive C.cJSON_ReplaceItemInObjectCaseSensitive
|
|
||||||
func (o *JSON) ReplaceItemInObjectCaseSensitive(s *c.Char, newitem *JSON) Bool {
|
|
||||||
return Bool(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_Bool recurse);
|
|
||||||
//
|
|
||||||
// Duplicate a cJSON item
|
|
||||||
//
|
|
||||||
// Duplicate will create a new, identical cJSON item to the one you pass,
|
|
||||||
// in new memory that will need to be released. With recurse!=0,
|
|
||||||
// it will duplicate any children connected to the item.
|
|
||||||
// The item->next and ->prev pointers are always zero on return from Duplicate.
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).Duplicate C.cJSON_Duplicate
|
|
||||||
func (o *JSON) Duplicate(recurse Bool) *JSON { return nil }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON_Bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_Bool case_sensitive);
|
|
||||||
//
|
|
||||||
// Recursively compare two cJSON items for equality. If either a or b is NULL or invalid,
|
|
||||||
// they will be considered unequal. case_sensitive determines if object keys are treated
|
|
||||||
// case sensitive (1) or case insensitive (0)
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).Compare C.cJSON_Compare
|
|
||||||
func (o *JSON) Compare(b *JSON, case_sensitive Bool) Bool { return Bool(0) }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
|
||||||
//
|
|
||||||
// Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
|
|
||||||
// The input pointer json cannot point to a read-only address area, such as a string constant,
|
|
||||||
// but should point to a readable and writable address area.
|
|
||||||
//
|
|
||||||
//go:linkname Minify C.cJSON_Minify
|
|
||||||
func Minify()
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
|
|
||||||
//
|
|
||||||
// Helper functions for creating and adding items to an object at the same time.
|
|
||||||
// They return the added item or NULL on failure.
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).AddNullToObject C.cJSON_AddNullToObject
|
|
||||||
func (o *JSON) AddNullToObject(name *c.Char) *JSON { return nil }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).AddTrueToObject C.cJSON_AddTrueToObject
|
|
||||||
func (o *JSON) AddTrueToObject(name *c.Char) *JSON { return nil }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).AddFalseToObject C.cJSON_AddFalseToObject
|
|
||||||
func (o *JSON) AddFalseToObject(name *c.Char) *JSON { return nil }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_Bool boolean);
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).AddBoolToObject C.cJSON_AddBoolToObject
|
|
||||||
func (o *JSON) AddBoolToObject(name *c.Char, b Bool) *JSON { return nil }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).AddNumberToObject C.cJSON_AddNumberToObject
|
|
||||||
func (o *JSON) AddNumberToObject(name *c.Char, num c.Double) *JSON { return nil }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).AddStringToObject C.cJSON_AddStringToObject
|
|
||||||
func (o *JSON) AddStringToObject(name *c.Char, s *c.Char) *JSON { return nil }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).AddRawToObject C.cJSON_AddRawToObject
|
|
||||||
func (o *JSON) AddRawToObject(name *c.Char, raw *c.Char) *JSON { return nil }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).AddObjectToObject C.cJSON_AddObjectToObject
|
|
||||||
func (o *JSON) AddObjectToObject(name *c.Char) *JSON { return nil }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).AddArrayToObject C.cJSON_AddArrayToObject
|
|
||||||
func (o *JSON) AddArrayToObject(name *c.Char) *JSON { return nil }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
|
||||||
//
|
|
||||||
// helper for the cJSON_SetNumberValue macro
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).SetNumberHelper C.cJSON_SetNumberHelper
|
|
||||||
func (o *JSON) SetNumberHelper(number c.Double) c.Double { return 0 }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
|
|
||||||
//
|
|
||||||
// Change the valuestring of a cJSON_String object, only takes effect when type of
|
|
||||||
// object is cJSON_String
|
|
||||||
//
|
|
||||||
// llgo:link (*JSON).SetValuestring C.cJSON_SetValuestring
|
|
||||||
func (o *JSON) SetValuestring(v *c.Char) *c.Char { return nil }
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
|
||||||
//
|
|
||||||
// malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks
|
|
||||||
//
|
|
||||||
//go:linkname Malloc C.cJSON_malloc
|
|
||||||
func Malloc(size uintptr)
|
|
||||||
|
|
||||||
// CJSON_PUBLIC(void) cJSON_free(void *object);
|
|
||||||
//
|
|
||||||
//go:linkname Free C.cJSON_free
|
//go:linkname Free C.cJSON_free
|
||||||
func Free(ptr unsafe.Pointer)
|
func Free(ptr unsafe.Pointer)
|
||||||
|
|
||||||
|
//go:linkname FreeCStr C.cJSON_free
|
||||||
|
func FreeCStr(*c.Char)
|
||||||
|
|||||||
61
c/clang/_demo/castdump/astdump.go
Normal file
61
c/clang/_demo/castdump/astdump.go
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
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()
|
||||||
|
}
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/c/clang"
|
|
||||||
"github.com/goplus/llgo/chore/_xtool/llcppsymg/clangutils"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
_, unit, err := clangutils.CreateTranslationUnit(&clangutils.Config{
|
|
||||||
File: "#include <stddef.h>",
|
|
||||||
Temp: true,
|
|
||||||
IsCpp: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
println(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
clang.GetInclusions(unit, func(included_file clang.File, inclusion_stack *clang.SourceLocation, include_len c.Uint, client_data c.Pointer) {
|
|
||||||
filename := included_file.FileName()
|
|
||||||
c.Printf(c.Str("Included file: %s Include length: %d\n"), filename.CStr(), include_len)
|
|
||||||
inclusions := unsafe.Slice(inclusion_stack, include_len)
|
|
||||||
for i := range inclusions {
|
|
||||||
loc := inclusions[i]
|
|
||||||
var file clang.File
|
|
||||||
var line, column c.Uint
|
|
||||||
loc.SpellingLocation(&file, &line, &column, nil)
|
|
||||||
filename = file.FileName()
|
|
||||||
c.Printf(c.Str(" included from: %s:%d:%d\n"), filename.CStr(), line, column)
|
|
||||||
}
|
|
||||||
}, nil)
|
|
||||||
}
|
|
||||||
@@ -80,7 +80,7 @@ func printFuncInfo(cursor clang.Cursor) {
|
|||||||
}
|
}
|
||||||
c.Printf(c.Str("%s\n"), cursorStr.CStr())
|
c.Printf(c.Str("%s\n"), cursorStr.CStr())
|
||||||
|
|
||||||
if cursor.Kind == clang.CursorCXXMethod || cursor.Kind == clang.CursorFunctionDecl {
|
if cursor.Kind == clang.CXXMethod || cursor.Kind == clang.FunctionDecl {
|
||||||
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()
|
||||||
@@ -107,19 +107,19 @@ func printFuncInfo(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.CursorMacroDefinition {
|
if cursor.Kind == clang.MacroDefinition {
|
||||||
printMarcoInfo(cursor)
|
printMarcoInfo(cursor)
|
||||||
} else if cursor.Kind == clang.CursorNamespace {
|
} else if cursor.Kind == clang.Namespace {
|
||||||
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.CursorClassDecl {
|
} else if cursor.Kind == clang.ClassDecl {
|
||||||
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.CursorCXXMethod || cursor.Kind == clang.CursorFunctionDecl {
|
} else if cursor.Kind == clang.CXXMethod || cursor.Kind == clang.FunctionDecl {
|
||||||
printFuncInfo(cursor)
|
printFuncInfo(cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,53 +15,9 @@ CXChildVisitResult wrap_visitor(CXCursor cursor, CXCursor parent, CXClientData d
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
void wrap_clang_getLocation(CXTranslationUnit tu, CXFile file, unsigned line, unsigned column, CXSourceLocation *loc) {
|
CXString wrap_clang_getCursorSpelling(CXCursor *cur) { return clang_getCursorSpelling(*cur); }
|
||||||
*loc = clang_getLocation(tu, file, line, column);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wrap_clang_getLocationForOffset(CXTranslationUnit tu, CXFile file, unsigned offset, CXSourceLocation *loc) {
|
CXString wrap_clang_Cursor_getMangling(CXCursor *cur) { return clang_Cursor_getMangling(*cur); }
|
||||||
*loc = clang_getLocationForOffset(tu, file, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wrap_clang_getTranslationUnitCursor(CXTranslationUnit uint, CXCursor *cur) {
|
|
||||||
*cur = clang_getTranslationUnitCursor(uint);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned wrap_clang_equalCursors(CXCursor *cursor1, CXCursor *cursor2) {
|
|
||||||
return clang_equalCursors(*cursor1, *cursor2);
|
|
||||||
}
|
|
||||||
|
|
||||||
int wrap_clang_Cursor_isNull(CXCursor *cursor) { return clang_Cursor_isNull(*cursor); }
|
|
||||||
|
|
||||||
void wrap_clang_getCursorSemanticParent(CXCursor *C, CXCursor *parent) { *parent = clang_getCursorSemanticParent(*C); }
|
|
||||||
|
|
||||||
void wrap_clang_getCursorDefinition(CXCursor *C, CXCursor *def) { *def = clang_getCursorDefinition(*C); }
|
|
||||||
|
|
||||||
void wrap_clang_getCursorLexicalParent(CXCursor *C, CXCursor *parent) { *parent = clang_getCursorLexicalParent(*C); }
|
|
||||||
|
|
||||||
void wrap_clang_getOverriddenCursors(CXCursor *cursor, CXCursor **overridden, unsigned *num_overridden) {
|
|
||||||
clang_getOverriddenCursors(*cursor, overridden, num_overridden);
|
|
||||||
}
|
|
||||||
|
|
||||||
CXFile wrap_clang_getIncludedFile(CXCursor *cursor) { return clang_getIncludedFile(*cursor); }
|
|
||||||
|
|
||||||
void wrap_clang_getCursor(CXTranslationUnit uint, CXSourceLocation *loc, CXCursor *cur) {
|
|
||||||
*cur = clang_getCursor(uint, *loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wrap_clang_getCursorLocation(CXCursor *cur, CXSourceLocation *loc) { *loc = clang_getCursorLocation(*cur); }
|
|
||||||
|
|
||||||
void wrap_clang_getCursorExtent(CXCursor *cur, CXSourceRange *range) { *range = clang_getCursorExtent(*cur); }
|
|
||||||
|
|
||||||
void wrap_clang_getCursorType(CXCursor *cur, CXType *typ) { *typ = clang_getCursorType(*cur); }
|
|
||||||
|
|
||||||
CXString wrap_clang_getTypeSpelling(CXType *typ) { return clang_getTypeSpelling(*typ); }
|
|
||||||
|
|
||||||
void wrap_clang_getTypedefDeclUnderlyingType(CXCursor *cur, CXType *typ) {
|
|
||||||
*typ = clang_getTypedefDeclUnderlyingType(*cur);
|
|
||||||
}
|
|
||||||
|
|
||||||
long long wrap_clang_getEnumConstantDeclValue(CXCursor *cur) { return clang_getEnumConstantDeclValue(*cur); }
|
|
||||||
|
|
||||||
int wrap_clang_Cursor_getNumArguments(CXCursor *cur) { return clang_Cursor_getNumArguments(*cur); }
|
int wrap_clang_Cursor_getNumArguments(CXCursor *cur) { return clang_Cursor_getNumArguments(*cur); }
|
||||||
|
|
||||||
@@ -69,134 +25,29 @@ void wrap_clang_Cursor_getArgument(CXCursor *C, unsigned i, CXCursor *argCur) {
|
|||||||
*argCur = clang_Cursor_getArgument(*C, i);
|
*argCur = clang_Cursor_getArgument(*C, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wrap_clang_getCanonicalType(CXType *typ, CXType *canonicalType) { *canonicalType = clang_getCanonicalType(*typ); }
|
void wrap_clang_getTranslationUnitCursor(CXTranslationUnit uint, CXCursor *cur) {
|
||||||
|
*cur = clang_getTranslationUnitCursor(uint);
|
||||||
unsigned wrap_clang_isConstQualifiedType(CXType *typ) { return clang_isConstQualifiedType(*typ); }
|
|
||||||
|
|
||||||
unsigned wrap_clang_Cursor_isMacroFunctionLike(CXCursor *cur) { return clang_Cursor_isMacroFunctionLike(*cur); }
|
|
||||||
|
|
||||||
unsigned wrap_clang_Cursor_isMacroBuiltin(CXCursor *cur) { return clang_Cursor_isMacroBuiltin(*cur); }
|
|
||||||
|
|
||||||
unsigned wrap_clang_Cursor_isFunctionInlined(CXCursor *cur) { return clang_Cursor_isFunctionInlined(*cur); }
|
|
||||||
|
|
||||||
unsigned wrap_clang_isVolatileQualifiedType(CXType *T) { return clang_isVolatileQualifiedType(*T); }
|
|
||||||
|
|
||||||
unsigned wrap_clang_isRestrictQualifiedType(CXType *T) { return clang_isRestrictQualifiedType(*T); }
|
|
||||||
|
|
||||||
void wrap_clang_getPointeeType(CXType *pointerTyp, CXType *pointeeTyp) {
|
|
||||||
*pointeeTyp = clang_getPointeeType(*pointerTyp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wrap_clang_getNonReferenceType(CXType *typ, CXType *nonRefTyp) { *nonRefTyp = clang_getNonReferenceType(*typ); }
|
void wrap_clang_getCursorType(CXCursor *cur, CXType *typ) { *typ = clang_getCursorType(*cur); }
|
||||||
|
|
||||||
void wrap_clang_getTypeDeclaration(CXType *typ, CXCursor *cur) { *cur = clang_getTypeDeclaration(*typ); }
|
|
||||||
|
|
||||||
void wrap_clang_getResultType(CXType *typ, CXType *resultTyp) { *resultTyp = clang_getResultType(*typ); }
|
|
||||||
|
|
||||||
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); }
|
|
||||||
|
|
||||||
unsigned wrap_clang_isFunctionTypeVariadic(CXType *typ) { return clang_isFunctionTypeVariadic(*typ); }
|
|
||||||
|
|
||||||
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_getElementType(CXType *Typ, CXType *elemTyp) { *elemTyp = clang_getElementType(*Typ); }
|
CXString wrap_clang_getTypeSpelling(CXType *typ) { return clang_getTypeSpelling(*typ); }
|
||||||
|
|
||||||
void wrap_clang_getArrayElementType(CXType *arrayTyp, CXType *elemTyp) {
|
|
||||||
*elemTyp = clang_getArrayElementType(*arrayTyp);
|
|
||||||
}
|
|
||||||
|
|
||||||
long long wrap_clang_getArraySize(CXType *arrayTyp) { return clang_getArraySize(*arrayTyp); }
|
|
||||||
|
|
||||||
void wrap_clang_Type_getNamedType(CXType *typ, CXType *namedTyp) { *namedTyp = clang_Type_getNamedType(*typ); }
|
|
||||||
|
|
||||||
long long wrap_clang_Type_getSizeOf(CXType *typ) { return clang_Type_getSizeOf(*typ); }
|
|
||||||
|
|
||||||
unsigned wrap_clang_Cursor_isAnonymous(CXCursor *cursor) { return clang_Cursor_isAnonymous(*cursor); }
|
|
||||||
|
|
||||||
unsigned wrap_clang_Cursor_isAnonymousRecordDecl(CXCursor *cursor) {
|
|
||||||
return clang_Cursor_isAnonymousRecordDecl(*cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum CX_CXXAccessSpecifier wrap_clang_getCXXAccessSpecifier(CXCursor *cursor) {
|
|
||||||
return clang_getCXXAccessSpecifier(*cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum CX_StorageClass wrap_clang_Cursor_getStorageClass(CXCursor *cursor) {
|
|
||||||
return clang_Cursor_getStorageClass(*cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
CXString wrap_clang_getCursorUSR(CXCursor *cur) { return clang_getCursorUSR(*cur); }
|
|
||||||
|
|
||||||
CXString wrap_clang_getCursorSpelling(CXCursor *cur) { return clang_getCursorSpelling(*cur); }
|
|
||||||
|
|
||||||
CXString wrap_clang_getCursorDisplayName(CXCursor *cur) { return clang_getCursorDisplayName(*cur); }
|
|
||||||
|
|
||||||
void wrap_clang_getCursorReferenced(CXCursor *cur, CXCursor *referenced) {
|
|
||||||
*referenced = clang_getCursorReferenced(*cur);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned wrap_clang_Cursor_isVariadic(CXCursor *cur) { return clang_Cursor_isVariadic(*cur); }
|
|
||||||
|
|
||||||
void wrap_clang_Cursor_getCommentRange(CXCursor *cur, CXSourceRange *range) {
|
|
||||||
*range = clang_Cursor_getCommentRange(*cur);
|
|
||||||
}
|
|
||||||
|
|
||||||
CXString wrap_clang_Cursor_getRawCommentText(CXCursor *cursor) { return clang_Cursor_getRawCommentText(*cursor); }
|
|
||||||
|
|
||||||
CXString wrap_clang_Cursor_getMangling(CXCursor *cur) { return clang_Cursor_getMangling(*cur); }
|
|
||||||
|
|
||||||
unsigned wrap_clang_CXXConstructor_isConvertingConstructor(CXCursor *cursor) {
|
|
||||||
return clang_CXXConstructor_isConvertingConstructor(*cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned wrap_clang_CXXConstructor_isCopyConstructor(CXCursor *cursor) {
|
|
||||||
return clang_CXXConstructor_isCopyConstructor(*cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned wrap_clang_CXXConstructor_isDefaultConstructor(CXCursor *cursor) {
|
|
||||||
return clang_CXXConstructor_isDefaultConstructor(*cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned wrap_clang_CXXConstructor_isMoveConstructor(CXCursor *cursor) {
|
|
||||||
return clang_CXXConstructor_isMoveConstructor(*cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned wrap_clang_CXXField_isMutable(CXCursor *cursor) { return clang_CXXField_isMutable(*cursor); }
|
|
||||||
|
|
||||||
unsigned wrap_clang_CXXMethod_isDefaulted(CXCursor *cursor) { return clang_CXXMethod_isDefaulted(*cursor); }
|
|
||||||
|
|
||||||
unsigned wrap_clang_CXXMethod_isDeleted(CXCursor *cursor) { return clang_CXXMethod_isDeleted(*cursor); }
|
|
||||||
|
|
||||||
unsigned wrap_clang_CXXMethod_isPureVirtual(CXCursor *cursor) { return clang_CXXMethod_isPureVirtual(*cursor); }
|
|
||||||
|
|
||||||
unsigned wrap_clang_CXXMethod_isStatic(CXCursor *cursor) { return clang_CXXMethod_isStatic(*cursor); }
|
|
||||||
|
|
||||||
unsigned wrap_clang_CXXMethod_isVirtual(CXCursor *cursor) { return clang_CXXMethod_isVirtual(*cursor); }
|
|
||||||
|
|
||||||
unsigned wrap_clang_CXXMethod_isCopyAssignmentOperator(CXCursor *cursor) {
|
|
||||||
return clang_CXXMethod_isCopyAssignmentOperator(*cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned wrap_clang_CXXMethod_isMoveAssignmentOperator(CXCursor *cursor) {
|
|
||||||
return clang_CXXMethod_isMoveAssignmentOperator(*cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned wrap_clang_CXXMethod_isExplicit(CXCursor *cursor) { return clang_CXXMethod_isExplicit(*cursor); }
|
|
||||||
|
|
||||||
unsigned wrap_clang_CXXRecord_isAbstract(CXCursor *cursor) { return clang_CXXRecord_isAbstract(*cursor); }
|
|
||||||
|
|
||||||
unsigned wrap_clang_EnumDecl_isScoped(CXCursor *cursor) { return clang_EnumDecl_isScoped(*cursor); }
|
|
||||||
|
|
||||||
unsigned wrap_clang_CXXMethod_isConst(CXCursor *cursor) { return clang_CXXMethod_isConst(*cursor); }
|
|
||||||
|
|
||||||
CXTokenKind wrap_clang_getTokenKind(CXToken *token) { return clang_getTokenKind(*token); }
|
|
||||||
|
|
||||||
CXString wrap_clang_getTokenSpelling(CXTranslationUnit unit, CXToken *token) {
|
CXString wrap_clang_getTokenSpelling(CXTranslationUnit unit, CXToken *token) {
|
||||||
return clang_getTokenSpelling(unit, *token);
|
return clang_getTokenSpelling(unit, *token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wrap_clang_getCursorLocation(CXCursor *cur, CXSourceLocation *loc) { *loc = clang_getCursorLocation(*cur); }
|
||||||
|
|
||||||
|
void wrap_clang_getSpellingLocation(CXSourceLocation *loc, CXFile *file, unsigned *line, unsigned *column,
|
||||||
|
unsigned *offset) {
|
||||||
|
clang_getSpellingLocation(*loc, file, line, column, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wrap_clang_getCursorExtent(CXCursor *cur, CXSourceRange *range) { *range = clang_getCursorExtent(*cur); }
|
||||||
|
|
||||||
void wrap_clang_tokenize(CXTranslationUnit unit, CXSourceRange *Range, CXToken **Tokens, unsigned *NumTokens) {
|
void wrap_clang_tokenize(CXTranslationUnit unit, CXSourceRange *Range, CXToken **Tokens, unsigned *NumTokens) {
|
||||||
clang_tokenize(unit, *Range, Tokens, NumTokens);
|
clang_tokenize(unit, *Range, Tokens, NumTokens);
|
||||||
}
|
}
|
||||||
@@ -206,15 +57,4 @@ unsigned wrap_clang_visitChildren(CXCursor *parent, wrap_CXCursorVisitor visitor
|
|||||||
return clang_visitChildren(*parent, wrap_visitor, CXClientData(&data));
|
return clang_visitChildren(*parent, wrap_visitor, CXClientData(&data));
|
||||||
}
|
}
|
||||||
|
|
||||||
int wrap_clang_Location_isInSystemHeader(CXSourceLocation *loc) { return clang_Location_isInSystemHeader(*loc); }
|
|
||||||
|
|
||||||
void wrap_clang_getSpellingLocation(CXSourceLocation *loc, CXFile *file, unsigned *line, unsigned *column,
|
|
||||||
unsigned *offset) {
|
|
||||||
clang_getSpellingLocation(*loc, file, line, column, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wrap_clang_getRangeStart(CXSourceRange *range, CXSourceLocation *loc) { *loc = clang_getRangeStart(*range); }
|
|
||||||
|
|
||||||
void wrap_clang_getRangeEnd(CXSourceRange *range, CXSourceLocation *loc) { *loc = clang_getRangeEnd(*range); }
|
|
||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|||||||
@@ -57,12 +57,3 @@ type StringSet struct {
|
|||||||
*/
|
*/
|
||||||
// llgo:link (*StringSet).Dispose C.clang_disposeStringSet
|
// llgo:link (*StringSet).Dispose C.clang_disposeStringSet
|
||||||
func (*StringSet) Dispose() {}
|
func (*StringSet) Dispose() {}
|
||||||
|
|
||||||
func GoString(clangStr String) (str string) {
|
|
||||||
defer clangStr.Dispose()
|
|
||||||
cstr := clangStr.CStr()
|
|
||||||
if cstr != nil {
|
|
||||||
str = c.GoString(cstr)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|||||||
2035
c/clang/clang.go
2035
c/clang/clang.go
File diff suppressed because it is too large
Load Diff
@@ -1,27 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/c/debug"
|
|
||||||
)
|
|
||||||
|
|
||||||
type T struct {
|
|
||||||
n int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *T) Demo() {
|
|
||||||
println(t.n)
|
|
||||||
addr := debug.Address()
|
|
||||||
c.Printf(c.Str("addr:0x%x\n"), addr)
|
|
||||||
var info debug.Info
|
|
||||||
r := debug.Addrinfo(addr, &info)
|
|
||||||
if r == 0 {
|
|
||||||
panic("not found info")
|
|
||||||
}
|
|
||||||
c.Printf(c.Str("func file:%s name:%s base:0x%x addr:0x%x\n"), info.Fname, info.Sname, info.Fbase, info.Saddr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
t := &T{100}
|
|
||||||
t.Demo()
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c/debug"
|
|
||||||
)
|
|
||||||
|
|
||||||
type T struct {
|
|
||||||
n int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *T) Demo() {
|
|
||||||
println(t.n)
|
|
||||||
debug.StackTrace(0, func(fr *debug.Frame) bool {
|
|
||||||
var info debug.Info
|
|
||||||
debug.Addrinfo(unsafe.Pointer(fr.PC), &info)
|
|
||||||
println("[", fr.PC, "]", fr.Name, "+", fr.Offset, ", SP =", fr.SP)
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
t := &T{100}
|
|
||||||
t.Demo()
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
#if defined(__linux__)
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <features.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <libunwind.h>
|
|
||||||
|
|
||||||
void *llgo_address() {
|
|
||||||
return __builtin_return_address(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int llgo_addrinfo(void *addr, Dl_info *info) {
|
|
||||||
return dladdr(addr, info);
|
|
||||||
}
|
|
||||||
|
|
||||||
void llgo_stacktrace(int skip, void *ctx, int (*fn)(void *ctx, void *pc, void *offset, void *sp, char *name)) {
|
|
||||||
unw_cursor_t cursor;
|
|
||||||
unw_context_t context;
|
|
||||||
unw_word_t offset, pc, sp;
|
|
||||||
char fname[256];
|
|
||||||
unw_getcontext(&context);
|
|
||||||
unw_init_local(&cursor, &context);
|
|
||||||
int depth = 0;
|
|
||||||
while (unw_step(&cursor) > 0) {
|
|
||||||
if (depth < skip) {
|
|
||||||
depth++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (unw_get_reg(&cursor, UNW_REG_IP, &pc) == 0) {
|
|
||||||
unw_get_proc_name(&cursor, fname, sizeof(fname), &offset);
|
|
||||||
unw_get_reg(&cursor, UNW_REG_SP, &sp);
|
|
||||||
if (fn(ctx, (void*)pc, (void*)offset, (void*)sp, fname) == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
package debug
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
LLGoPackage = "link"
|
|
||||||
LLGoFiles = "_wrap/debug.c"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Info struct {
|
|
||||||
Fname *c.Char
|
|
||||||
Fbase c.Pointer
|
|
||||||
Sname *c.Char
|
|
||||||
Saddr c.Pointer
|
|
||||||
}
|
|
||||||
|
|
||||||
//go:linkname Address C.llgo_address
|
|
||||||
func Address() unsafe.Pointer
|
|
||||||
|
|
||||||
//go:linkname Addrinfo C.llgo_addrinfo
|
|
||||||
func Addrinfo(addr unsafe.Pointer, info *Info) c.Int
|
|
||||||
|
|
||||||
//go:linkname stacktrace C.llgo_stacktrace
|
|
||||||
func stacktrace(skip c.Int, ctx unsafe.Pointer, fn func(ctx, pc, offset, sp unsafe.Pointer, name *c.Char) c.Int)
|
|
||||||
|
|
||||||
type Frame struct {
|
|
||||||
PC uintptr
|
|
||||||
Offset uintptr
|
|
||||||
SP unsafe.Pointer
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
|
|
||||||
func StackTrace(skip int, fn func(fr *Frame) bool) {
|
|
||||||
stacktrace(c.Int(1+skip), unsafe.Pointer(&fn), func(ctx, pc, offset, sp unsafe.Pointer, name *c.Char) c.Int {
|
|
||||||
fn := *(*func(fr *Frame) bool)(ctx)
|
|
||||||
if !fn(&Frame{uintptr(pc), uintptr(offset), sp, c.GoString(name)}) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return 1
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
struct array
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
int z;
|
|
||||||
int k;
|
|
||||||
};
|
|
||||||
|
|
||||||
int demo1(struct array a)
|
|
||||||
{
|
|
||||||
printf("c.demo1: %d %d %d %d\n",a.x,a.y,a.z,a.k);
|
|
||||||
return a.x+a.y+a.z+a.k;
|
|
||||||
}
|
|
||||||
|
|
||||||
int demo2( int (*fn)(struct array)) {
|
|
||||||
printf("c.demo2: %p\n",fn);
|
|
||||||
struct array a;
|
|
||||||
a.x = 1;
|
|
||||||
a.y = 2;
|
|
||||||
a.z = 3;
|
|
||||||
a.k = 4;
|
|
||||||
return (*fn)(a);
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/c/ffi"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
LLGoPackage = "link"
|
|
||||||
LLGoFiles = "../_wrap/wrap.c"
|
|
||||||
)
|
|
||||||
|
|
||||||
//llgo:type C
|
|
||||||
type Callback func(array) c.Int
|
|
||||||
|
|
||||||
//go:linkname demo1 C.demo1
|
|
||||||
func demo1(array) c.Int
|
|
||||||
|
|
||||||
//go:linkname demo2 C.demo2
|
|
||||||
func demo2(fn Callback) c.Int
|
|
||||||
|
|
||||||
//llgo:type C
|
|
||||||
type array struct {
|
|
||||||
x c.Int
|
|
||||||
y c.Int
|
|
||||||
z c.Int
|
|
||||||
k c.Int
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
typeInt32 = &ffi.Type{4, 4, ffi.Sint32, nil}
|
|
||||||
typePointer = &ffi.Type{unsafe.Sizeof(0), uint16(unsafe.Alignof(0)), ffi.Pointer, nil}
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
cdemo1()
|
|
||||||
cdemo2()
|
|
||||||
}
|
|
||||||
|
|
||||||
func cdemo1() {
|
|
||||||
var cif ffi.Cif
|
|
||||||
tarray := &ffi.Type{0, 0, ffi.Struct, &[]*ffi.Type{typeInt32, typeInt32, typeInt32, typeInt32, nil}[0]}
|
|
||||||
status := ffi.PrepCif(&cif, ffi.DefaultAbi, 1, typeInt32, &[]*ffi.Type{tarray}[0])
|
|
||||||
if status != ffi.OK {
|
|
||||||
panic(status)
|
|
||||||
}
|
|
||||||
ar := array{1, 2, 3, 4}
|
|
||||||
var ret int32
|
|
||||||
ffi.Call(&cif, c.Func(demo1), unsafe.Pointer(&ret), &[]unsafe.Pointer{unsafe.Pointer(&ar)}[0])
|
|
||||||
c.Printf(c.Str("ret: %d\n"), ret)
|
|
||||||
}
|
|
||||||
|
|
||||||
func cdemo2() {
|
|
||||||
var cif ffi.Cif
|
|
||||||
status := ffi.PrepCif(&cif, ffi.DefaultAbi, 1, typeInt32, &[]*ffi.Type{typePointer}[0])
|
|
||||||
if status != ffi.OK {
|
|
||||||
panic(status)
|
|
||||||
}
|
|
||||||
var ret int32
|
|
||||||
fn := c.Func(demo1)
|
|
||||||
ffi.Call(&cif, c.Func(demo2), unsafe.Pointer(&ret), &[]unsafe.Pointer{unsafe.Pointer(&fn)}[0])
|
|
||||||
c.Printf(c.Str("ret: %d\n"), ret)
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/c/ffi"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
LLGoPackage = "link"
|
|
||||||
LLGoFiles = "../_wrap/wrap.c"
|
|
||||||
)
|
|
||||||
|
|
||||||
//llgo:type C
|
|
||||||
type Callback func(array) c.Int
|
|
||||||
|
|
||||||
//go:linkname demo1 C.demo1
|
|
||||||
func demo1(array) c.Int
|
|
||||||
|
|
||||||
//go:linkname demo2 C.demo2
|
|
||||||
func demo2(fn Callback) c.Int
|
|
||||||
|
|
||||||
//llgo:type C
|
|
||||||
type array struct {
|
|
||||||
x c.Int
|
|
||||||
y c.Int
|
|
||||||
z c.Int
|
|
||||||
k c.Int
|
|
||||||
}
|
|
||||||
|
|
||||||
func demo(a array) c.Int {
|
|
||||||
c.Printf(c.Str("go.demo %d %d %d %d\n"), a.x, a.y, a.z, a.k)
|
|
||||||
return a.x + a.y + a.z + a.k
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
typeInt32 = &ffi.Type{4, 4, ffi.Sint32, nil}
|
|
||||||
typePointer = &ffi.Type{unsafe.Sizeof(0), uint16(unsafe.Alignof(0)), ffi.Pointer, nil}
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
gofn()
|
|
||||||
c.Printf(c.Str("\n"))
|
|
||||||
goclosure()
|
|
||||||
}
|
|
||||||
|
|
||||||
func gofn() {
|
|
||||||
var cif ffi.Cif
|
|
||||||
status := ffi.PrepCif(&cif, ffi.DefaultAbi, 1, typeInt32, &[]*ffi.Type{typePointer}[0])
|
|
||||||
if status != ffi.OK {
|
|
||||||
panic(status)
|
|
||||||
}
|
|
||||||
var fncode unsafe.Pointer
|
|
||||||
closure := ffi.ClosureAlloc(&fncode)
|
|
||||||
defer ffi.ClosureFree(closure)
|
|
||||||
status = ffi.PreClosureLoc(closure, &cif, func(cif *ffi.Cif, ret unsafe.Pointer, args *unsafe.Pointer, userdata unsafe.Pointer) {
|
|
||||||
ar := *(*array)(ffi.Index(args, 0))
|
|
||||||
*(*c.Int)(ret) = demo(ar)
|
|
||||||
}, nil, fncode)
|
|
||||||
if status != ffi.OK {
|
|
||||||
panic(status)
|
|
||||||
}
|
|
||||||
var ret int32
|
|
||||||
ffi.Call(&cif, c.Func(demo2), unsafe.Pointer(&ret), &[]unsafe.Pointer{unsafe.Pointer(&fncode)}[0])
|
|
||||||
c.Printf(c.Str("ret: %d\n"), ret)
|
|
||||||
}
|
|
||||||
|
|
||||||
func goclosure() {
|
|
||||||
var cif ffi.Cif
|
|
||||||
status := ffi.PrepCif(&cif, ffi.DefaultAbi, 1, typeInt32, &[]*ffi.Type{typePointer}[0])
|
|
||||||
if status != ffi.OK {
|
|
||||||
panic(status)
|
|
||||||
}
|
|
||||||
fn := func(ar array) c.Int {
|
|
||||||
c.Printf(c.Str("call closure %d\n"), cif.NArgs)
|
|
||||||
return demo(ar)
|
|
||||||
}
|
|
||||||
var fncode unsafe.Pointer
|
|
||||||
closure := ffi.ClosureAlloc(&fncode)
|
|
||||||
defer ffi.ClosureFree(closure)
|
|
||||||
status = ffi.PreClosureLoc(closure, &cif, func(cif *ffi.Cif, ret unsafe.Pointer, args *unsafe.Pointer, userdata unsafe.Pointer) {
|
|
||||||
ar := *(*array)(ffi.Index(args, 0))
|
|
||||||
fn := *(*func(array) c.Int)(userdata)
|
|
||||||
*(*c.Int)(ret) = fn(ar)
|
|
||||||
}, unsafe.Pointer(&fn), fncode)
|
|
||||||
if status != ffi.OK {
|
|
||||||
panic(status)
|
|
||||||
}
|
|
||||||
var ret int32
|
|
||||||
ffi.Call(&cif, c.Func(demo2), unsafe.Pointer(&ret), &[]unsafe.Pointer{unsafe.Pointer(&fncode)}[0])
|
|
||||||
c.Printf(c.Str("ret: %d\n"), ret)
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/c/ffi"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
typeInt32 = &ffi.Type{4, 4, ffi.Sint32, nil}
|
|
||||||
typePointer = &ffi.Type{unsafe.Sizeof(0), uint16(unsafe.Alignof(0)), ffi.Pointer, nil}
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
var cif ffi.Cif
|
|
||||||
status := ffi.PrepCifVar(&cif, ffi.DefaultAbi, 1, 2, typeInt32, &[]*ffi.Type{typePointer, typeInt32}[0])
|
|
||||||
if status != ffi.OK {
|
|
||||||
panic(status)
|
|
||||||
}
|
|
||||||
var ret int32
|
|
||||||
text := c.Str("hello world: %d\n")
|
|
||||||
var n int32 = 100
|
|
||||||
ffi.Call(&cif, c.Func(c.Printf), unsafe.Pointer(&ret), &[]unsafe.Pointer{unsafe.Pointer(&text), unsafe.Pointer(&n)}[0])
|
|
||||||
c.Printf(c.Str("ret: %d\n"), ret)
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
#include <ffi.h>
|
|
||||||
|
|
||||||
void *llog_ffi_closure_alloc(void **code) {
|
|
||||||
return ffi_closure_alloc(sizeof(ffi_closure), code);
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
//go:build ((freebsd || linux || darwin) && arm64) || (windows && (amd64 || arm64))
|
|
||||||
|
|
||||||
package ffi
|
|
||||||
|
|
||||||
const (
|
|
||||||
DefaultAbi = 1
|
|
||||||
)
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
//go:build freebsd || linux || darwin
|
|
||||||
|
|
||||||
package ffi
|
|
||||||
|
|
||||||
const (
|
|
||||||
DefaultAbi = 2
|
|
||||||
)
|
|
||||||
132
c/ffi/ffi.go
132
c/ffi/ffi.go
@@ -1,132 +0,0 @@
|
|||||||
package ffi
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
LLGoPackage = "link: $(pkg-config --libs libffi); -lffi"
|
|
||||||
LLGoFiles = "$(pkg-config --cflags libffi): _wrap/libffi.c"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
Void = iota
|
|
||||||
Int
|
|
||||||
Float
|
|
||||||
Double
|
|
||||||
LongDouble
|
|
||||||
Uint8
|
|
||||||
Sint8
|
|
||||||
Uint16
|
|
||||||
Sint16
|
|
||||||
Uint32
|
|
||||||
Sint32
|
|
||||||
Uint64
|
|
||||||
Sint64
|
|
||||||
Struct
|
|
||||||
Pointer
|
|
||||||
Complex
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
OK = iota
|
|
||||||
BAD_TYPEDEF
|
|
||||||
BAD_ABI
|
|
||||||
BAD_ARGTYPE
|
|
||||||
)
|
|
||||||
|
|
||||||
type Type struct {
|
|
||||||
Size uintptr
|
|
||||||
Alignment uint16
|
|
||||||
Type uint16
|
|
||||||
Elements **Type
|
|
||||||
}
|
|
||||||
|
|
||||||
/*typedef struct {
|
|
||||||
ffi_abi abi;
|
|
||||||
unsigned nargs;
|
|
||||||
ffi_type **arg_types;
|
|
||||||
ffi_type *rtype;
|
|
||||||
unsigned bytes;
|
|
||||||
unsigned flags;
|
|
||||||
#ifdef FFI_EXTRA_CIF_FIELDS
|
|
||||||
FFI_EXTRA_CIF_FIELDS;
|
|
||||||
#endif
|
|
||||||
} ffi_cif;
|
|
||||||
*/
|
|
||||||
|
|
||||||
type Cif struct {
|
|
||||||
Abi c.Uint
|
|
||||||
NArgs c.Uint
|
|
||||||
ArgTypes **Type
|
|
||||||
RType *Type
|
|
||||||
Bytes c.Uint
|
|
||||||
Flags c.Uint
|
|
||||||
//Extra c.Uint
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
ffi_status
|
|
||||||
ffi_prep_cif(ffi_cif *cif,
|
|
||||||
ffi_abi abi,
|
|
||||||
unsigned int nargs,
|
|
||||||
ffi_type *rtype,
|
|
||||||
ffi_type **atypes);
|
|
||||||
*/
|
|
||||||
//go:linkname PrepCif C.ffi_prep_cif
|
|
||||||
func PrepCif(cif *Cif, abi c.Uint, nargs c.Uint, rtype *Type, atype **Type) c.Uint
|
|
||||||
|
|
||||||
/*
|
|
||||||
ffi_status ffi_prep_cif_var(ffi_cif *cif,
|
|
||||||
ffi_abi abi,
|
|
||||||
unsigned int nfixedargs,
|
|
||||||
unsigned int ntotalargs,
|
|
||||||
ffi_type *rtype,
|
|
||||||
ffi_type **atypes);
|
|
||||||
*/
|
|
||||||
//go:linkname PrepCifVar C.ffi_prep_cif_var
|
|
||||||
func PrepCifVar(cif *Cif, abi c.Uint, nfixedargs c.Uint, ntotalargs c.Uint, rtype *Type, atype **Type) c.Uint
|
|
||||||
|
|
||||||
/*
|
|
||||||
void ffi_call(ffi_cif *cif,
|
|
||||||
void (*fn)(void),
|
|
||||||
void *rvalue,
|
|
||||||
void **avalue);
|
|
||||||
*/
|
|
||||||
//go:linkname Call C.ffi_call
|
|
||||||
func Call(cif *Cif, fn unsafe.Pointer, rvalue unsafe.Pointer, avalue *unsafe.Pointer)
|
|
||||||
|
|
||||||
// void *ffi_closure_alloc (size_t size, void **code);
|
|
||||||
//
|
|
||||||
//go:linkname ClosureAlloc C.llog_ffi_closure_alloc
|
|
||||||
func ClosureAlloc(code *unsafe.Pointer) unsafe.Pointer
|
|
||||||
|
|
||||||
// void ffi_closure_free (void *);
|
|
||||||
//
|
|
||||||
//go:linkname ClosureFree C.ffi_closure_free
|
|
||||||
func ClosureFree(unsafe.Pointer)
|
|
||||||
|
|
||||||
/*
|
|
||||||
ffi_status
|
|
||||||
ffi_prep_closure_loc (ffi_closure*,
|
|
||||||
ffi_cif *,
|
|
||||||
void (*fun)(ffi_cif*,void*,void**,void*),
|
|
||||||
void *user_data,
|
|
||||||
void *codeloc);
|
|
||||||
*/
|
|
||||||
|
|
||||||
//llgo:type C
|
|
||||||
type ClosureFunc func(cif *Cif, ret unsafe.Pointer, args *unsafe.Pointer, userdata unsafe.Pointer)
|
|
||||||
|
|
||||||
//go:linkname PreClosureLoc C.ffi_prep_closure_loc
|
|
||||||
func PreClosureLoc(closure unsafe.Pointer, cif *Cif, fn ClosureFunc, userdata unsafe.Pointer, codeloc unsafe.Pointer) c.Uint
|
|
||||||
|
|
||||||
func add(ptr unsafe.Pointer, offset uintptr) unsafe.Pointer {
|
|
||||||
return unsafe.Pointer(uintptr(ptr) + offset)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Index(args *unsafe.Pointer, i uintptr) unsafe.Pointer {
|
|
||||||
return (*(*unsafe.Pointer)(add(unsafe.Pointer(args), i*unsafe.Sizeof(0))))
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
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
|
|
||||||
*/
|
|
||||||
@@ -31,7 +31,7 @@ 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
|
||||||
result := loop.Run(libuv.RUN_DEFAULT)
|
result := libuv.Run(loop, libuv.RUN_DEFAULT)
|
||||||
|
|
||||||
if result != 0 {
|
if result != 0 {
|
||||||
c.Fprintf(c.Stderr, c.Str("Error in Run: %s\n"), libuv.Strerror(libuv.Errno(result)))
|
c.Fprintf(c.Stderr, c.Str("Error in Run: %s\n"), libuv.Strerror(libuv.Errno(result)))
|
||||||
@@ -43,14 +43,14 @@ func main() {
|
|||||||
|
|
||||||
func onOpen(req *libuv.Fs) {
|
func onOpen(req *libuv.Fs) {
|
||||||
// Check for errors
|
// Check for errors
|
||||||
if req.GetResult() < 0 {
|
if libuv.FsGetResult(req) < 0 {
|
||||||
c.Fprintf(c.Stderr, c.Str("Error opening file: %s\n"), libuv.Strerror(libuv.Errno(req.GetResult())))
|
c.Fprintf(c.Stderr, c.Str("Error opening file: %s\n"), libuv.Strerror(libuv.Errno(libuv.FsGetResult(req))))
|
||||||
loop.Close()
|
libuv.LoopClose(loop)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the file descriptor
|
// Store the file descriptor
|
||||||
file = libuv.File(req.GetResult())
|
file = libuv.File(libuv.FsGetResult(req))
|
||||||
|
|
||||||
// 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)))
|
||||||
@@ -68,28 +68,28 @@ func readFile() {
|
|||||||
readRes := libuv.FsRead(loop, &readReq, file, &iov, 1, -1, onRead)
|
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)
|
||||||
readReq.ReqCleanup()
|
libuv.FsReqCleanup(&readReq)
|
||||||
loop.Close()
|
libuv.LoopClose(loop)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func onRead(req *libuv.Fs) {
|
func onRead(req *libuv.Fs) {
|
||||||
// Cleanup the request
|
// Cleanup the request
|
||||||
defer req.ReqCleanup()
|
defer libuv.FsReqCleanup(req)
|
||||||
// Check for errors
|
// Check for errors
|
||||||
if req.GetResult() < 0 {
|
if libuv.FsGetResult(req) < 0 {
|
||||||
c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror(libuv.Errno(req.GetResult())))
|
c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror(libuv.Errno(libuv.FsGetResult(req))))
|
||||||
} else if req.GetResult() == 0 {
|
} else if libuv.FsGetResult(req) == 0 {
|
||||||
// Close the file
|
// Close the file
|
||||||
closeRes := libuv.FsClose(loop, &closeReq, libuv.File(openReq.GetResult()), onClose)
|
closeRes := libuv.FsClose(loop, &closeReq, libuv.File(libuv.FsGetResult(&openReq)), onClose)
|
||||||
if closeRes != 0 {
|
if closeRes != 0 {
|
||||||
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)
|
||||||
loop.Close()
|
libuv.LoopClose(loop)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c.Printf(c.Str("Read %d bytes\n"), req.GetResult())
|
c.Printf(c.Str("Read %d bytes\n"), libuv.FsGetResult(req))
|
||||||
c.Printf(c.Str("Read content: %.*s\n"), req.GetResult(), (*c.Char)(unsafe.Pointer(&buffer[0])))
|
c.Printf(c.Str("Read content: %.*s\n"), libuv.FsGetResult(req), (*c.Char)(unsafe.Pointer(&buffer[0])))
|
||||||
// Read the file again
|
// Read the file again
|
||||||
readFile()
|
readFile()
|
||||||
}
|
}
|
||||||
@@ -97,8 +97,8 @@ func onRead(req *libuv.Fs) {
|
|||||||
|
|
||||||
func onClose(req *libuv.Fs) {
|
func onClose(req *libuv.Fs) {
|
||||||
// Check for errors
|
// Check for errors
|
||||||
if req.GetResult() < 0 {
|
if libuv.FsGetResult(req) < 0 {
|
||||||
c.Fprintf(c.Stderr, c.Str("Error closing file: %s\n"), libuv.Strerror(libuv.Errno(req.GetResult())))
|
c.Fprintf(c.Stderr, c.Str("Error closing file: %s\n"), libuv.Strerror(libuv.Errno(libuv.FsGetResult(req))))
|
||||||
} else {
|
} else {
|
||||||
c.Printf(c.Str("\nFile closed successfully.\n"))
|
c.Printf(c.Str("\nFile closed successfully.\n"))
|
||||||
}
|
}
|
||||||
@@ -106,10 +106,10 @@ func onClose(req *libuv.Fs) {
|
|||||||
|
|
||||||
func cleanup() {
|
func cleanup() {
|
||||||
// Cleanup the requests
|
// Cleanup the requests
|
||||||
openReq.ReqCleanup()
|
libuv.FsReqCleanup(&openReq)
|
||||||
closeReq.ReqCleanup()
|
libuv.FsReqCleanup(&closeReq)
|
||||||
// Close the loop
|
// Close the loop
|
||||||
result := loop.Close()
|
result := libuv.LoopClose(loop)
|
||||||
if result != 0 {
|
if result != 0 {
|
||||||
c.Fprintf(c.Stderr, c.Str("Error in LoopClose: %s\n"), libuv.Strerror(libuv.Errno(result)))
|
c.Fprintf(c.Stderr, c.Str("Error in LoopClose: %s\n"), libuv.Strerror(libuv.Errno(result)))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
"github.com/goplus/llgo/c"
|
||||||
"github.com/goplus/llgo/c/libuv"
|
"github.com/goplus/llgo/c/libuv"
|
||||||
"github.com/goplus/llgo/c/net"
|
"github.com/goplus/llgo/c/net"
|
||||||
@@ -19,8 +21,8 @@ func main() {
|
|||||||
var loop = libuv.DefaultLoop()
|
var loop = libuv.DefaultLoop()
|
||||||
|
|
||||||
// Initialize a TCP server
|
// Initialize a TCP server
|
||||||
server := &libuv.Tcp{}
|
var 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
|
||||||
@@ -28,24 +30,22 @@ 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
|
||||||
loop.Run(libuv.RUN_DEFAULT)
|
libuv.Run(loop, libuv.RUN_DEFAULT)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FreeWriteReq(req *libuv.Write) {
|
func FreeWriteReq(req *libuv.Write) {
|
||||||
wr := (*WriteReq)(c.Pointer(req))
|
wr := (*WriteReq)(c.Pointer(req))
|
||||||
// Free the buffer base.
|
// Free the buffer base and the WriteReq itself.
|
||||||
if wr.Buf.Base != nil {
|
|
||||||
c.Free(c.Pointer(wr.Buf.Base))
|
c.Free(c.Pointer(wr.Buf.Base))
|
||||||
wr.Buf.Base = nil
|
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) {
|
||||||
@@ -56,24 +56,29 @@ 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(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func EchoRead(client *libuv.Stream, nread c.Long, buf *libuv.Buf) {
|
func EchoRead(client *libuv.Stream, nread c.Long, buf *libuv.Buf) {
|
||||||
if nread > 0 {
|
if nread > 0 {
|
||||||
req := new(WriteReq)
|
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))
|
req.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.Req).Write(client, &req.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)
|
||||||
}
|
}
|
||||||
@@ -90,7 +95,7 @@ func OnNewConnection(server *libuv.Stream, status c.Int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Allocate memory for a new client.
|
// Allocate memory for a new client.
|
||||||
client := &libuv.Tcp{}
|
client := (*libuv.Tcp)(c.Malloc(unsafe.Sizeof(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"))
|
||||||
@@ -100,6 +105,7 @@ func OnNewConnection(server *libuv.Stream, status c.Int) {
|
|||||||
// Initialize the client TCP handle.
|
// Initialize the client TCP handle.
|
||||||
if libuv.InitTcp(libuv.DefaultLoop(), client) < 0 {
|
if libuv.InitTcp(libuv.DefaultLoop(), client) < 0 {
|
||||||
c.Fprintf(c.Stderr, c.Str("Failed to initialize client\n"))
|
c.Fprintf(c.Stderr, c.Str("Failed to initialize client\n"))
|
||||||
|
c.Free(c.Pointer(client))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
#include <uv.h>
|
|
||||||
|
|
||||||
int uv_tcp_get_io_watcher_fd (uv_tcp_t* handle) {
|
|
||||||
return handle->io_watcher.fd;
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package 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
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package libuv
|
|
||||||
|
|
||||||
import (
|
|
||||||
_ "unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
)
|
|
||||||
|
|
||||||
/* Handle types. */
|
|
||||||
|
|
||||||
type Check struct {
|
|
||||||
Unused [120]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Function type */
|
|
||||||
|
|
||||||
// llgo:type C
|
|
||||||
type CheckCb func(Check *Check)
|
|
||||||
|
|
||||||
//go:linkname InitCheck C.uv_check_init
|
|
||||||
func InitCheck(loop *Loop, Check *Check) c.Int
|
|
||||||
|
|
||||||
// llgo:link (*Check).Start C.uv_check_start
|
|
||||||
func (Check *Check) Start(CheckCb CheckCb) c.Int { return 0 }
|
|
||||||
|
|
||||||
// llgo:link (*Check).Stop C.uv_check_stop
|
|
||||||
func (Check *Check) Stop() c.Int { return 0 }
|
|
||||||
@@ -95,7 +95,7 @@ const (
|
|||||||
ECHARSET Errno = -4080
|
ECHARSET Errno = -4080
|
||||||
ENONET Errno = -4056
|
ENONET Errno = -4056
|
||||||
UNKNOWN Errno = -4094
|
UNKNOWN Errno = -4094
|
||||||
EOF Errno = -4095
|
EOF Errno = -1
|
||||||
EREMOTEIO Errno = -4030
|
EREMOTEIO Errno = -4030
|
||||||
ERRNO_MAX Errno = EOF - 1
|
ERRNO_MAX Errno = EOF - 1
|
||||||
)
|
)
|
||||||
|
|||||||
101
c/libuv/fs.go
101
c/libuv/fs.go
@@ -106,40 +106,29 @@ type FsPollCb func(handle *FsPoll, status c.Int, events c.Int)
|
|||||||
|
|
||||||
/* Fs related function and method */
|
/* Fs related function and method */
|
||||||
|
|
||||||
// llgo:link (*Fs).GetType C.uv_fs_get_type
|
//go:linkname FsGetType C.uv_fs_get_type
|
||||||
func (req *Fs) GetType() FsType {
|
func FsGetType(req *Fs) FsType
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Fs).GetPath C.uv_fs_get_path
|
//go:linkname FsGetPath C.uv_fs_get_path
|
||||||
func (req *Fs) GetPath() *c.Char {
|
func FsGetPath(req *Fs) *c.Char
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Fs).GetResult C.uv_fs_get_result
|
//go:linkname FsGetResult C.uv_fs_get_result
|
||||||
func (req *Fs) GetResult() c.Int {
|
func FsGetResult(req *Fs) c.Int
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Fs).GetPtr C.uv_fs_get_ptr
|
//go:linkname FsGetPtr C.uv_fs_get_ptr
|
||||||
func (req *Fs) GetPtr() c.Pointer {
|
func FsGetPtr(req *Fs) c.Pointer
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Fs).GetSystemError C.uv_fs_get_system_error
|
//go:linkname FsGetSystemError C.uv_fs_get_system_error
|
||||||
func (req *Fs) GetSystemError() c.Int {
|
func FsGetSystemError(req *Fs) c.Int
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Fs).GetStatBuf C.uv_fs_get_statbuf
|
//go:linkname FsGetStatBuf C.uv_fs_get_statbuf
|
||||||
func (req *Fs) GetStatBuf() *Stat {
|
func FsGetStatBuf(req *Fs) *Stat
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Fs).ReqCleanup C.uv_fs_req_cleanup
|
//go:linkname FsReqCleanup C.uv_fs_req_cleanup
|
||||||
func (req *Fs) ReqCleanup() {
|
func FsReqCleanup(req *Fs)
|
||||||
// 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
|
||||||
@@ -252,56 +241,32 @@ 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
|
||||||
|
|
||||||
// llgo:link (*FsEvent).Start C.uv_fs_event_start
|
//go:linkname FsEventStart C.uv_fs_event_start
|
||||||
func (handle *FsEvent) Start(cb FsEventCb, path *c.Char, flags c.Int) c.Int {
|
func FsEventStart(handle *FsEvent, cb FsEventCb, path *c.Char, flags c.Int) c.Int
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*FsEvent).Stop C.uv_fs_event_stop
|
//go:linkname FsEventStop C.uv_fs_event_stop
|
||||||
func (handle *FsEvent) Stop() c.Int {
|
func FsEventStop(handle *FsEvent) c.Int
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*FsEvent).Close C.uv_fs_event_close
|
//go:linkname FsEventClose C.uv_fs_event_close
|
||||||
func (handle *FsEvent) Close() c.Int {
|
func FsEventClose(handle *FsEvent) c.Int
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*FsEvent).Getpath C.uv_fs_event_getpath
|
//go:linkname FsEventGetpath C.uv_fs_event_getpath
|
||||||
func (handle *FsEvent) Getpath() *c.Char {
|
func FsEventGetpath(handle *FsEvent) *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
|
||||||
|
|
||||||
// llgo:link (*FsPoll).Start C.uv_fs_poll_start
|
//go:linkname FsPollStart C.uv_fs_poll_start
|
||||||
func (handle *FsPoll) Start(cb FsPollCb, path *c.Char, interval uint) c.Int {
|
func FsPollStart(handle *FsPoll, cb FsPollCb, path *c.Char, interval uint) c.Int
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*FsPoll).Stop C.uv_fs_poll_stop
|
//go:linkname FsPollStop C.uv_fs_poll_stop
|
||||||
func (handle *FsPoll) Stop() c.Int {
|
func FsPollStop(handle *FsPoll) c.Int
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*FsPoll).Close C.uv_fs_poll_close
|
//go:linkname FsPollClose C.uv_fs_poll_close
|
||||||
func (handle *FsPoll) Close() c.Int {
|
func FsPollClose(handle *FsPoll) c.Int
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*FsPoll).GetPath C.uv_fs_poll_getpath
|
//go:linkname FsPollGetPath C.uv_fs_poll_getpath
|
||||||
func (handle *FsPoll) GetPath() *c.Char {
|
func FsPollGetPath(handle *FsPoll) *c.Char
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
package libuv
|
|
||||||
|
|
||||||
import (
|
|
||||||
_ "unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
)
|
|
||||||
|
|
||||||
/* Handle types. */
|
|
||||||
|
|
||||||
type Idle struct {
|
|
||||||
Unused [120]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Function type */
|
|
||||||
|
|
||||||
// llgo:type C
|
|
||||||
type IdleCb func(idle *Idle)
|
|
||||||
|
|
||||||
//go:linkname InitIdle C.uv_idle_init
|
|
||||||
func InitIdle(loop *Loop, idle *Idle) c.Int
|
|
||||||
|
|
||||||
// llgo:link (*Idle).Start C.uv_idle_start
|
|
||||||
func (idle *Idle) Start(idleCb IdleCb) c.Int { return 0 }
|
|
||||||
|
|
||||||
// llgo:link (*Idle).Stop C.uv_idle_stop
|
|
||||||
func (idle *Idle) Stop() c.Int { return 0 }
|
|
||||||
136
c/libuv/libuv.go
136
c/libuv/libuv.go
@@ -9,7 +9,6 @@ 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"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
@@ -99,12 +98,15 @@ type Loop struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Poll struct {
|
type Poll struct {
|
||||||
Data c.Pointer
|
Unused [0]byte
|
||||||
Unused [160]byte
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Request types. */
|
/* Request types. */
|
||||||
|
|
||||||
|
type Shutdown struct {
|
||||||
|
Unused [0]byte
|
||||||
|
}
|
||||||
|
|
||||||
type Buf struct {
|
type Buf struct {
|
||||||
Base *c.Char
|
Base *c.Char
|
||||||
Len uintptr
|
Len uintptr
|
||||||
@@ -133,6 +135,9 @@ 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 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)
|
||||||
|
|
||||||
@@ -155,98 +160,59 @@ func ReplaceAllocator(mallocFunc MallocFunc, reallocFunc ReallocFunc, callocFunc
|
|||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
|
|
||||||
/* Loop related functions and method. */
|
// llgo:link (*Shutdown).Shutdown C.uv_shutdown
|
||||||
|
func (shutdown *Shutdown) Shutdown(stream *Stream, shutdownCb ShutdownCb) c.Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
//go:linkname DefaultLoop C.uv_default_loop
|
// ----------------------------------------------
|
||||||
func DefaultLoop() *Loop
|
|
||||||
|
/* Loop related functions and method. */
|
||||||
|
|
||||||
//go:linkname LoopSize C.uv_loop_size
|
//go:linkname LoopSize C.uv_loop_size
|
||||||
func LoopSize() uintptr
|
func LoopSize() uintptr
|
||||||
|
|
||||||
// llgo:link (*Loop).Run C.uv_run
|
//go:linkname Run C.uv_run
|
||||||
func (loop *Loop) Run(mode RunMode) c.Int {
|
func Run(loop *Loop, mode RunMode) c.Int
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Loop).Alive C.uv_loop_alive
|
//go:linkname LoopAlive C.uv_loop_alive
|
||||||
func (loop *Loop) Alive() c.Int {
|
func LoopAlive(loop *Loop) c.Int
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// void uv_stop(uv_loop_t *loop)
|
//go:linkname LoopClose C.uv_loop_close
|
||||||
//
|
func LoopClose(loop *Loop) c.Int
|
||||||
// llgo:link (*Loop).Stop C.uv_stop
|
|
||||||
func (loop *Loop) Stop() {}
|
|
||||||
|
|
||||||
// llgo:link (*Loop).Close C.uv_loop_close
|
//go:linkname LoopConfigure C.uv_loop_configure
|
||||||
func (loop *Loop) Close() c.Int {
|
func LoopConfigure(loop *Loop, option LoopOption, arg c.Int) c.Int
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Loop).Configure C.uv_loop_configure
|
//go:linkname LoopDefault C.uv_default_loop
|
||||||
func (loop *Loop) Configure(option LoopOption, arg c.Int) c.Int {
|
func LoopDefault() *Loop
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link LoopDefault C.uv_default_loop
|
//go:linkname LoopDelete C.uv_loop_delete
|
||||||
func LoopDefault() *Loop {
|
func LoopDelete(loop *Loop) c.Int
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Loop).Delete C.uv_loop_delete
|
//go:linkname LoopFork C.uv_loop_fork
|
||||||
func (loop *Loop) Delete() c.Int {
|
func LoopFork(loop *Loop) c.Int
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Loop).Fork C.uv_loop_fork
|
//go:linkname LoopInit C.uv_loop_init
|
||||||
func (loop *Loop) Fork() c.Int {
|
func LoopInit(loop *Loop) c.Int
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Loop).Init C.uv_loop_init
|
//go:linkname LoopNew C.uv_loop_new
|
||||||
func (loop *Loop) Init() c.Int {
|
func LoopNew() *Loop
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link LoopNew C.uv_loop_new
|
//go:linkname LoopNow C.uv_now
|
||||||
func LoopNew() *Loop {
|
func LoopNow(loop *Loop) c.UlongLong
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Loop).SetData C.uv_loop_set_data
|
//go:linkname LoopUpdateTime C.uv_update_time
|
||||||
func (loop *Loop) SetData(data c.Pointer) {
|
func LoopUpdateTime(loop *Loop)
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Loop).GetData C.uv_loop_get_data
|
//go:linkname LoopBackendFd C.uv_backend_fd
|
||||||
func (loop *Loop) GetData() c.Pointer {
|
func LoopBackendFd(loop *Loop) c.Int
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Loop).Now C.uv_now
|
//go:linkname LoopBackendTimeout C.uv_backend_timeout
|
||||||
func (loop *Loop) Now() c.UlongLong {
|
func LoopBackendTimeout(loop *Loop) c.Int
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Loop).UpdateTime C.uv_update_time
|
//go:linkname LoopWalk C.uv_walk
|
||||||
func (loop *Loop) UpdateTime() {
|
func LoopWalk(loop *Loop, walkCb WalkCb, arg c.Pointer)
|
||||||
// No return value needed for this method
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Loop).BackendFd C.uv_backend_fd
|
|
||||||
func (loop *Loop) BackendFd() c.Int {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Loop).BackendTimeout C.uv_backend_timeout
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
|
|
||||||
@@ -262,15 +228,11 @@ 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
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Poll).Stop C.uv_poll_stop
|
|
||||||
func (handle *Poll) Stop() c.Int {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -83,21 +83,18 @@ type Tcp struct {
|
|||||||
Unused [256]byte
|
Unused [256]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(spongehah): Udp
|
|
||||||
type Udp struct {
|
type Udp struct {
|
||||||
Unused [224]byte
|
Unused [0]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Request types. */
|
/* Request types. */
|
||||||
|
|
||||||
// TODO(spongehah): Req
|
|
||||||
type Req struct {
|
type Req struct {
|
||||||
Unused [64]byte
|
Unused [0]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(spongehah): UdpSend
|
|
||||||
type UdpSend struct {
|
type UdpSend struct {
|
||||||
Unused [320]byte
|
Unused [0]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(spongehah): Write
|
// TODO(spongehah): Write
|
||||||
@@ -112,19 +109,12 @@ type Connect struct {
|
|||||||
Unused [88]byte
|
Unused [88]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(spongehah): GetAddrInfo
|
|
||||||
type GetAddrInfo struct {
|
type GetAddrInfo struct {
|
||||||
Unused [160]byte
|
Unused [0]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(spongehah): GetNameInfo
|
|
||||||
type GetNameInfo struct {
|
type GetNameInfo struct {
|
||||||
Unused [1320]byte
|
Unused [0]byte
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(spongehah): Shutdown
|
|
||||||
type Shutdown struct {
|
|
||||||
Unused [80]byte
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
@@ -152,19 +142,10 @@ type WriteCb func(req *Write, status c.Int)
|
|||||||
// llgo:type C
|
// llgo:type C
|
||||||
type ConnectionCb func(server *Stream, status c.Int)
|
type ConnectionCb func(server *Stream, status c.Int)
|
||||||
|
|
||||||
// llgo:type C
|
|
||||||
type ShutdownCb func(req *Shutdown, status c.Int)
|
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
|
|
||||||
/* Handle related function and method */
|
/* 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
|
// llgo:link (*Handle).Ref C.uv_ref
|
||||||
func (handle *Handle) Ref() {}
|
func (handle *Handle) Ref() {}
|
||||||
|
|
||||||
@@ -176,11 +157,17 @@ func (handle *Handle) HasRef() c.Int {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:linkname HandleSize C.uv_handle_size
|
||||||
|
func HandleSize(handleType HandleType) uintptr
|
||||||
|
|
||||||
// llgo:link (*Handle).GetType C.uv_handle_get_type
|
// llgo:link (*Handle).GetType C.uv_handle_get_type
|
||||||
func (handle *Handle) GetType() HandleType {
|
func (handle *Handle) GetType() HandleType {
|
||||||
return 0
|
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
|
// llgo:link (*Handle).GetData C.uv_handle_get_data
|
||||||
func (handle *Handle) GetData() c.Pointer {
|
func (handle *Handle) GetData() c.Pointer {
|
||||||
return nil
|
return nil
|
||||||
@@ -217,21 +204,6 @@ func (handle *Handle) Fileno(fd *OsFd) c.Int {
|
|||||||
return 0
|
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
|
//go:linkname Pipe C.uv_pipe
|
||||||
func Pipe(fds [2]File, readFlags c.Int, writeFlags c.Int) c.Int {
|
func Pipe(fds [2]File, readFlags c.Int, writeFlags c.Int) c.Int {
|
||||||
return 0
|
return 0
|
||||||
@@ -242,6 +214,11 @@ func Socketpair(_type c.Int, protocol c.Int, socketVector [2]OsSock, flag0 c.Int
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// llgo:link (*Handle).IsClosing C.uv_is_closing
|
||||||
|
func (handle *Handle) IsClosing() c.Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
|
|
||||||
/* Req related function and method */
|
/* Req related function and method */
|
||||||
@@ -249,15 +226,12 @@ func Socketpair(_type c.Int, protocol c.Int, socketVector [2]OsSock, flag0 c.Int
|
|||||||
//go:linkname ReqSize C.uv_req_size
|
//go:linkname ReqSize C.uv_req_size
|
||||||
func ReqSize(reqType ReqType) uintptr
|
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
|
// llgo:link (*Req).GetData C.uv_req_get_data
|
||||||
func (req *Req) GetData() c.Pointer {
|
func (req *Req) GetData() c.Pointer {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// llgo:link (*Req).SetData C.uv_req_set_data
|
// llgo:link (*Req).SetData C.uv_handle_set_data
|
||||||
func (req *Req) SetData(data c.Pointer) {}
|
func (req *Req) SetData(data c.Pointer) {}
|
||||||
|
|
||||||
// llgo:link (*Req).GetType C.uv_req_get_type
|
// llgo:link (*Req).GetType C.uv_req_get_type
|
||||||
@@ -265,10 +239,8 @@ func (req *Req) GetType() ReqType {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// llgo:link (*Req).Cancel C.uv_cancel
|
//go:linkname TypeName C.uv_req_type_name
|
||||||
func (req *Req) Cancel() c.Int {
|
func TypeName(reqType ReqType) *c.Char
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
|
|
||||||
@@ -334,11 +306,6 @@ func (stream *Stream) SetBlocking(blocking c.Int) c.Int {
|
|||||||
return 0
|
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 */
|
||||||
@@ -389,11 +356,6 @@ 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
|
||||||
|
|
||||||
@@ -467,6 +429,9 @@ 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
|
||||||
@@ -497,13 +462,8 @@ 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
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
/* Handle types. */
|
/* Handle types. */
|
||||||
|
|
||||||
type Signal struct {
|
type Signal struct {
|
||||||
Unused [152]byte
|
Unused [0]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
@@ -26,17 +26,8 @@ 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
|
||||||
|
|
||||||
// llgo:link (*Signal).Start C.uv_signal_start
|
//go:linkname SignalStart C.uv_signal_start
|
||||||
func (handle *Signal) Start(cb SignalCb, signum c.Int) c.Int {
|
func SignalStart(handle *Signal, cb SignalCb, signum c.Int) c.Int
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Signal).StartOneshot C.uv_signal_start_oneshot
|
//go:linkname SignalStartOneshot C.uv_signal_start_oneshot
|
||||||
func (handle *Signal) StartOneshot(cb SignalCb, signum c.Int) c.Int {
|
func SignalStartOneshot(handle *Signal, 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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,78 +0,0 @@
|
|||||||
package libuv
|
|
||||||
|
|
||||||
import (
|
|
||||||
_ "unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Thread struct {
|
|
||||||
Unused [8]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type ThreadOptions struct {
|
|
||||||
flags c.Uint
|
|
||||||
stackSize uintptr
|
|
||||||
}
|
|
||||||
|
|
||||||
type Work struct {
|
|
||||||
Unused [128]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------
|
|
||||||
|
|
||||||
/* Function type */
|
|
||||||
|
|
||||||
// llgo:type C
|
|
||||||
type ThreadCb func(arg c.Pointer)
|
|
||||||
|
|
||||||
//llgo:type C
|
|
||||||
type WorkCb func(req *Work)
|
|
||||||
|
|
||||||
//llgo:type C
|
|
||||||
type AfterWorkCb func(req *Work, status c.Int)
|
|
||||||
|
|
||||||
// ----------------------------------------------
|
|
||||||
|
|
||||||
/* Thread related functions and method. */
|
|
||||||
|
|
||||||
//go:linkname ThreadEqual C.uv_thread_equal
|
|
||||||
func ThreadEqual(t1 *Thread, t2 *Thread) c.Int
|
|
||||||
|
|
||||||
//go:linkname ThreadGetCPU C.uv_thread_getcpu
|
|
||||||
func ThreadGetCPU() c.Int
|
|
||||||
|
|
||||||
//go:linkname ThreadSelf C.uv_thread_self
|
|
||||||
func ThreadSelf() Thread
|
|
||||||
|
|
||||||
// llgo:link (*Thread).Create C.uv_thread_create
|
|
||||||
func (t *Thread) Create(entry ThreadCb, arg c.Pointer) c.Int {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Thread).CreateEx C.uv_thread_create_ex
|
|
||||||
func (t *Thread) CreateEx(entry ThreadCb, params *ThreadOptions, arg c.Pointer) c.Int {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Thread).Join C.uv_thread_join
|
|
||||||
func (t *Thread) Join() c.Int {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Thread).SetAffinity C.uv_thread_set_affinity
|
|
||||||
func (t *Thread) SetAffinity(cpuMask *c.Char, oldMask *c.Char, maskSize uintptr) c.Int {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// llgo:link (*Thread).GetAffinity C.uv_thread_get_affinity
|
|
||||||
func (t *Thread) GetAffinity(cpuMask *c.Char, maskSize uintptr) c.Int {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------
|
|
||||||
|
|
||||||
/* Work related functions and method. */
|
|
||||||
|
|
||||||
//go:linkname QueueWork C.uv_queue_work
|
|
||||||
func QueueWork(loop *Loop, req *Work, workCb WorkCb, afterWorkCb AfterWorkCb) c.Int
|
|
||||||
@@ -12,12 +12,12 @@ import (
|
|||||||
|
|
||||||
// TODO(spongehah): Timer
|
// TODO(spongehah): Timer
|
||||||
type Timer struct {
|
type Timer struct {
|
||||||
Unused [152]byte
|
Unused [0]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
|
|
||||||
// llgo:type C
|
// llgo:type Cgit
|
||||||
type TimerCb func(timer *Timer)
|
type TimerCb func(timer *Timer)
|
||||||
|
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
@@ -28,7 +28,7 @@ type TimerCb func(timer *Timer)
|
|||||||
func InitTimer(loop *Loop, timer *Timer) c.Int
|
func InitTimer(loop *Loop, timer *Timer) c.Int
|
||||||
|
|
||||||
// llgo:link (*Timer).Start C.uv_timer_start
|
// llgo:link (*Timer).Start C.uv_timer_start
|
||||||
func (timer *Timer) Start(cb TimerCb, timeoutMs uint64, repeat uint64) c.Int {
|
func (timer *Timer) Start(cb TimerCb, timeout uint64, repeat uint64) c.Int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ func coroutineFunc(L *lua.State) c.Int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
L := lua.Newstate__1()
|
L := lua.Newstate()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
|
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ func coroutineFunc(L *lua.State) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
L := lua.Newstate__1()
|
L := lua.Newstate()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
|
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
|
|||||||
@@ -1,72 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/c/lua"
|
|
||||||
)
|
|
||||||
|
|
||||||
func countdownContinue(L *lua.State, status c.Int, ctx lua.KContext) c.Int {
|
|
||||||
return countdown(L)
|
|
||||||
}
|
|
||||||
|
|
||||||
func countdown(L *lua.State) c.Int {
|
|
||||||
arg := L.Tointeger(lua.Upvalueindex(1))
|
|
||||||
c.Printf(c.Str("resume called with %d\n"), arg)
|
|
||||||
if arg > 0 {
|
|
||||||
L.Pushinteger(arg - 1)
|
|
||||||
L.Replace(lua.Upvalueindex(1))
|
|
||||||
L.Pushinteger(arg)
|
|
||||||
return L.Yieldk(1, c.Pointer(uintptr(0)), countdownContinue)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func createCountdown(L *lua.State) c.Int {
|
|
||||||
max := L.Checkinteger(1)
|
|
||||||
L.Pushinteger(max)
|
|
||||||
L.Pushcclosure(countdown, 1)
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
L := lua.Newstate__1()
|
|
||||||
L.Openlibs()
|
|
||||||
defer L.Close()
|
|
||||||
L.Register(c.Str("create_countdown"), createCountdown)
|
|
||||||
|
|
||||||
testcode := c.Str(`
|
|
||||||
local countdown = create_countdown(5)
|
|
||||||
local co = coroutine.create(countdown)
|
|
||||||
while true do
|
|
||||||
local success, value = coroutine.resume(co)
|
|
||||||
if not success then
|
|
||||||
print('Error:', value)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
if value == nil then break end
|
|
||||||
print('Lua received:', value)
|
|
||||||
end
|
|
||||||
print('Countdown finished');
|
|
||||||
`)
|
|
||||||
|
|
||||||
if L.Dostring(testcode) != lua.OK {
|
|
||||||
c.Printf(c.Str("Error: %s\n"), L.Tostring(-1))
|
|
||||||
}
|
|
||||||
|
|
||||||
L.Openlibs()
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Expected output:
|
|
||||||
resume called with 5
|
|
||||||
Lua received: 5
|
|
||||||
resume called with 4
|
|
||||||
Lua received: 4
|
|
||||||
resume called with 3
|
|
||||||
Lua received: 3
|
|
||||||
resume called with 2
|
|
||||||
Lua received: 2
|
|
||||||
resume called with 1
|
|
||||||
Lua received: 1
|
|
||||||
resume called with 0
|
|
||||||
Countdown finished
|
|
||||||
*/
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/c/lua"
|
|
||||||
)
|
|
||||||
|
|
||||||
func triggerError(L *lua.State) c.Int {
|
|
||||||
L.Pushstring(c.Str("This is an error triggered"))
|
|
||||||
return L.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
func triggerFormatError(L *lua.State) c.Int {
|
|
||||||
return L.LError(c.Str("This is an error code:(%d)"), 42)
|
|
||||||
}
|
|
||||||
|
|
||||||
func customPanic(L *lua.State) c.Int {
|
|
||||||
msg := L.Tostring(-1)
|
|
||||||
c.Printf(c.Str("Pani'c: %s\n"), msg)
|
|
||||||
os.Exit(1)
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
L := lua.Newstate__1()
|
|
||||||
defer L.Close()
|
|
||||||
|
|
||||||
L.Openlibs()
|
|
||||||
|
|
||||||
L.Atpanic(customPanic)
|
|
||||||
|
|
||||||
L.Register(c.Str("trigger_error"), triggerError)
|
|
||||||
L.Register(c.Str("trigger_format_error"), triggerFormatError)
|
|
||||||
|
|
||||||
c.Printf(c.Str("1. error (protected):\n"))
|
|
||||||
L.Getglobal(c.Str("trigger_error"))
|
|
||||||
if L.Pcall(0, 0, 0) != lua.OK {
|
|
||||||
c.Printf(c.Str("Error: %s\n"), L.Tostring(-1))
|
|
||||||
L.Pop(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Printf(c.Str("2. format_error (protected):\n"))
|
|
||||||
L.Getglobal(c.Str("trigger_format_error"))
|
|
||||||
if L.Pcall(0, 0, 0) != lua.OK {
|
|
||||||
c.Printf(c.Str("Error: %s\n"), L.Tostring(-1))
|
|
||||||
L.Pop(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Printf(c.Str("3. Unprotected call (panic):\n"))
|
|
||||||
L.Getglobal(c.Str("trigger_error"))
|
|
||||||
// This will trigger unprotected panic and catch by customPanic
|
|
||||||
L.Call(0, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Expected output:
|
|
||||||
1. error (protected):
|
|
||||||
Error: This is an error triggered
|
|
||||||
2. format_error (protected):
|
|
||||||
Error: This is an error code:(42)
|
|
||||||
3. Unprotected call (panic):
|
|
||||||
Panic: This is an error triggered
|
|
||||||
*/
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/c/lua"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Hook(L *lua.State, ar *lua.Debug) {
|
|
||||||
L.Getinfo(c.Str("nSl"), ar)
|
|
||||||
c.Printf(c.Str("Hook called:"))
|
|
||||||
if name := ar.Name; name != nil {
|
|
||||||
c.Printf(c.Str("name: %s,"), name)
|
|
||||||
}
|
|
||||||
if what := ar.What; what != nil {
|
|
||||||
c.Printf(c.Str("what: %s,"), what)
|
|
||||||
}
|
|
||||||
c.Printf(c.Str("source: %s,"), c.Pointer(unsafe.SliceData(ar.ShortSrc[:])))
|
|
||||||
c.Printf(c.Str("line: %d\n"), ar.Currentline)
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
L := lua.Newstate__1()
|
|
||||||
defer L.Close()
|
|
||||||
L.Openlibs()
|
|
||||||
|
|
||||||
L.Sethook(Hook, lua.MASKLINE, 0)
|
|
||||||
|
|
||||||
code :=
|
|
||||||
`function hello(name)
|
|
||||||
print('Hello, ' .. name .. '!')
|
|
||||||
end
|
|
||||||
hello('llgo')`
|
|
||||||
if res := L.Dostring(c.Str(code)); res != lua.OK {
|
|
||||||
c.Printf(c.Str("error: %s\n"), L.Tostring(-1))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Expected output:
|
|
||||||
Hook called:what: main,source: [string "function hello(name) ..."],line: 3
|
|
||||||
Hook called:what: main,source: [string "function hello(name) ..."],line: 1
|
|
||||||
Hook called:what: main,source: [string "function hello(name) ..."],line: 4
|
|
||||||
Hook called:name: hello,what: Lua,source: [string "function hello(name) ..."],line: 2
|
|
||||||
Hello, llgo!
|
|
||||||
Hook called:name: hello,what: Lua,source: [string "function hello(name) ..."],line: 3
|
|
||||||
*/
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/c/lua"
|
|
||||||
)
|
|
||||||
|
|
||||||
func reader(L *lua.State, data c.Pointer, size *c.Ulong) *c.Char {
|
|
||||||
file := (*os.File)(data)
|
|
||||||
|
|
||||||
fileInfo, err := file.Stat()
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
fileSize := fileInfo.Size()
|
|
||||||
|
|
||||||
buffer := make([]byte, fileSize)
|
|
||||||
bytesRead, err := file.Read(buffer)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
*size = c.Ulong(bytesRead)
|
|
||||||
|
|
||||||
if bytesRead > 0 {
|
|
||||||
return (*c.Char)(unsafe.Pointer(unsafe.SliceData(buffer)))
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
L := lua.Newstate__1()
|
|
||||||
defer L.Close()
|
|
||||||
L.Openlibs()
|
|
||||||
|
|
||||||
file, err := os.Open("../llgofunc.luac")
|
|
||||||
if err != nil {
|
|
||||||
c.Printf(c.Str("Failed to open file for reading\n"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
if L.Load(reader, c.Pointer(file), c.Str("greet"), nil) != lua.OK {
|
|
||||||
c.Printf(c.Str("Failed to dump Lua function\n"))
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Printf(c.Str("Stack size before call: %d\n"), L.Gettop())
|
|
||||||
c.Printf(c.Str("Top element type after call: %s\n"), L.Typename(L.Type(-1)))
|
|
||||||
|
|
||||||
L.Pushstring(c.Str("World"))
|
|
||||||
if L.Pcall(1, 1, 0) != lua.OK {
|
|
||||||
c.Printf(c.Str("Failed to call function: %s\n"))
|
|
||||||
}
|
|
||||||
|
|
||||||
if L.Isstring(-1) != 0 {
|
|
||||||
c.Printf(c.Str("Result: %s\n"), L.Tostring(-1))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Expected output:
|
|
||||||
Stack size before call: 1
|
|
||||||
Top element type after call: function
|
|
||||||
Result: Hello, World!
|
|
||||||
*/
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/c/lua"
|
|
||||||
)
|
|
||||||
|
|
||||||
func writer(L *lua.State, p c.Pointer, sz c.Ulong, ud c.Pointer) c.Int {
|
|
||||||
file := (*os.File)(ud)
|
|
||||||
data := unsafe.Slice((*byte)(p), sz)
|
|
||||||
|
|
||||||
n, err := file.Write(data)
|
|
||||||
if err != nil || n != int(sz) {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return lua.OK
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
L := lua.Newstate__1()
|
|
||||||
defer L.Close()
|
|
||||||
L.Openlibs()
|
|
||||||
|
|
||||||
if res := L.Loadstring(c.Str(`
|
|
||||||
function greet(name)
|
|
||||||
return 'Hello, ' .. name .. '!'
|
|
||||||
end
|
|
||||||
return greet
|
|
||||||
`)); res != lua.OK {
|
|
||||||
c.Printf(c.Str("error: %s\n"), L.Tostring(-1))
|
|
||||||
}
|
|
||||||
|
|
||||||
if res := L.Pcall(0, 1, 0); res != lua.OK {
|
|
||||||
c.Printf(c.Str("error: %s\n"), L.Tostring(-1))
|
|
||||||
}
|
|
||||||
|
|
||||||
if !L.Isfunction(-1) {
|
|
||||||
c.Printf(c.Str("Expected a function, but got %s"), L.Typename(L.Type(-1)))
|
|
||||||
}
|
|
||||||
|
|
||||||
file, err := os.Create("../llgofunc.luac")
|
|
||||||
if err != nil {
|
|
||||||
c.Printf(c.Str("Failed to open file for writing\n"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
if L.Dump(writer, c.Pointer(file), 0) != lua.OK {
|
|
||||||
c.Printf(c.Str("Failed to dump Lua function\n"))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
L := lua.Newstate__1()
|
L := lua.Newstate()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
if res := L.Loadstring(c.Str("function doubleNumber(x) ! return x * 2 end")); res != lua.OK {
|
if res := L.Loadstring(c.Str("function doubleNumber(x) ! return x * 2 end")); res != lua.OK {
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
_ "unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/c/lua"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetData(L *lua.State) c.Int {
|
|
||||||
extra := (*int)(L.Getextraspace())
|
|
||||||
L.Pushfstring(c.Str("Stored integer is: %d"), *extra)
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
L := lua.Newstate__1()
|
|
||||||
defer L.Close()
|
|
||||||
|
|
||||||
L.Openlibs()
|
|
||||||
|
|
||||||
extra := (*int)(L.Getextraspace())
|
|
||||||
*extra = 42
|
|
||||||
|
|
||||||
difference := uintptr(unsafe.Pointer(L)) - uintptr(L.Getextraspace())
|
|
||||||
if difference == unsafe.Sizeof(uintptr(0)) {
|
|
||||||
c.Printf(c.Str("Extra space is pointer size\n"), unsafe.Sizeof(uintptr(0)))
|
|
||||||
}
|
|
||||||
|
|
||||||
L.Pushcfunction(GetData)
|
|
||||||
L.Setglobal(c.Str("GetData"))
|
|
||||||
|
|
||||||
if L.Dostring(c.Str("print(GetData())")) != lua.OK {
|
|
||||||
c.Printf(c.Str("Error: %s\n"), L.Tostring(-1))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Expected output:
|
|
||||||
Extra space is pointer size
|
|
||||||
Stored integer is: 42
|
|
||||||
*/
|
|
||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
L := lua.Newstate__1()
|
L := lua.Newstate()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
|
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
L := lua.Newstate__1()
|
L := lua.Newstate()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
|
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
L := lua.Newstate__1()
|
L := lua.Newstate()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
|
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
L := lua.Newstate__1()
|
L := lua.Newstate()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
if res := L.Dostring(c.Str("print('hello world')")); res != lua.OK {
|
if res := L.Dostring(c.Str("print('hello world')")); res != lua.OK {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
L := lua.Newstate__1()
|
L := lua.Newstate()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
|
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ func printStack(L *lua.State, message string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
L := lua.Newstate__1()
|
L := lua.Newstate()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
|
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ func printStack(L *lua.State, stateName *c.Char) {
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Create a new Lua state and open libraries
|
// Create a new Lua state and open libraries
|
||||||
L := lua.Newstate__1()
|
L := lua.Newstate()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ func main() {
|
|||||||
printStack(L, c.Str("L1"))
|
printStack(L, c.Str("L1"))
|
||||||
|
|
||||||
// Create a second Lua state
|
// Create a second Lua state
|
||||||
L1 := lua.Newstate__1()
|
L1 := lua.Newstate()
|
||||||
defer L1.Close()
|
defer L1.Close()
|
||||||
|
|
||||||
// Move two elements to the new state
|
// Move two elements to the new state
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/c/lua"
|
|
||||||
)
|
|
||||||
|
|
||||||
func alloc(ud c.Pointer, ptr c.Pointer, osize c.Ulong, nsize c.Ulong) c.Pointer {
|
|
||||||
if nsize == 0 {
|
|
||||||
c.Free(ptr)
|
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
return c.Realloc(ptr, uintptr(nsize))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
L := lua.Newstate__0(alloc, nil)
|
|
||||||
defer L.Close()
|
|
||||||
L.Openlibs()
|
|
||||||
if res := L.Dostring(c.Str("print('new state success')")); res != lua.OK {
|
|
||||||
println("newstate error")
|
|
||||||
}
|
|
||||||
|
|
||||||
allocf := L.Getallocf(nil)
|
|
||||||
L.Setallocf(allocf, nil)
|
|
||||||
|
|
||||||
if res := L.Dostring(c.Str("print('set newstate success')")); res != lua.OK {
|
|
||||||
println("set newstate error")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Expected output:
|
|
||||||
new state success
|
|
||||||
set newstate success
|
|
||||||
*/
|
|
||||||
@@ -1,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/lua"
|
"github.com/goplus/llgo/c/lua"
|
||||||
)
|
)
|
||||||
@@ -10,91 +8,53 @@ import (
|
|||||||
func printTable(L *lua.State) {
|
func printTable(L *lua.State) {
|
||||||
L.Pushnil()
|
L.Pushnil()
|
||||||
for L.Next(-2) != 0 {
|
for L.Next(-2) != 0 {
|
||||||
value := L.Tostring(-1)
|
|
||||||
switch L.Type(-2) {
|
|
||||||
case lua.STRING:
|
|
||||||
key := L.Tostring(-2)
|
key := L.Tostring(-2)
|
||||||
|
value := L.Tostring(-1)
|
||||||
c.Printf(c.Str("%s - %s\n"), key, value)
|
c.Printf(c.Str("%s - %s\n"), key, value)
|
||||||
case lua.NUMBER:
|
|
||||||
key := L.Tonumber(-2)
|
|
||||||
c.Printf(c.Str("[%.0f] - %s\n"), key, value)
|
|
||||||
case lua.LIGHTUSERDATA:
|
|
||||||
c.Printf(c.Str("[pointer] - %s\n"), value)
|
|
||||||
default:
|
|
||||||
c.Printf(c.Str("unknown key type %s %d\n"), L.Typename(-2), L.Type(-2))
|
|
||||||
}
|
|
||||||
L.Pop(1)
|
L.Pop(1)
|
||||||
}
|
}
|
||||||
L.Pop(1)
|
L.Pop(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
L := lua.Newstate__1()
|
L := lua.Newstate()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
|
|
||||||
L.Openlibs()
|
L.Openlibs()
|
||||||
|
|
||||||
L.Newtable()
|
L.Newtable()
|
||||||
|
|
||||||
// set table name:John
|
|
||||||
L.Pushstring(c.Str("name"))
|
L.Pushstring(c.Str("name"))
|
||||||
L.Pushstring(c.Str("John"))
|
L.Pushstring(c.Str("John"))
|
||||||
L.Settable(-3)
|
L.Settable(-3)
|
||||||
|
|
||||||
// set table age:30
|
|
||||||
L.Pushstring(c.Str("age"))
|
L.Pushstring(c.Str("age"))
|
||||||
L.Pushnumber(30)
|
L.Pushnumber(30)
|
||||||
L.Settable(-3)
|
L.Settable(-3)
|
||||||
|
|
||||||
// set table field fullname:John Doe
|
|
||||||
L.Pushstring(c.Str("John Doe"))
|
L.Pushstring(c.Str("John Doe"))
|
||||||
L.Setfield(-2, c.Str("fullname"))
|
L.Setfield(-2, c.Str("fullname"))
|
||||||
|
|
||||||
// set index field
|
|
||||||
L.Pushinteger(123)
|
|
||||||
L.Seti(-2, c.Int(1))
|
|
||||||
|
|
||||||
// set pointer key field
|
|
||||||
pointerKey := c.AllocaCStr("pointer key")
|
|
||||||
L.Pushstring(c.Str("pointer value"))
|
|
||||||
L.Rawsetp(-2, unsafe.Pointer(pointerKey))
|
|
||||||
|
|
||||||
// get field by Getfield
|
|
||||||
L.Getfield(-1, c.Str("name"))
|
L.Getfield(-1, c.Str("name"))
|
||||||
c.Printf(c.Str("name: %s\n"), L.Tostring(-1))
|
c.Printf(c.Str("%s\n"), L.Tostring(-1))
|
||||||
L.Pop(1)
|
L.Pop(1)
|
||||||
|
|
||||||
// get field by Rawget
|
|
||||||
L.Pushstring(c.Str("fullname"))
|
|
||||||
L.Rawget(-2)
|
|
||||||
c.Printf(c.Str("fullname: %s\n"), L.Tostring(-1))
|
|
||||||
L.Pop(1)
|
|
||||||
|
|
||||||
// get field by Gettable
|
|
||||||
L.Pushstring(c.Str("age"))
|
L.Pushstring(c.Str("age"))
|
||||||
L.Gettable(-2)
|
L.Gettable(-2)
|
||||||
age := int(L.Tonumber(-1))
|
age := int(L.Tonumber(-1))
|
||||||
c.Printf(c.Str("Age: %d\n"), age)
|
c.Printf(c.Str("Age: %d\n"), age)
|
||||||
L.Pop(1)
|
L.Pop(1)
|
||||||
|
|
||||||
// get index field
|
|
||||||
L.Geti(-1, c.Int(1))
|
|
||||||
c.Printf(c.Str("Index[%d] value: %d\n"), 1, L.Tointeger(-1))
|
|
||||||
L.Pop(1)
|
|
||||||
|
|
||||||
c.Printf(c.Str("All entries in the table:\n"))
|
c.Printf(c.Str("All entries in the table:\n"))
|
||||||
printTable(L)
|
printTable(L)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expected output:
|
/* Expected output:
|
||||||
name: John
|
John
|
||||||
fullname: John Doe
|
|
||||||
Age: 30
|
Age: 30
|
||||||
Index[1] value: 123
|
|
||||||
All entries in the table:
|
All entries in the table:
|
||||||
[1] - 123
|
|
||||||
name - John
|
|
||||||
[pointer] - pointer value
|
|
||||||
fullname - John Doe
|
|
||||||
age - 30.0
|
age - 30.0
|
||||||
|
fullname - John Doe
|
||||||
|
name - John
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/c/lua"
|
|
||||||
)
|
|
||||||
|
|
||||||
func pushThread(state *lua.State, name string) {
|
|
||||||
isMain := state.Pushthread()
|
|
||||||
if isMain != 0 {
|
|
||||||
c.Printf(c.Str("%s Thread is main\n"), c.AllocaCStr(name))
|
|
||||||
} else {
|
|
||||||
c.Printf(c.Str("%s Thread is not main\n"), c.AllocaCStr(name))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
L := lua.Newstate__1()
|
|
||||||
defer L.Close()
|
|
||||||
|
|
||||||
L.Openlibs()
|
|
||||||
pushThread(L, "main")
|
|
||||||
L.Pop(1)
|
|
||||||
newThread := L.Newthread()
|
|
||||||
pushThread(newThread, "newthread")
|
|
||||||
|
|
||||||
state := newThread.Tothread(-1)
|
|
||||||
if newThread == state {
|
|
||||||
c.Printf(c.Str("Successfully retrieved thread from stack\n"))
|
|
||||||
}
|
|
||||||
status := state.Status()
|
|
||||||
c.Printf(c.Str("New thread status: %d"), status)
|
|
||||||
|
|
||||||
if L.Closethread(newThread) != lua.OK {
|
|
||||||
println("Failed to close thread status %d", state.Status())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Expected output:
|
|
||||||
main Thread is main
|
|
||||||
newthread Thread is not main
|
|
||||||
Successfully retrieved thread from stack
|
|
||||||
New thread status: 0
|
|
||||||
*/
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/c/lua"
|
|
||||||
)
|
|
||||||
|
|
||||||
type lightdata struct {
|
|
||||||
value int
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
L := lua.Newstate__1()
|
|
||||||
defer L.Close()
|
|
||||||
L.Openlibs()
|
|
||||||
|
|
||||||
data := L.Newuserdata(unsafe.Sizeof(0))
|
|
||||||
*((*int)(data)) = 42
|
|
||||||
L.Setglobal(c.Str("data"))
|
|
||||||
|
|
||||||
light := &lightdata{value: 24}
|
|
||||||
L.Pushlightuserdata(unsafe.Pointer(light))
|
|
||||||
L.Setglobal(c.Str("lightdata"))
|
|
||||||
|
|
||||||
L.Getglobal(c.Str("data"))
|
|
||||||
if L.Isuserdata(-1) != 0 {
|
|
||||||
data := L.Touserdata(-1)
|
|
||||||
c.Printf(c.Str("userdata %d\n"), *(*int)(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
L.Getglobal(c.Str("lightdata"))
|
|
||||||
if L.Islightuserdata(-1) {
|
|
||||||
light := (*lightdata)(L.Touserdata(-1))
|
|
||||||
c.Printf(c.Str("lightdata %d\n"), light.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Expected output:
|
|
||||||
userdata 42
|
|
||||||
lightdata 24
|
|
||||||
*/
|
|
||||||
@@ -14,15 +14,6 @@ import (
|
|||||||
|
|
||||||
// /* key, in the registry, for table of preloaded loaders */
|
// /* key, in the registry, for table of preloaded loaders */
|
||||||
|
|
||||||
// llgo:link (*State).Checkinteger C.luaL_checkinteger
|
|
||||||
func (L *State) Checkinteger(arg c.Int) Integer { return 0 }
|
|
||||||
|
|
||||||
// llgo:link (*State).Checknumber C.luaL_checknumber
|
|
||||||
func (L *State) Checknumber(arg c.Int) Number { return 0 }
|
|
||||||
|
|
||||||
// llgo:link (*State).LError C.luaL_error
|
|
||||||
func (L *State) LError(format *c.Char, __llgo_va_list ...any) c.Int { return 0 }
|
|
||||||
|
|
||||||
// /* predefined references */
|
// /* predefined references */
|
||||||
|
|
||||||
// llgo:link (*State).Loadfilex C.luaL_loadfilex
|
// llgo:link (*State).Loadfilex C.luaL_loadfilex
|
||||||
@@ -33,8 +24,8 @@ func (L *State) Loadfile(filename *c.Char) c.Int { return L.Loadfilex(filename,
|
|||||||
// llgo:link (*State).Loadstring C.luaL_loadstring
|
// llgo:link (*State).Loadstring C.luaL_loadstring
|
||||||
func (L *State) Loadstring(s *c.Char) c.Int { return 0 }
|
func (L *State) Loadstring(s *c.Char) c.Int { return 0 }
|
||||||
|
|
||||||
//go:linkname Newstate__1 C.luaL_newstate
|
//go:linkname Newstate C.luaL_newstate
|
||||||
func Newstate__1() *State
|
func Newstate() *State
|
||||||
|
|
||||||
// /*
|
// /*
|
||||||
// ** ===============================================================
|
// ** ===============================================================
|
||||||
|
|||||||
491
c/lua/lua.go
491
c/lua/lua.go
@@ -10,28 +10,20 @@ const (
|
|||||||
LLGoPackage = "link: $(pkg-config --libs lua); -llua -lm"
|
LLGoPackage = "link: $(pkg-config --libs lua); -llua -lm"
|
||||||
)
|
)
|
||||||
|
|
||||||
/* mark for precompiled code ('<esc>Lua') */
|
// /* mark for precompiled code ('<esc>Lua') */
|
||||||
|
|
||||||
/* option for multiple returns in 'lua_pcall' and 'lua_call' */
|
// /* option for multiple returns in 'lua_pcall' and 'lua_call' */
|
||||||
const (
|
const (
|
||||||
MULTRET = -1
|
MULTRET = -1
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
// /*
|
||||||
* Pseudo-indices
|
// ** Pseudo-indices
|
||||||
* (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty
|
// ** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty
|
||||||
* space after that to help overflow detection)
|
// ** space after that to help overflow detection)
|
||||||
*/
|
// */
|
||||||
|
|
||||||
const (
|
// /* thread status */
|
||||||
REGISTRYINDEX = -MAXSTACK - 1000
|
|
||||||
)
|
|
||||||
|
|
||||||
func Upvalueindex(i c.Int) c.Int {
|
|
||||||
return c.Int(REGISTRYINDEX) - i
|
|
||||||
}
|
|
||||||
|
|
||||||
/* thread status */
|
|
||||||
const (
|
const (
|
||||||
OK = 0
|
OK = 0
|
||||||
YIELD = 1
|
YIELD = 1
|
||||||
@@ -45,9 +37,9 @@ type State struct {
|
|||||||
Unused [8]byte
|
Unused [8]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// /*
|
||||||
* basic types
|
// ** basic types
|
||||||
*/
|
// */
|
||||||
const (
|
const (
|
||||||
NONE c.Int = -1
|
NONE c.Int = -1
|
||||||
NIL c.Int = 0
|
NIL c.Int = 0
|
||||||
@@ -59,112 +51,113 @@ const (
|
|||||||
FUNCTION c.Int = 6
|
FUNCTION c.Int = 6
|
||||||
USERDATA c.Int = 7
|
USERDATA c.Int = 7
|
||||||
THREAD c.Int = 8
|
THREAD c.Int = 8
|
||||||
NUMTYPES c.Int = 9
|
UMTYPES c.Int = 9
|
||||||
)
|
)
|
||||||
|
|
||||||
/* minimum Lua stack available to a C function */
|
// /* minimum Lua stack available to a C function */
|
||||||
const (
|
const (
|
||||||
MINSTACK = 20
|
MINSTACK = 20
|
||||||
)
|
)
|
||||||
|
|
||||||
/* predefined values in the registry */
|
// /* predefined values in the registry */
|
||||||
const (
|
const (
|
||||||
RIDX_MAINTHREAD = 1
|
RIDX_MAINTHREAD = 1
|
||||||
RIDX_GLOBALS = 2
|
RIDX_GLOBALS = 2
|
||||||
RIDX_LAST = RIDX_GLOBALS
|
RIDX_LAST = RIDX_GLOBALS
|
||||||
)
|
)
|
||||||
|
|
||||||
/* type of numbers in Lua */
|
// /* type of numbers in Lua */
|
||||||
type Number = c.Double
|
type Number = c.Double
|
||||||
|
|
||||||
/* type for integer functions */
|
// /* type for integer functions */
|
||||||
|
// TODO(zzy):consider dynamic size
|
||||||
|
|
||||||
type Integer = c.Int
|
type Integer = c.Int
|
||||||
|
|
||||||
/* unsigned integer type */
|
// /* unsigned integer type */
|
||||||
type Unsigned = c.Uint
|
type Unsigned = c.Uint
|
||||||
|
|
||||||
/* type for continuation-function contexts */
|
// /* type for continuation-function contexts */
|
||||||
type KContext = c.Pointer
|
type KContext = c.Pointer
|
||||||
|
|
||||||
/*
|
// /*
|
||||||
* Type for C functions registered with Lua
|
// ** Type for C functions registered with Lua
|
||||||
*/
|
// */
|
||||||
|
|
||||||
// llgo:type C
|
// llgo:type C
|
||||||
type CFunction func(L *State) c.Int
|
type CFunction func(L *State) c.Int
|
||||||
|
|
||||||
/*
|
// /*
|
||||||
* Type for continuation functions
|
// ** Type for continuation functions
|
||||||
*/
|
// */
|
||||||
|
|
||||||
// llgo:type C
|
// TODO(zzy): KFunction does not currently support
|
||||||
type KFunction func(L *State, status c.Int, ctx KContext) c.Int
|
type KFunction func(L *State, status c.Int, ctx KContext) c.Int
|
||||||
|
|
||||||
/*
|
// /*
|
||||||
* Type for functions that read/write blocks when loading/dumping Lua chunks
|
// ** Type for functions that read/write blocks when loading/dumping Lua chunks
|
||||||
*/
|
// */
|
||||||
|
|
||||||
// llgo:type C
|
// typedef const char * (*lua_Reader) (State *L, void *ud, size_t *sz);
|
||||||
type Reader func(L *State, ud c.Pointer, sz *c.Ulong) *c.Char
|
// typedef int (*lua_Writer) (State *L, const void *p, size_t sz, void *ud);
|
||||||
|
|
||||||
// llgo:type C
|
// /*
|
||||||
type Writer func(L *State, p c.Pointer, sz c.Ulong, ud c.Pointer) c.Int
|
// ** Type for memory-allocation functions
|
||||||
|
// */
|
||||||
|
|
||||||
/*
|
// typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
|
||||||
* Type for memory-allocation functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
// llgo:type C
|
// /*
|
||||||
type Alloc func(ud c.Pointer, ptr c.Pointer, osize c.Ulong, nsize c.Ulong) c.Pointer
|
// ** Type for warning functions
|
||||||
|
// */
|
||||||
|
|
||||||
/*
|
// typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont);
|
||||||
* Type for warning functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
// llgo:type C
|
// /*
|
||||||
type WarnFunction func(ud c.Pointer, msg c.Char, tocont c.Int)
|
// ** Type used by the debug API to collect debug information
|
||||||
|
// */
|
||||||
|
|
||||||
/*
|
// typedef struct lua_Debug lua_Debug;
|
||||||
* Functions to be called by the debugger in specific events
|
|
||||||
*/
|
|
||||||
|
|
||||||
// llgo:type C
|
// /*
|
||||||
type Hook func(L *State, ar *Debug)
|
// ** Functions to be called by the debugger in specific events
|
||||||
|
// */
|
||||||
|
|
||||||
/*
|
// typedef void (*lua_Hook) (State *L, lua_Debug *ar);
|
||||||
* RCS ident string
|
|
||||||
*/
|
// /*
|
||||||
|
// ** generic extra include file
|
||||||
|
// */
|
||||||
|
|
||||||
|
// #if defined(LUA_USER_H)
|
||||||
|
// #include LUA_USER_H
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// /*
|
||||||
|
// ** RCS ident string
|
||||||
|
// */
|
||||||
|
|
||||||
// extern const char lua_ident[];
|
// extern const char lua_ident[];
|
||||||
|
|
||||||
/*
|
// /*
|
||||||
** state manipulation
|
// ** state manipulation
|
||||||
*/
|
// */
|
||||||
|
|
||||||
// llgo:link (*State).Close C.lua_close
|
// llgo:link (*State).Close C.lua_close
|
||||||
func (L *State) Close() {}
|
func (L *State) Close() {}
|
||||||
|
|
||||||
// llgo:link Newstate__0 C.lua_newstate
|
// State *(lua_newstate) (lua_Alloc f, void *ud);
|
||||||
func Newstate__0(f Alloc, ud c.Pointer) *State { return nil }
|
|
||||||
|
|
||||||
// llgo:link (*State).Newthread C.lua_newthread
|
// llgo:link (*State).Newthread C.lua_newthread
|
||||||
func (L *State) Newthread() *State { return nil }
|
func (L *State) Newthread() *State { return nil }
|
||||||
|
|
||||||
// llgo:link (*State).Closethread C.lua_closethread
|
// int (lua_closethread) (State *L, State *from);
|
||||||
func (L *State) Closethread(from *State) c.Int { return 0 }
|
// int (lua_resetthread) (State *L); /* Deprecated! */
|
||||||
|
// lua_CFunction (lua_atpanic) (State *L, lua_CFunction panicf);
|
||||||
|
// lua_Number (lua_version) (State *L);
|
||||||
|
|
||||||
// llgo:link (*State).Resetthread C.lua_resetthread
|
// /*
|
||||||
func (L *State) Resetthread(from *State) c.Int { return 0 }
|
// ** basic stack manipulation
|
||||||
|
// */
|
||||||
// llgo:link (*State).Atpanic C.lua_atpanic
|
|
||||||
func (L *State) Atpanic(panicf CFunction) CFunction { return nil }
|
|
||||||
|
|
||||||
// llgo:link (*State).Version C.lua_version
|
|
||||||
func (L *State) Version() Number { return 0 }
|
|
||||||
|
|
||||||
/*
|
|
||||||
* basic stack manipulation
|
|
||||||
*/
|
|
||||||
|
|
||||||
// llgo:link (*State).Absindex C.lua_absindex
|
// llgo:link (*State).Absindex C.lua_absindex
|
||||||
func (L *State) Absindex(idx c.Int) c.Int { return 0 }
|
func (L *State) Absindex(idx c.Int) c.Int { return 0 }
|
||||||
@@ -190,9 +183,9 @@ func (L *State) Checkstack(n c.Int) c.Int { return 0 }
|
|||||||
// llgo:link (*State).Xmove C.lua_xmove
|
// llgo:link (*State).Xmove C.lua_xmove
|
||||||
func (L *State) Xmove(to *State, n c.Int) {}
|
func (L *State) Xmove(to *State, n c.Int) {}
|
||||||
|
|
||||||
/*
|
// /*
|
||||||
* access functions (stack -> C)
|
// ** access functions (stack -> C)
|
||||||
*/
|
// */
|
||||||
|
|
||||||
// llgo:link (*State).Isnumber C.lua_isnumber
|
// llgo:link (*State).Isnumber C.lua_isnumber
|
||||||
func (L *State) Isnumber(idx c.Int) c.Int { return 0 }
|
func (L *State) Isnumber(idx c.Int) c.Int { return 0 }
|
||||||
@@ -206,8 +199,7 @@ func (L *State) Iscfunction(idx c.Int) c.Int { return 0 }
|
|||||||
// llgo:link (*State).Isinteger C.lua_isinteger
|
// llgo:link (*State).Isinteger C.lua_isinteger
|
||||||
func (L *State) Isinteger(idx c.Int) c.Int { return 0 }
|
func (L *State) Isinteger(idx c.Int) c.Int { return 0 }
|
||||||
|
|
||||||
// llgo:link (*State).Isuserdata C.lua_isuserdata
|
// LUA_API int (lua_isuserdata) (State *L, int idx);
|
||||||
func (L *State) Isuserdata(idx c.Int) c.Int { return 0 }
|
|
||||||
|
|
||||||
// llgo:link (*State).Type C.lua_type
|
// llgo:link (*State).Type C.lua_type
|
||||||
func (L *State) Type(idx c.Int) c.Int { return 0 }
|
func (L *State) Type(idx c.Int) c.Int { return 0 }
|
||||||
@@ -232,23 +224,17 @@ func (L *State) Tolstring(idx c.Int, len *c.Ulong) *c.Char { return nil }
|
|||||||
// llgo:link (*State).Tocfunction C.lua_tocfunction
|
// llgo:link (*State).Tocfunction C.lua_tocfunction
|
||||||
func (L *State) Tocfunction(idx c.Int) CFunction { return nil }
|
func (L *State) Tocfunction(idx c.Int) CFunction { return nil }
|
||||||
|
|
||||||
// llgo:link (*State).Touserdata C.lua_touserdata
|
// LUA_API void *(lua_touserdata) (State *L, int idx);
|
||||||
func (L *State) Touserdata(idx c.Int) c.Pointer { return nil }
|
// LUA_API State *(lua_tothread) (State *L, int idx);
|
||||||
|
// LUA_API const void *(lua_topointer) (State *L, int idx);
|
||||||
|
|
||||||
// llgo:link (*State).Tothread C.lua_tothread
|
// /*
|
||||||
func (L *State) Tothread(idx c.Int) *State { return nil }
|
// ** Comparison and arithmetic functions
|
||||||
|
// */
|
||||||
// llgo:link (*State).Topointer C.lua_topointer
|
|
||||||
func (L *State) Topointer(idx c.Int) c.Pointer { return nil }
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Comparison and arithmetic functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* push functions (C -> stack)
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
// /*
|
||||||
|
// ** push functions (C -> stack)
|
||||||
|
// */
|
||||||
// llgo:link (*State).Pushnil C.lua_pushnil
|
// llgo:link (*State).Pushnil C.lua_pushnil
|
||||||
func (L *State) Pushnil() {}
|
func (L *State) Pushnil() {}
|
||||||
|
|
||||||
@@ -273,15 +259,12 @@ 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) {}
|
||||||
|
|
||||||
// llgo:link (*State).Pushlightuserdata C.lua_pushlightuserdata
|
//void (lua_pushlightuserdata) (State *L, void *p);
|
||||||
func (L *State) Pushlightuserdata(p c.Pointer) {}
|
//int (lua_pushthread) (State *L);
|
||||||
|
|
||||||
// llgo:link (*State).Pushthread C.lua_pushthread
|
// /*
|
||||||
func (L *State) Pushthread() c.Int { return 0 }
|
// ** get functions (Lua -> stack)
|
||||||
|
// */
|
||||||
/*
|
|
||||||
* get functions (Lua -> stack)
|
|
||||||
*/
|
|
||||||
|
|
||||||
// llgo:link (*State).Getglobal C.lua_getglobal
|
// llgo:link (*State).Getglobal C.lua_getglobal
|
||||||
func (L *State) Getglobal(name *c.Char) c.Int { return 0 }
|
func (L *State) Getglobal(name *c.Char) c.Int { return 0 }
|
||||||
@@ -292,33 +275,24 @@ 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).Geti C.lua_geti
|
// LUA_API int (lua_geti) (State *L, int idx, lua_Integer n);
|
||||||
func (L *State) Geti(idx c.Int, n Integer) c.Int { return 0 }
|
// LUA_API int (lua_rawget) (State *L, int idx);
|
||||||
|
// LUA_API int (lua_rawgeti) (State *L, int idx, lua_Integer n);
|
||||||
// llgo:link (*State).Rawget C.lua_rawget
|
// LUA_API int (lua_rawgetp) (State *L, int idx, const void *p);
|
||||||
func (L *State) Rawget(idx c.Int) c.Int { return 0 }
|
|
||||||
|
|
||||||
// llgo:link (*State).Rawgeti C.lua_rawgeti
|
|
||||||
func (L *State) Rawgeti(idx c.Int, n Integer) c.Int { return 0 }
|
|
||||||
|
|
||||||
// llgo:link (*State).Rawgetp C.lua_rawgetp
|
|
||||||
func (L *State) Rawgetp(idx c.Int, p c.Pointer) c.Int { return 0 }
|
|
||||||
|
|
||||||
// llgo:link (*State).Createtable C.lua_createtable
|
// llgo:link (*State).Createtable C.lua_createtable
|
||||||
func (L *State) Createtable(narr c.Int, nrec c.Int) {}
|
func (L *State) Createtable(narr c.Int, nrec c.Int) {}
|
||||||
|
|
||||||
// llgo:link (*State).Newuserdatauv C.lua_newuserdatauv
|
// LUA_API void *(lua_newuserdatauv) (State *L, size_t sz, int nuvalue);
|
||||||
func (L *State) Newuserdatauv(sz uintptr, nuvalue c.Int) c.Pointer { return nil }
|
|
||||||
|
|
||||||
// llgo:link (*State).Getmetatable C.lua_getmetatable
|
// llgo:link (*State).Getmetatable C.lua_getmetatable
|
||||||
func (L *State) Getmetatable(objindex c.Int) c.Int { return 0 }
|
func (L *State) Getmetatable(objindex c.Int) c.Int { return 0 }
|
||||||
|
|
||||||
// llgo:link (*State).Getiuservalue C.lua_getiuservalue
|
// LUA_API int (lua_getiuservalue) (State *L, int idx, int n);
|
||||||
func (L *State) Getiuservalue(idx c.Int, n c.Int) c.Int { return 0 }
|
|
||||||
|
|
||||||
/*
|
// /*
|
||||||
* set functions (stack -> Lua)
|
// ** set functions (stack -> Lua)
|
||||||
*/
|
// */
|
||||||
|
|
||||||
// llgo:link (*State).Setglobal C.lua_setglobal
|
// llgo:link (*State).Setglobal C.lua_setglobal
|
||||||
func (L *State) Setglobal(name *c.Char) {}
|
func (L *State) Setglobal(name *c.Char) {}
|
||||||
@@ -329,27 +303,19 @@ func (L *State) Settable(idx c.Int) {}
|
|||||||
// llgo:link (*State).Setfield C.lua_setfield
|
// llgo:link (*State).Setfield C.lua_setfield
|
||||||
func (L *State) Setfield(idx c.Int, k *c.Char) {}
|
func (L *State) Setfield(idx c.Int, k *c.Char) {}
|
||||||
|
|
||||||
// llgo:link (*State).Seti C.lua_seti
|
//void (lua_seti) (State *L, int idx, lua_Integer n);
|
||||||
func (L *State) Seti(idx c.Int, n Integer) {}
|
//void (lua_rawset) (State *L, int idx);
|
||||||
|
//void (lua_rawseti) (State *L, int idx, lua_Integer n);
|
||||||
// llgo:link (*State).Rawset C.lua_rawset
|
//void (lua_rawsetp) (State *L, int idx, const void *p);
|
||||||
func (L *State) Rawset(idx c.Int) {}
|
|
||||||
|
|
||||||
// llgo:link (*State).Rawseti C.lua_rawseti
|
|
||||||
func (L *State) Rawseti(idx c.Int, n Integer) {}
|
|
||||||
|
|
||||||
// llgo:link (*State).Rawsetp C.lua_rawsetp
|
|
||||||
func (L *State) Rawsetp(idx c.Int, p c.Pointer) {}
|
|
||||||
|
|
||||||
// llgo:link (*State).Setmetatable C.lua_setmetatable
|
// llgo:link (*State).Setmetatable C.lua_setmetatable
|
||||||
func (L *State) Setmetatable(objindex c.Int) c.Int { return 0 }
|
func (L *State) Setmetatable(objindex c.Int) c.Int { return 0 }
|
||||||
|
|
||||||
// llgo:link (*State).Setiuservalue C.lua_setiuservalue
|
//int (lua_setiuservalue) (State *L, int idx, int n);
|
||||||
func (L *State) Setiuservalue(idx c.Int, n c.Int) c.Int { return 0 }
|
|
||||||
|
|
||||||
/*
|
// /*
|
||||||
* 'load' and 'call' functions (load and run Lua code)
|
// ** 'load' and 'call' functions (load and run Lua code)
|
||||||
*/
|
// */
|
||||||
|
|
||||||
// llgo:link (*State).Callk C.lua_callk
|
// llgo:link (*State).Callk C.lua_callk
|
||||||
func (L *State) Callk(nargs c.Int, nresults c.Int, ctx KContext, k KFunction) c.Int {
|
func (L *State) Callk(nargs c.Int, nresults c.Int, ctx KContext, k KFunction) c.Int {
|
||||||
@@ -369,15 +335,13 @@ func (L *State) Pcall(nargs c.Int, nresults c.Int, errfunc c.Int) c.Int {
|
|||||||
return L.Pcallk(nargs, nresults, errfunc, nil, nil)
|
return L.Pcallk(nargs, nresults, errfunc, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// llgo:link (*State).Load C.lua_load
|
// int (lua_load) (State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode);
|
||||||
func (L *State) Load(reader Reader, dt c.Pointer, chunkname *c.Char, mode *c.Char) c.Int { return 0 }
|
|
||||||
|
|
||||||
// llgo:link (*State).Dump C.lua_dump
|
// int (lua_dump) (State *L, lua_Writer writer, void *data, int strip);
|
||||||
func (L *State) Dump(writer Writer, data c.Pointer, strip c.Int) c.Int { return 0 }
|
|
||||||
|
|
||||||
/*
|
// /*
|
||||||
* coroutine functions
|
// ** coroutine functions
|
||||||
*/
|
// */
|
||||||
|
|
||||||
// llgo:link (*State).Resume C.lua_resume
|
// llgo:link (*State).Resume C.lua_resume
|
||||||
func (L *State) Resume(from *State, narg c.Int, nres *c.Int) c.Int { return 0 }
|
func (L *State) Resume(from *State, narg c.Int, nres *c.Int) c.Int { return 0 }
|
||||||
@@ -392,19 +356,16 @@ func (L *State) Isyieldable() c.Int { return 0 }
|
|||||||
func (L *State) Yieldk(nresults c.Int, ctx KContext, k KFunction) c.Int { return 0 }
|
func (L *State) Yieldk(nresults c.Int, ctx KContext, k KFunction) c.Int { return 0 }
|
||||||
func (L *State) Yield(nresults c.Int) c.Int { return L.Yieldk(nresults, nil, nil) }
|
func (L *State) Yield(nresults c.Int) c.Int { return L.Yieldk(nresults, nil, nil) }
|
||||||
|
|
||||||
/*
|
// /*
|
||||||
* Warning-related functions
|
// ** Warning-related functions
|
||||||
*/
|
// */
|
||||||
|
|
||||||
// llgo:link (*State).Setwarnf C.lua_setwarnf
|
//void (lua_setwarnf) (State *L, lua_WarnFunction f, void *ud);
|
||||||
func (L *State) Setwarnf(f WarnFunction, ud c.Pointer) {}
|
//void (lua_warning) (State *L, const char *msg, int tocont);
|
||||||
|
|
||||||
// llgo:link (*State).Warning C.lua_warning
|
// /*
|
||||||
func (L *State) Warning(msg *c.Char, tocont c.Int) {}
|
// ** garbage-collection function and options
|
||||||
|
// */
|
||||||
/*
|
|
||||||
* garbage-collection function and options
|
|
||||||
*/
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
GCSTOP = 0
|
GCSTOP = 0
|
||||||
@@ -420,59 +381,42 @@ const (
|
|||||||
GCINC = 11
|
GCINC = 11
|
||||||
)
|
)
|
||||||
|
|
||||||
// llgo:link (*State).Gc C.lua_gc
|
// LUA_API int (lua_gc) (State *L, int what, ...);
|
||||||
func (L *State) Gc(what c.Int, __llgo_va_list ...any) c.Int { return 0 }
|
|
||||||
|
|
||||||
/*
|
|
||||||
* miscellaneous functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
// /*
|
||||||
|
// ** miscellaneous functions
|
||||||
|
// */
|
||||||
// llgo:link (*State).Next C.lua_next
|
// llgo:link (*State).Next C.lua_next
|
||||||
func (L *State) Next(idx c.Int) c.Int { return 0 }
|
func (L *State) Next(idx c.Int) c.Int { return 0 }
|
||||||
|
|
||||||
// llgo:link (*State).Error C.lua_error
|
// LUA_API int (lua_error) (State *L);
|
||||||
func (L *State) Error() c.Int { return 0 }
|
|
||||||
|
|
||||||
// llgo:link (*State).Concat C.lua_concat
|
// LUA_API void (lua_concat) (State *L, int n);
|
||||||
func (L *State) Concat(n c.Int) {}
|
// LUA_API void (lua_len) (State *L, int idx);
|
||||||
|
|
||||||
// llgo:link (*State).Len C.lua_len
|
// LUA_API size_t (lua_stringtonumber) (State *L, const char *s);
|
||||||
func (L *State) Len(idx c.Int) {}
|
|
||||||
|
|
||||||
// llgo:link (*State).Stringtonumber C.lua_stringtonumber
|
// LUA_API lua_Alloc (lua_getallocf) (State *L, void **ud);
|
||||||
func (L *State) Stringtonumber(s *c.Char) c.Ulong { return 0 }
|
// LUA_API void (lua_setallocf) (State *L, lua_Alloc f, void *ud);
|
||||||
|
|
||||||
// llgo:link (*State).Getallocf C.lua_getallocf
|
// LUA_API void (lua_toclose) (State *L, int idx);
|
||||||
func (L *State) Getallocf(ud *c.Pointer) Alloc { return nil }
|
// LUA_API void (lua_closeslot) (State *L, int idx);
|
||||||
|
|
||||||
// llgo:link (*State).Setallocf C.lua_setallocf
|
// /*
|
||||||
func (L *State) Setallocf(f Alloc, ud c.Pointer) Alloc { return nil }
|
// ** {==============================================================
|
||||||
|
// ** some useful macros
|
||||||
|
// ** ===============================================================
|
||||||
|
// */
|
||||||
|
|
||||||
// llgo:link (*State).Toclose C.lua_toclose
|
// #define lua_getextraspace(L) ((void *)((char *)(L) - LUA_EXTRASPACE))
|
||||||
func (L *State) Toclose(idx c.Int) {}
|
|
||||||
|
|
||||||
// llgo:link (*State).Closeslot C.lua_closeslot
|
|
||||||
func (L *State) Closeslot(idx c.Int) {}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** {==============================================================
|
|
||||||
** some useful macros
|
|
||||||
** ===============================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
func (L *State) Getextraspace() c.Pointer {
|
|
||||||
return c.Pointer(uintptr(c.Pointer(L)) - EXTRASPACE)
|
|
||||||
}
|
|
||||||
func (L *State) Tonumber(idx c.Int) Number { return L.Tonumberx(idx, nil) }
|
func (L *State) Tonumber(idx c.Int) Number { return L.Tonumberx(idx, nil) }
|
||||||
func (L *State) Tostring(idx c.Int) *c.Char { return L.Tolstring(idx, nil) }
|
func (L *State) Tostring(idx c.Int) *c.Char { return L.Tolstring(idx, nil) }
|
||||||
func (L *State) Tointeger(idx c.Int) Integer { return L.Tointegerx(idx, nil) }
|
func (L *State) Tointeger(idx c.Int) Integer { return L.Tointegerx(idx, nil) }
|
||||||
func (L *State) Pop(n c.Int) { L.Settop(-(n) - 1) }
|
func (L *State) Pop(n c.Int) { L.Settop(-(n) - 1) }
|
||||||
func (L *State) Newtable() { L.Createtable(0, 0) }
|
func (L *State) Newtable() { L.Createtable(0, 0) }
|
||||||
|
|
||||||
func (L *State) Register(name *c.Char, f CFunction) {
|
// #define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
|
||||||
L.Pushcfunction(f)
|
|
||||||
L.Setglobal(name)
|
|
||||||
}
|
|
||||||
func (L *State) Pushcfunction(f CFunction) { L.Pushcclosure(f, 0) }
|
func (L *State) Pushcfunction(f CFunction) { L.Pushcclosure(f, 0) }
|
||||||
|
|
||||||
func (L *State) Isfunction(n c.Int) bool { return L.Type(n) == c.Int(FUNCTION) }
|
func (L *State) Isfunction(n c.Int) bool { return L.Type(n) == c.Int(FUNCTION) }
|
||||||
@@ -483,63 +427,38 @@ func (L *State) Isboolean(n c.Int) bool { return L.Type(n) == c.Int(BOOLEA
|
|||||||
func (L *State) Isthread(n c.Int) bool { return L.Type(n) == c.Int(THREAD) }
|
func (L *State) Isthread(n c.Int) bool { return L.Type(n) == c.Int(THREAD) }
|
||||||
func (L *State) Isnone(n c.Int) bool { return L.Type(n) == c.Int(NONE) }
|
func (L *State) Isnone(n c.Int) bool { return L.Type(n) == c.Int(NONE) }
|
||||||
func (L *State) Isnoneornil(n c.Int) bool { return L.Type(n) <= 0 }
|
func (L *State) Isnoneornil(n c.Int) bool { return L.Type(n) <= 0 }
|
||||||
func (L *State) Pushliteral(s *c.Char) *c.Char {
|
|
||||||
return L.Pushstring(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (L *State) Pushglobaltable() c.Int {
|
// #define lua_pushliteral(L, s) lua_pushstring(L, "" s)
|
||||||
return L.Rawgeti(REGISTRYINDEX, RIDX_GLOBALS)
|
// #define lua_pushglobaltable(L) ((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS))
|
||||||
}
|
|
||||||
|
|
||||||
func (L *State) Insert(idx c.Int) {
|
// #define lua_insert(L,idx) lua_rotate(L, (idx), 1)
|
||||||
L.Rotate(idx, 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))
|
||||||
|
|
||||||
func (L *State) Remove(idx c.Int) {
|
// /* }============================================================== */
|
||||||
L.Rotate(idx, -1)
|
|
||||||
L.Pop(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (L *State) Replace(idx c.Int) {
|
// /*
|
||||||
L.Copy(-1, idx)
|
// ** {==============================================================
|
||||||
L.Pop(1)
|
// ** compatibility macros
|
||||||
}
|
// ** ===============================================================
|
||||||
|
// */
|
||||||
|
|
||||||
/* }============================================================== */
|
// #define lua_newuserdata(L,s) lua_newuserdatauv(L,s,1)
|
||||||
|
// #define lua_getuservalue(L,idx) lua_getiuservalue(L,idx,1)
|
||||||
|
// #define lua_setuservalue(L,idx) lua_setiuservalue(L,idx,1)
|
||||||
|
|
||||||
/*
|
// #define LUA_NUMTAGS LUA_NUMTYPES
|
||||||
** {==============================================================
|
|
||||||
** compatibility macros
|
|
||||||
** ===============================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
func (L *State) Newuserdata(sz uintptr) c.Pointer {
|
// /* }============================================================== */
|
||||||
return L.Newuserdatauv(sz, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (L *State) Getuservalue(idx c.Int) c.Int {
|
// /*
|
||||||
return L.Getiuservalue(idx, 1)
|
// ** {======================================================================
|
||||||
}
|
// ** Debug API
|
||||||
|
// ** =======================================================================
|
||||||
func (L *State) Setuservalue(idx c.Int) c.Int {
|
// */
|
||||||
return L.Setiuservalue(idx, 1)
|
// /*
|
||||||
}
|
// ** Event codes
|
||||||
|
// */
|
||||||
const (
|
|
||||||
NUMTAGS = NUMTYPES
|
|
||||||
)
|
|
||||||
|
|
||||||
/* }============================================================== */
|
|
||||||
|
|
||||||
/*
|
|
||||||
** {======================================================================
|
|
||||||
** Debug API
|
|
||||||
** =======================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Event codes
|
|
||||||
*/
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
HOOKCALL = 0
|
HOOKCALL = 0
|
||||||
@@ -549,9 +468,13 @@ const (
|
|||||||
HOOKTAILCALL = 4
|
HOOKTAILCALL = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
// /*
|
||||||
* Event masks
|
// ** Event masks
|
||||||
*/
|
// */
|
||||||
|
// #define LUA_MASKCALL (1 << LUA_HOOKCALL)
|
||||||
|
// #define LUA_MASKRET (1 << LUA_HOOKRET)
|
||||||
|
// #define LUA_MASKLINE (1 << LUA_HOOKLINE)
|
||||||
|
// #define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MASKCALL = 1 << HOOKCOUNT
|
MASKCALL = 1 << HOOKCOUNT
|
||||||
@@ -560,68 +483,22 @@ const (
|
|||||||
MASKCOUNT = 1 << HOOKCOUNT
|
MASKCOUNT = 1 << HOOKCOUNT
|
||||||
)
|
)
|
||||||
|
|
||||||
// llgo:link (*State).Getstack C.lua_getstack
|
// LUA_API int (lua_getstack) (State *L, int level, lua_Debug *ar);
|
||||||
func (L *State) Getstack(level c.Int, ar *Debug) c.Int { return 0 }
|
// LUA_API int (lua_getinfo) (State *L, const char *what, lua_Debug *ar);
|
||||||
|
// LUA_API const char *(lua_getlocal) (State *L, const lua_Debug *ar, int n);
|
||||||
|
// LUA_API const char *(lua_setlocal) (State *L, const lua_Debug *ar, int n);
|
||||||
|
// LUA_API const char *(lua_getupvalue) (State *L, int funcindex, int n);
|
||||||
|
// LUA_API const char *(lua_setupvalue) (State *L, int funcindex, int n);
|
||||||
|
|
||||||
// llgo:link (*State).Getinfo C.lua_getinfo
|
// LUA_API void *(lua_upvalueid) (State *L, int fidx, int n);
|
||||||
func (L *State) Getinfo(what *c.Char, ar *Debug) c.Int { return 0 }
|
// LUA_API void (lua_upvaluejoin) (State *L, int fidx1, int n1, int fidx2, int n2);
|
||||||
|
|
||||||
// llgo:link (*State).Getlocal C.lua_getlocal
|
// LUA_API void (lua_sethook) (State *L, lua_Hook func, int mask, int count);
|
||||||
func (L *State) Getlocal(ar *Debug, n c.Int) *c.Char { return nil }
|
// LUA_API lua_Hook (lua_gethook) (State *L);
|
||||||
|
// LUA_API int (lua_gethookmask) (State *L);
|
||||||
|
// LUA_API int (lua_gethookcount) (State *L);
|
||||||
|
|
||||||
// llgo:link (*State).Setlocal C.lua_setlocal
|
// LUA_API int (lua_setcstacklimit) (State *L, unsigned int limit);
|
||||||
func (L *State) Setlocal(ar *Debug, n c.Int) *c.Char { return nil }
|
|
||||||
|
|
||||||
// llgo:link (*State).Getupvalue C.lua_getupvalue
|
// struct lua_Debug
|
||||||
func (L *State) Getupvalue(funcindex c.Int, n c.Int) *c.Char { return nil }
|
// /* }====================================================================== */
|
||||||
|
|
||||||
// llgo:link (*State).Setupvalue C.lua_setupvalue
|
|
||||||
func (L *State) Setupvalue(funcindex c.Int, n c.Int) *c.Char { return nil }
|
|
||||||
|
|
||||||
// llgo:link (*State).Upvalueid C.lua_upvalueid
|
|
||||||
func (L *State) Upvalueid(fidx c.Int, n c.Int) c.Pointer { return nil }
|
|
||||||
|
|
||||||
// llgo:link (*State).Upvaluejoin C.lua_upvaluejoin
|
|
||||||
func (L *State) Upvaluejoin(fidx1 c.Int, n1 c.Int, fidx2 c.Int, n2 c.Int) {}
|
|
||||||
|
|
||||||
// llgo:link (*State).Sethook C.lua_sethook
|
|
||||||
func (L *State) Sethook(fn Hook, mask c.Int, count c.Int) {}
|
|
||||||
|
|
||||||
// llgo:link (*State).Gethook C.lua_gethook
|
|
||||||
func (L *State) Gethook() Hook { return nil }
|
|
||||||
|
|
||||||
// llgo:link (*State).Gethookmask C.lua_gethookmask
|
|
||||||
func (L *State) Gethookmask() c.Int { return 0 }
|
|
||||||
|
|
||||||
// llgo:link (*State).Gethookcount C.lua_gethookcount
|
|
||||||
func (L *State) Gethookcount() c.Int { return 0 }
|
|
||||||
|
|
||||||
// llgo:link (*State).Setcstacklimit C.lua_setcstacklimit
|
|
||||||
func (L *State) Setcstacklimit(limit c.Uint) c.Int { return 0 }
|
|
||||||
|
|
||||||
type CallInfo struct {
|
|
||||||
Unused [8]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type Debug struct {
|
|
||||||
Event c.Int
|
|
||||||
Name *c.Char /* (n) */
|
|
||||||
Namewhat *c.Char /* (n) 'global', 'local', 'field', 'method' */
|
|
||||||
What *c.Char /* (S) 'Lua', 'C', 'main', 'tail' */
|
|
||||||
Source *c.Char /* (S) */
|
|
||||||
Srclen uintptr /* (S) */
|
|
||||||
Currentline c.Int /* (l) */
|
|
||||||
Linedefined c.Int /* (S) */
|
|
||||||
Lastlinedefined c.Int /* (S) */
|
|
||||||
Nups byte /* (u) number of upvalues */
|
|
||||||
Nparams byte /* (u) number of parameters */
|
|
||||||
Isvararg c.Char /* (u) */
|
|
||||||
Istailcall c.Char /* (t) */
|
|
||||||
Ftransfer uint16 /* (r) index of first value transferred */
|
|
||||||
Ntransfer uint16 /* (r) number of transferred values */
|
|
||||||
ShortSrc [IDSIZE]c.Char /* (S) */
|
|
||||||
/* private part */
|
|
||||||
ICi *CallInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
/* }====================================================================== */
|
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
package lua
|
|
||||||
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
/*
|
|
||||||
** {==================================================================
|
|
||||||
** Macros that affect the API and must be stable (that is, must be the
|
|
||||||
** same when you compile Lua and when you compile code that links to
|
|
||||||
** Lua).
|
|
||||||
** =====================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ LUAI_MAXSTACK limits the size of the Lua stack.
|
|
||||||
** CHANGE it if you need a different limit. This limit is arbitrary;
|
|
||||||
** its only purpose is to stop Lua from consuming unlimited stack
|
|
||||||
** space (and to reserve some numbers for pseudo-indices).
|
|
||||||
** (It must fit into max(size_t)/32 and max(int)/2.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
const (
|
|
||||||
MAXSTACK = 1000000
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ LUA_EXTRASPACE defines the size of a raw memory area associated with
|
|
||||||
** a Lua state with very fast access.
|
|
||||||
** CHANGE it if you need a different size.
|
|
||||||
*/
|
|
||||||
const (
|
|
||||||
EXTRASPACE = unsafe.Sizeof(uintptr(0))
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ LUA_IDSIZE gives the maximum size for the description of the source
|
|
||||||
** of a function in debug information.
|
|
||||||
** CHANGE it if you want a different size.
|
|
||||||
*/
|
|
||||||
const (
|
|
||||||
IDSIZE = 60
|
|
||||||
)
|
|
||||||
42
c/net/net.go
42
c/net/net.go
@@ -17,7 +17,7 @@
|
|||||||
package net
|
package net
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"unsafe"
|
_ "unsafe"
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
"github.com/goplus/llgo/c"
|
||||||
)
|
)
|
||||||
@@ -97,13 +97,6 @@ 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
|
||||||
|
|
||||||
@@ -124,14 +117,6 @@ 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
|
||||||
}
|
}
|
||||||
@@ -186,21 +171,6 @@ 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
|
|
||||||
|
|
||||||
//go:linkname Ntohs C.ntohs
|
|
||||||
func Ntohs(x uint16) uint16
|
|
||||||
|
|
||||||
//go:linkname Htons C.htons
|
|
||||||
func Htons(x uint16) uint16
|
|
||||||
|
|
||||||
//go:linkname Ntohl C.ntohl
|
|
||||||
func Ntohl(x c.Uint) c.Uint
|
|
||||||
|
|
||||||
//go:linkname Htonl C.htonl
|
|
||||||
func Htonl(x c.Uint) c.Uint
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
type AddrInfo struct {
|
type AddrInfo struct {
|
||||||
@@ -221,3 +191,13 @@ func Getaddrinfo(host *c.Char, port *c.Char, addrInfo *AddrInfo, result **AddrIn
|
|||||||
func Freeaddrinfo(addrInfo *AddrInfo) c.Int
|
func Freeaddrinfo(addrInfo *AddrInfo) c.Int
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
func swapInt16(data uint16) uint16 {
|
||||||
|
return (data << 8) | (data >> 8)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Htons(x uint16) uint16 {
|
||||||
|
return swapInt16(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer ctx.Free()
|
defer ctx.Free()
|
||||||
|
|
||||||
var ret c.Int = ctx.InitEx(unsafe.Pointer(unsafe.StringData(key)), c.Int(lenKey), openssl.EVP_sha256(), nil)
|
var ret c.Int = ctx.InitEx(unsafe.Pointer(unsafe.StringData(key)), c.Int(lenKey), openssl.EVP_sha256(), nil)
|
||||||
if ret == 0 {
|
if ret == 0 {
|
||||||
c.Fprintf(c.Stderr, c.Str("%s\n"), c.Str("Error initializing HMAC_CTX"))
|
c.Fprintf(c.Stderr, c.Str("%s\n"), c.Str("Error initializing HMAC_CTX"))
|
||||||
@@ -36,5 +37,9 @@ func main() {
|
|||||||
c.Fprintf(c.Stderr, c.Str("%s\n"), c.Str("Error finalizing HMAC_CTX"))
|
c.Fprintf(c.Stderr, c.Str("%s\n"), c.Str("Error finalizing HMAC_CTX"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Printf("HMAC:%x\n", digest[:digestLen])
|
fmt.Print("HMAC: ")
|
||||||
|
for i := 0; i < int(digestLen); i++ {
|
||||||
|
fmt.Printf("%02x", digest[i])
|
||||||
|
}
|
||||||
|
fmt.Print("\n")
|
||||||
}
|
}
|
||||||
|
|||||||
102
c/openssl/bn.go
102
c/openssl/bn.go
@@ -49,19 +49,8 @@ func BN_CTXSecureNew() *BN_CTX
|
|||||||
func (*BN_CTX) Free() {}
|
func (*BN_CTX) Free() {}
|
||||||
|
|
||||||
// void BN_CTX_start(BN_CTX *ctx);
|
// 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);
|
// 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);
|
// void BN_CTX_end(BN_CTX *ctx);
|
||||||
//
|
|
||||||
// llgo:link (*BN_CTX).End C.BN_CTX_end
|
|
||||||
func (*BN_CTX) End() {}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -202,80 +191,23 @@ func BNDec2bn(a **BIGNUM, str *c.Char) c.Int
|
|||||||
//go:linkname BNAsc2bn C.BN_asc2bn
|
//go:linkname BNAsc2bn C.BN_asc2bn
|
||||||
func BNAsc2bn(a **BIGNUM, str *c.Char) c.Int
|
func BNAsc2bn(a **BIGNUM, str *c.Char) c.Int
|
||||||
|
|
||||||
// BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
|
/*
|
||||||
//
|
BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
|
||||||
//go:linkname BNBin2bn C.BN_bin2bn
|
BIGNUM *BN_signed_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
|
||||||
func BNBin2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM
|
int BN_bn2bin(const BIGNUM *a, unsigned char *to);
|
||||||
|
int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen);
|
||||||
// BIGNUM *BN_signed_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
|
int BN_signed_bn2bin(const BIGNUM *a, unsigned char *to, int tolen);
|
||||||
//
|
BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret);
|
||||||
//go:linkname BNSignedBin2bn C.BN_signed_bin2bn
|
BIGNUM *BN_signed_lebin2bn(const unsigned char *s, int len, BIGNUM *ret);
|
||||||
func BNSignedBin2bn(s *byte, len c.Int, ret *BIGNUM) *BIGNUM
|
int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen);
|
||||||
|
int BN_signed_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen);
|
||||||
// int BN_bn2bin(const BIGNUM *a, unsigned char *to);
|
BIGNUM *BN_native2bn(const unsigned char *s, int len, BIGNUM *ret);
|
||||||
//
|
BIGNUM *BN_signed_native2bn(const unsigned char *s, int len, BIGNUM *ret);
|
||||||
// llgo:link (*BIGNUM).Bn2bin C.BN_bn2bin
|
int BN_bn2nativepad(const BIGNUM *a, unsigned char *to, int tolen);
|
||||||
func (bn *BIGNUM) Bn2bin(to *byte) c.Int { return 0 }
|
int BN_signed_bn2native(const BIGNUM *a, unsigned char *to, int tolen);
|
||||||
|
BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret);
|
||||||
// int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen);
|
int BN_bn2mpi(const BIGNUM *a, unsigned char *to);
|
||||||
//
|
*/
|
||||||
// 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);
|
// int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -6,15 +6,7 @@ import (
|
|||||||
"github.com/goplus/llgo/c"
|
"github.com/goplus/llgo/c"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const EVP_MAX_MD_SIZE = 64 /* longest known is SHA512 */
|
||||||
EVP_MAX_MD_SIZE = 64 /* longest known is SHA512 */
|
|
||||||
)
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
type EVP_MD struct {
|
|
||||||
Unused [0]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// const EVP_MD *EVP_sha1(void)
|
// const EVP_MD *EVP_sha1(void)
|
||||||
//
|
//
|
||||||
@@ -51,7 +43,13 @@ func EVP_sha384() *EVP_MD
|
|||||||
//go:linkname EVP_sha512 C.EVP_sha512
|
//go:linkname EVP_sha512 C.EVP_sha512
|
||||||
func EVP_sha512() *EVP_MD
|
func EVP_sha512() *EVP_MD
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
type EVP_MD struct {
|
||||||
|
Unused [0]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type EVP_MD_CTX struct {
|
||||||
|
Unused [0]byte
|
||||||
|
}
|
||||||
|
|
||||||
type HMAC_CTX struct {
|
type HMAC_CTX struct {
|
||||||
Unused [0]byte
|
Unused [0]byte
|
||||||
@@ -65,38 +63,30 @@ func NewHMAC_CTX() *HMAC_CTX
|
|||||||
// OSSL_DEPRECATEDIN_3_0 void HMAC_CTX_free(HMAC_CTX *ctx);
|
// OSSL_DEPRECATEDIN_3_0 void HMAC_CTX_free(HMAC_CTX *ctx);
|
||||||
//
|
//
|
||||||
// llgo:link (*HMAC_CTX).Free C.HMAC_CTX_free
|
// llgo:link (*HMAC_CTX).Free C.HMAC_CTX_free
|
||||||
func (ctx *HMAC_CTX) Free() {}
|
func (c *HMAC_CTX) Free() {}
|
||||||
|
|
||||||
// OSSL_DEPRECATEDIN_3_0 size_t HMAC_size(const HMAC_CTX *e);
|
// OSSL_DEPRECATEDIN_3_0 size_t HMAC_size(const HMAC_CTX *e);
|
||||||
//
|
//
|
||||||
// llgo:link (*HMAC_CTX).Size C.HMAC_size
|
// llgo:link (*HMAC_CTX).Size C.HMAC_size
|
||||||
func (ctx *HMAC_CTX) Size() uintptr { return 0 }
|
func (c *HMAC_CTX) Size() uintptr { return 0 }
|
||||||
|
|
||||||
// OSSL_DEPRECATEDIN_3_0 int HMAC_CTX_reset(HMAC_CTX *ctx);
|
// OSSL_DEPRECATEDIN_3_0 int HMAC_CTX_reset(HMAC_CTX *ctx);
|
||||||
//
|
//
|
||||||
// llgo:link (*HMAC_CTX).Reset C.HMAC_CTX_reset
|
// llgo:link (*HMAC_CTX).Reset C.HMAC_CTX_reset
|
||||||
func (ctx *HMAC_CTX) Reset() c.Int { return 0 }
|
func (c *HMAC_CTX) Reset() c.Int { return 0 }
|
||||||
|
|
||||||
// OSSL_DEPRECATEDIN_1_1_0 __owur int HMAC_Init(HMAC_CTX *ctx,
|
// OSSL_DEPRECATEDIN_1_1_0 __owur int HMAC_Init(HMAC_CTX *ctx,
|
||||||
// const void *key, int len,
|
// const void *key, int len,
|
||||||
// const EVP_MD *md);
|
// const EVP_MD *md);
|
||||||
//
|
//
|
||||||
// llgo:link (*HMAC_CTX).Init C.HMAC_Init
|
// 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 (c *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,
|
// OSSL_DEPRECATEDIN_3_0 int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
|
||||||
// const EVP_MD *md, ENGINE *impl);
|
// const EVP_MD *md, ENGINE *impl);
|
||||||
//
|
//
|
||||||
// llgo:link (*HMAC_CTX).InitEx C.HMAC_Init_ex
|
// 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 {
|
func (c *HMAC_CTX) InitEx(key unsafe.Pointer, len c.Int, md *EVP_MD, impl unsafe.Pointer) c.Int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,30 +94,28 @@ func (ctx *HMAC_CTX) InitEx(key unsafe.Pointer, len c.Int, md *EVP_MD, impl unsa
|
|||||||
// size_t len);
|
// size_t len);
|
||||||
//
|
//
|
||||||
// llgo:link (*HMAC_CTX).Update C.HMAC_Update
|
// llgo:link (*HMAC_CTX).Update C.HMAC_Update
|
||||||
func (ctx *HMAC_CTX) Update(data unsafe.Pointer, len uintptr) c.Int { return 0 }
|
func (c *HMAC_CTX) Update(data unsafe.Pointer, len uintptr) c.Int { return 0 }
|
||||||
|
|
||||||
func (ctx *HMAC_CTX) UpdateBytes(data []byte) c.Int {
|
func (c *HMAC_CTX) UpdateBytes(data []byte) c.Int {
|
||||||
return ctx.Update(unsafe.Pointer(unsafe.SliceData(data)), uintptr(len(data)))
|
return c.Update(unsafe.Pointer(unsafe.SliceData(data)), uintptr(len(data)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *HMAC_CTX) UpdateString(data string) c.Int {
|
func (c *HMAC_CTX) UpdateString(data string) c.Int {
|
||||||
return ctx.Update(unsafe.Pointer(unsafe.StringData(data)), uintptr(len(data)))
|
return c.Update(unsafe.Pointer(unsafe.StringData(data)), uintptr(len(data)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// OSSL_DEPRECATEDIN_3_0 int HMAC_Final(HMAC_CTX *ctx, unsigned char *md,
|
// OSSL_DEPRECATEDIN_3_0 int HMAC_Final(HMAC_CTX *ctx, unsigned char *md,
|
||||||
// unsigned int *len);
|
// unsigned int *len);
|
||||||
//
|
//
|
||||||
// llgo:link (*HMAC_CTX).Final C.HMAC_Final
|
// llgo:link (*HMAC_CTX).Final C.HMAC_Final
|
||||||
func (ctx *HMAC_CTX) Final(md *byte, len *c.Uint) c.Int { return 0 }
|
func (c *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);
|
// OSSL_DEPRECATEDIN_3_0 __owur int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx);
|
||||||
//
|
//
|
||||||
// llgo:link (*HMAC_CTX).Copy C.HMAC_CTX_copy
|
// llgo:link (*HMAC_CTX).Copy C.HMAC_CTX_copy
|
||||||
func (ctx *HMAC_CTX) Copy(sctx *HMAC_CTX) c.Int { return 0 }
|
func (c *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);
|
// 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
|
// llgo:link (*HMAC_CTX).SetFlags C.HMAC_CTX_set_flags
|
||||||
func (ctx *HMAC_CTX) SetFlags(flags c.Ulong) {}
|
func (c *HMAC_CTX) SetFlags(flags c.Ulong) {}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
int llgoClearenv() {
|
int llgoClearenv() {
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
@@ -8,5 +7,3 @@ int llgoClearenv() {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int llgoErrno() { return errno; }
|
|
||||||
|
|||||||
10
c/os/os.go
10
c/os/os.go
@@ -70,8 +70,8 @@ type (
|
|||||||
StatT = syscall.Stat_t
|
StatT = syscall.Stat_t
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:linkname Errno C.llgoErrno
|
//go:linkname Errno errno
|
||||||
func Errno() c.Int
|
var Errno c.Int
|
||||||
|
|
||||||
//go:linkname Umask C.umask
|
//go:linkname Umask C.umask
|
||||||
func Umask(cmask ModeT) ModeT
|
func Umask(cmask ModeT) ModeT
|
||||||
@@ -236,12 +236,12 @@ func Isatty(fd c.Int) c.Int
|
|||||||
// Execl requires the full path of the program to be provided.
|
// Execl requires the full path of the program to be provided.
|
||||||
//
|
//
|
||||||
//go:linkname Execl C.execl
|
//go:linkname Execl C.execl
|
||||||
func Execl(path *c.Char, arg0 *c.Char, __llgo_va_list ...any) c.Int
|
func Execl(path *c.Char, __llgo_va_list ...any) c.Int
|
||||||
|
|
||||||
// Execle(const char *path, const char *arg0, ..., /* (char *)0, char *const envp[] */)
|
// Execle(const char *path, const char *arg0, ..., /* (char *)0, char *const envp[] */)
|
||||||
//
|
//
|
||||||
//go:linkname Execle C.execle
|
//go:linkname Execle C.execle
|
||||||
func Execle(path *c.Char, arg0 *c.Char, __llgo_va_list ...any) c.Int
|
func Execle(path *c.Char, __llgo_va_list ...any) c.Int
|
||||||
|
|
||||||
// Execlp(const char *file, const char *arg0, ..., /*, (char *)0, */)
|
// Execlp(const char *file, const char *arg0, ..., /*, (char *)0, */)
|
||||||
//
|
//
|
||||||
@@ -249,7 +249,7 @@ func Execle(path *c.Char, arg0 *c.Char, __llgo_va_list ...any) c.Int
|
|||||||
// paths specified in the PATH environment variable.
|
// paths specified in the PATH environment variable.
|
||||||
//
|
//
|
||||||
//go:linkname Execlp C.execlp
|
//go:linkname Execlp C.execlp
|
||||||
func Execlp(file *c.Char, arg0 *c.Char, __llgo_va_list ...any) c.Int
|
func Execlp(file *c.Char, __llgo_va_list ...any) c.Int
|
||||||
|
|
||||||
//go:linkname Execv C.execv
|
//go:linkname Execv C.execv
|
||||||
func Execv(path *c.Char, argv **c.Char) c.Int
|
func Execv(path *c.Char, argv **c.Char) c.Int
|
||||||
|
|||||||
@@ -21,8 +21,7 @@ package os
|
|||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LLGoFiles = "_os/os.c"
|
LLGoPackage = "decl"
|
||||||
LLGoPackage = "link"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:linkname Clearenv C.clearenv
|
//go:linkname Clearenv C.clearenv
|
||||||
|
|||||||
@@ -22,6 +22,10 @@ import (
|
|||||||
"github.com/goplus/llgo/c"
|
"github.com/goplus/llgo/c"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LLGoPackage = "decl"
|
||||||
|
)
|
||||||
|
|
||||||
func __noop__() c.Int {
|
func __noop__() c.Int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@@ -32,12 +36,59 @@ type aThread struct {
|
|||||||
Unused [8]byte
|
Unused [8]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
//llgo:type C
|
|
||||||
type RoutineFunc func(c.Pointer) c.Pointer
|
|
||||||
|
|
||||||
// Thread represents a POSIX thread.
|
// Thread represents a POSIX thread.
|
||||||
type Thread = *aThread
|
type Thread = *aThread
|
||||||
|
|
||||||
|
// The pthread_create() function starts a new thread in the calling
|
||||||
|
// process. The new thread starts execution by invoking
|
||||||
|
// start_routine(); arg is passed as the sole argument of
|
||||||
|
// start_routine().
|
||||||
|
//
|
||||||
|
// The new thread terminates in one of the following ways:
|
||||||
|
//
|
||||||
|
// - It calls pthread_exit(3), specifying an exit status value that
|
||||||
|
// is available to another thread in the same process that calls
|
||||||
|
// pthread_join(3).
|
||||||
|
//
|
||||||
|
// - It returns from start_routine(). This is equivalent to
|
||||||
|
// calling pthread_exit(3) with the value supplied in the return
|
||||||
|
// statement.
|
||||||
|
//
|
||||||
|
// - It is canceled (see pthread_cancel(3)).
|
||||||
|
//
|
||||||
|
// - Any of the threads in the process calls exit(3), or the main
|
||||||
|
// thread performs a return from main(). This causes the
|
||||||
|
// termination of all threads in the process.
|
||||||
|
//
|
||||||
|
// On success, pthread_create() returns 0; on error, it returns an
|
||||||
|
// error number, and the contents of *thread are undefined.
|
||||||
|
//
|
||||||
|
// See https://man7.org/linux/man-pages/man3/pthread_create.3.html
|
||||||
|
//
|
||||||
|
//go:linkname Create C.pthread_create
|
||||||
|
func Create(pthread *Thread, attr *Attr, routine func(c.Pointer) c.Pointer, arg c.Pointer) c.Int
|
||||||
|
|
||||||
|
// The pthread_join() function waits for the thread specified by
|
||||||
|
// thread to terminate. If that thread has already terminated, then
|
||||||
|
// pthread_join() returns immediately. The thread specified by
|
||||||
|
// thread must be joinable.
|
||||||
|
//
|
||||||
|
// If retval is not NULL, then pthread_join() copies the exit status
|
||||||
|
// of the target thread (i.e., the value that the target thread
|
||||||
|
// supplied to pthread_exit(3)) into the location pointed to by
|
||||||
|
// retval. If the target thread was canceled, then PTHREAD_CANCELED
|
||||||
|
// is placed in the location pointed to by retval.
|
||||||
|
//
|
||||||
|
// If multiple threads simultaneously try to join with the same
|
||||||
|
// thread, the results are undefined. If the thread calling
|
||||||
|
// pthread_join() is canceled, then the target thread will remain
|
||||||
|
// joinable (i.e., it will not be detached).
|
||||||
|
//
|
||||||
|
// See https://man7.org/linux/man-pages/man3/pthread_join.3.html
|
||||||
|
//
|
||||||
|
//go:linkname Join C.pthread_join
|
||||||
|
func Join(thread Thread, retval *c.Pointer) c.Int
|
||||||
|
|
||||||
// The pthread_exit() function terminates the calling thread and
|
// The pthread_exit() function terminates the calling thread and
|
||||||
// returns a value via retval that (if the thread is joinable) is
|
// returns a value via retval that (if the thread is joinable) is
|
||||||
// available to another thread in the same process that calls
|
// available to another thread in the same process that calls
|
||||||
|
|||||||
@@ -1,80 +0,0 @@
|
|||||||
//go:build !nogc
|
|
||||||
// +build !nogc
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pthread
|
|
||||||
|
|
||||||
import (
|
|
||||||
_ "unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
LLGoPackage = "link: $(pkg-config --libs bdw-gc); -lgc"
|
|
||||||
)
|
|
||||||
|
|
||||||
// The pthread_create() function starts a new thread in the calling
|
|
||||||
// process. The new thread starts execution by invoking
|
|
||||||
// start_routine(); arg is passed as the sole argument of
|
|
||||||
// start_routine().
|
|
||||||
//
|
|
||||||
// The new thread terminates in one of the following ways:
|
|
||||||
//
|
|
||||||
// - It calls pthread_exit(3), specifying an exit status value that
|
|
||||||
// is available to another thread in the same process that calls
|
|
||||||
// pthread_join(3).
|
|
||||||
//
|
|
||||||
// - It returns from start_routine(). This is equivalent to
|
|
||||||
// calling pthread_exit(3) with the value supplied in the return
|
|
||||||
// statement.
|
|
||||||
//
|
|
||||||
// - It is canceled (see pthread_cancel(3)).
|
|
||||||
//
|
|
||||||
// - Any of the threads in the process calls exit(3), or the main
|
|
||||||
// thread performs a return from main(). This causes the
|
|
||||||
// termination of all threads in the process.
|
|
||||||
//
|
|
||||||
// On success, pthread_create() returns 0; on error, it returns an
|
|
||||||
// error number, and the contents of *thread are undefined.
|
|
||||||
//
|
|
||||||
// See https://man7.org/linux/man-pages/man3/pthread_create.3.html
|
|
||||||
//
|
|
||||||
//go:linkname Create C.GC_pthread_create
|
|
||||||
func Create(pthread *Thread, attr *Attr, routine RoutineFunc, arg c.Pointer) c.Int
|
|
||||||
|
|
||||||
// The pthread_join() function waits for the thread specified by
|
|
||||||
// thread to terminate. If that thread has already terminated, then
|
|
||||||
// pthread_join() returns immediately. The thread specified by
|
|
||||||
// thread must be joinable.
|
|
||||||
//
|
|
||||||
// If retval is not NULL, then pthread_join() copies the exit status
|
|
||||||
// of the target thread (i.e., the value that the target thread
|
|
||||||
// supplied to pthread_exit(3)) into the location pointed to by
|
|
||||||
// retval. If the target thread was canceled, then PTHREAD_CANCELED
|
|
||||||
// is placed in the location pointed to by retval.
|
|
||||||
//
|
|
||||||
// If multiple threads simultaneously try to join with the same
|
|
||||||
// thread, the results are undefined. If the thread calling
|
|
||||||
// pthread_join() is canceled, then the target thread will remain
|
|
||||||
// joinable (i.e., it will not be detached).
|
|
||||||
//
|
|
||||||
// See https://man7.org/linux/man-pages/man3/pthread_join.3.html
|
|
||||||
//
|
|
||||||
//go:linkname Join C.GC_pthread_join
|
|
||||||
func Join(thread Thread, retval *c.Pointer) c.Int
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
//go:build nogc
|
|
||||||
// +build nogc
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pthread
|
|
||||||
|
|
||||||
import (
|
|
||||||
_ "unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
LLGoPackage = "decl"
|
|
||||||
)
|
|
||||||
|
|
||||||
// The pthread_create() function starts a new thread in the calling
|
|
||||||
// process. The new thread starts execution by invoking
|
|
||||||
// start_routine(); arg is passed as the sole argument of
|
|
||||||
// start_routine().
|
|
||||||
//
|
|
||||||
// The new thread terminates in one of the following ways:
|
|
||||||
//
|
|
||||||
// - It calls pthread_exit(3), specifying an exit status value that
|
|
||||||
// is available to another thread in the same process that calls
|
|
||||||
// pthread_join(3).
|
|
||||||
//
|
|
||||||
// - It returns from start_routine(). This is equivalent to
|
|
||||||
// calling pthread_exit(3) with the value supplied in the return
|
|
||||||
// statement.
|
|
||||||
//
|
|
||||||
// - It is canceled (see pthread_cancel(3)).
|
|
||||||
//
|
|
||||||
// - Any of the threads in the process calls exit(3), or the main
|
|
||||||
// thread performs a return from main(). This causes the
|
|
||||||
// termination of all threads in the process.
|
|
||||||
//
|
|
||||||
// On success, pthread_create() returns 0; on error, it returns an
|
|
||||||
// error number, and the contents of *thread are undefined.
|
|
||||||
//
|
|
||||||
// See https://man7.org/linux/man-pages/man3/pthread_create.3.html
|
|
||||||
//
|
|
||||||
//go:linkname Create C.pthread_create
|
|
||||||
func Create(pthread *Thread, attr *Attr, routine RoutineFunc, arg c.Pointer) c.Int
|
|
||||||
|
|
||||||
// The pthread_join() function waits for the thread specified by
|
|
||||||
// thread to terminate. If that thread has already terminated, then
|
|
||||||
// pthread_join() returns immediately. The thread specified by
|
|
||||||
// thread must be joinable.
|
|
||||||
//
|
|
||||||
// If retval is not NULL, then pthread_join() copies the exit status
|
|
||||||
// of the target thread (i.e., the value that the target thread
|
|
||||||
// supplied to pthread_exit(3)) into the location pointed to by
|
|
||||||
// retval. If the target thread was canceled, then PTHREAD_CANCELED
|
|
||||||
// is placed in the location pointed to by retval.
|
|
||||||
//
|
|
||||||
// If multiple threads simultaneously try to join with the same
|
|
||||||
// thread, the results are undefined. If the thread calling
|
|
||||||
// pthread_join() is canceled, then the target thread will remain
|
|
||||||
// joinable (i.e., it will not be detached).
|
|
||||||
//
|
|
||||||
// See https://man7.org/linux/man-pages/man3/pthread_join.3.html
|
|
||||||
//
|
|
||||||
//go:linkname Join C.pthread_join
|
|
||||||
func Join(thread Thread, retval *c.Pointer) c.Int
|
|
||||||
@@ -27,7 +27,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LLGoFiles = "_wrap/pthd.c"
|
LLGoFiles = "_pthd/pthd.c"
|
||||||
LLGoPackage = "link"
|
LLGoPackage = "link"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
package signal
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
)
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
const (
|
|
||||||
LLGoPackage = "link"
|
|
||||||
)
|
|
||||||
|
|
||||||
//llgo:type C
|
|
||||||
type SignalHandler func(c.Int)
|
|
||||||
|
|
||||||
//llgo:type C
|
|
||||||
type sigactiont struct {
|
|
||||||
handler SignalHandler
|
|
||||||
tramp unsafe.Pointer
|
|
||||||
mask c.Int
|
|
||||||
flags c.Int
|
|
||||||
}
|
|
||||||
|
|
||||||
//go:linkname sigaction C.sigaction
|
|
||||||
func sigaction(sig c.Int, act, old *sigactiont) c.Int
|
|
||||||
|
|
||||||
func Signal(sig c.Int, hanlder SignalHandler) c.Int {
|
|
||||||
var act sigactiont
|
|
||||||
act.handler = hanlder
|
|
||||||
return sigaction(sig, &act, nil)
|
|
||||||
}
|
|
||||||
@@ -1,221 +0,0 @@
|
|||||||
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.TypeDeclaration().TypedefDeclUnderlyingType(), data)
|
|
||||||
case clang.TypeElaborated:
|
|
||||||
printType(t.NamedType(), 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)
|
|
||||||
defer unit.DisposeTokens(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)
|
|
||||||
}
|
|
||||||
@@ -14,15 +14,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package runtime
|
package main
|
||||||
|
|
||||||
import (
|
func main() {
|
||||||
_ "unsafe"
|
// TODO(xsw): implement llcppsigfetch tool
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
|
||||||
"github.com/goplus/llgo/c/pthread"
|
|
||||||
)
|
|
||||||
|
|
||||||
func CreateThread(th *pthread.Thread, attr *pthread.Attr, routine pthread.RoutineFunc, arg c.Pointer) c.Int {
|
|
||||||
return pthread.Create(th, attr, routine, arg)
|
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user