Files
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

57 lines
1.5 KiB
Go

//go:build !windows
package languages
/*
#cgo linux LDFLAGS: -ldl
#include <dlfcn.h>
#include <stdlib.h>
// A tree-sitter grammar shared object exports
// const TSLanguage *tree_sitter_NAME(void);
// ts_grammar_call invokes a dlsym'd entry point and returns the
// TSLanguage pointer as an opaque void*.
typedef const void *(*ts_grammar_fn)(void);
static const void *ts_grammar_call(void *fn) {
return ((ts_grammar_fn)fn)();
}
*/
import "C"
import (
"fmt"
"unsafe"
)
// loadGrammarLanguage dlopen's a compiled tree-sitter grammar shared
// object, looks up the named entry point, invokes it, and returns the
// resulting TSLanguage pointer. The dlopen handle is intentionally
// leaked: the TSLanguage must outlive every parse, and the set of
// custom grammars is fixed for the process lifetime.
func loadGrammarLanguage(libPath, symbol string) (unsafe.Pointer, error) {
cPath := C.CString(libPath)
defer C.free(unsafe.Pointer(cPath))
handle := C.dlopen(cPath, C.RTLD_NOW|C.RTLD_LOCAL)
if handle == nil {
return nil, fmt.Errorf("dlopen: %s", C.GoString(C.dlerror()))
}
cSym := C.CString(symbol)
defer C.free(unsafe.Pointer(cSym))
C.dlerror() // clear any stale error before dlsym
fn := C.dlsym(handle, cSym)
if fn == nil {
err := C.GoString(C.dlerror())
C.dlclose(handle)
return nil, fmt.Errorf("dlsym %s: %s", symbol, err)
}
lang := C.ts_grammar_call(fn)
if lang == nil {
C.dlclose(handle)
return nil, fmt.Errorf("entry point %s returned a nil TSLanguage", symbol)
}
return unsafe.Pointer(lang), nil
}