Merge pull request #803 from luoliwoshang/llcppsigfetch/output
llcppsigfetch:refine
This commit is contained in:
@@ -27,34 +27,42 @@ import (
|
|||||||
"github.com/goplus/llgo/c"
|
"github.com/goplus/llgo/c"
|
||||||
"github.com/goplus/llgo/c/cjson"
|
"github.com/goplus/llgo/c/cjson"
|
||||||
"github.com/goplus/llgo/chore/_xtool/llcppsigfetch/parse"
|
"github.com/goplus/llgo/chore/_xtool/llcppsigfetch/parse"
|
||||||
|
"github.com/goplus/llgo/chore/_xtool/llcppsymg/clangutils"
|
||||||
"github.com/goplus/llgo/chore/_xtool/llcppsymg/config"
|
"github.com/goplus/llgo/chore/_xtool/llcppsymg/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if len(os.Args) == 1 {
|
cfgFile := ""
|
||||||
// run with default config file
|
outputToFile := false
|
||||||
runFromConfig()
|
for i := 1; i < len(os.Args); i++ {
|
||||||
return
|
arg := os.Args[i]
|
||||||
}
|
if arg == "--extract" {
|
||||||
|
runExtract()
|
||||||
if os.Args[1] == "--extract" {
|
return
|
||||||
runExtract()
|
} else if arg == "--help" || arg == "-h" {
|
||||||
} else if os.Args[1] == "--help" || os.Args[1] == "-h" {
|
printUsage()
|
||||||
printUsage()
|
return
|
||||||
} else {
|
} else if strings.HasPrefix(arg, "-out=") {
|
||||||
runFromConfig()
|
outputToFile = parseBoolArg(arg, "out", false)
|
||||||
|
} else if cfgFile == "" && !strings.HasPrefix(arg, "-") {
|
||||||
|
cfgFile = arg
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
runFromConfig(cfgFile, outputToFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
func printUsage() {
|
func printUsage() {
|
||||||
fmt.Println("Usage:")
|
fmt.Println("Usage:")
|
||||||
fmt.Println(" llcppsigfetch [<config_file>]")
|
fmt.Println(" llcppsigfetch [<config_file>] [-out=<bool>]")
|
||||||
fmt.Println(" OR")
|
fmt.Println(" OR")
|
||||||
fmt.Println(" llcppsigfetch --extract <file> <temp> [args...]")
|
fmt.Println(" llcppsigfetch --extract <file> [-out=<bool>] [-temp=<bool>] [-cpp=<bool>] [args...]")
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
fmt.Println("Options:")
|
fmt.Println("Options:")
|
||||||
fmt.Println(" [<config_file>]: Path to the configuration file (use '-' for stdin)")
|
fmt.Println(" [<config_file>]: Path to the configuration file (use '-' for stdin)")
|
||||||
fmt.Println(" If not provided, uses default 'llcppg.cfg'")
|
fmt.Println(" If not provided, uses default 'llcppg.cfg'")
|
||||||
|
fmt.Println(" -out=<bool>: Optional. Set to 'true' to output results to a file,")
|
||||||
|
fmt.Println(" 'false' (default) to output to stdout")
|
||||||
|
fmt.Println(" This option can be used with both modes")
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
fmt.Println(" --extract: Extract information from a single file")
|
fmt.Println(" --extract: Extract information from a single file")
|
||||||
fmt.Println(" <file>: Path to the file to process, or file content if -temp=true")
|
fmt.Println(" <file>: Path to the file to process, or file content if -temp=true")
|
||||||
@@ -71,10 +79,9 @@ func printUsage() {
|
|||||||
fmt.Println("Note: The two usage modes are mutually exclusive. Use either [<config_file>] OR --extract, not both.")
|
fmt.Println("Note: The two usage modes are mutually exclusive. Use either [<config_file>] OR --extract, not both.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func runFromConfig() {
|
func runFromConfig(cfgFile string, outputToFile bool) {
|
||||||
cfgFile := "llcppg.cfg"
|
if cfgFile == "" {
|
||||||
if len(os.Args) > 1 {
|
cfgFile = "llcppg.cfg"
|
||||||
cfgFile = os.Args[1]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var data []byte
|
var data []byte
|
||||||
@@ -100,7 +107,7 @@ func runFromConfig() {
|
|||||||
err = context.ProcessFiles(files)
|
err = context.ProcessFiles(files)
|
||||||
check(err)
|
check(err)
|
||||||
|
|
||||||
outputInfo(context)
|
outputInfo(context, outputToFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runExtract() {
|
func runExtract() {
|
||||||
@@ -110,13 +117,14 @@ func runExtract() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg := &parse.Config{
|
cfg := &clangutils.Config{
|
||||||
File: os.Args[2],
|
File: os.Args[2],
|
||||||
Args: []string{},
|
Args: []string{},
|
||||||
IsCpp: true,
|
IsCpp: true,
|
||||||
Temp: false,
|
Temp: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
outputToFile := false
|
||||||
for i := 3; i < len(os.Args); i++ {
|
for i := 3; i < len(os.Args); i++ {
|
||||||
arg := os.Args[i]
|
arg := os.Args[i]
|
||||||
switch {
|
switch {
|
||||||
@@ -128,6 +136,10 @@ func runExtract() {
|
|||||||
cfg.IsCpp = parseBoolArg(arg, "cpp", true)
|
cfg.IsCpp = parseBoolArg(arg, "cpp", true)
|
||||||
os.Args = append(os.Args[:i], os.Args[i+1:]...)
|
os.Args = append(os.Args[:i], os.Args[i+1:]...)
|
||||||
i--
|
i--
|
||||||
|
case strings.HasPrefix(arg, "-out="):
|
||||||
|
outputToFile = parseBoolArg(arg, "out", false)
|
||||||
|
os.Args = append(os.Args[:i], os.Args[i+1:]...)
|
||||||
|
i--
|
||||||
default:
|
default:
|
||||||
cfg.Args = append(cfg.Args, arg)
|
cfg.Args = append(cfg.Args, arg)
|
||||||
}
|
}
|
||||||
@@ -139,7 +151,7 @@ func runExtract() {
|
|||||||
check(err)
|
check(err)
|
||||||
result := converter.MarshalOutputASTFiles()
|
result := converter.MarshalOutputASTFiles()
|
||||||
cstr := result.Print()
|
cstr := result.Print()
|
||||||
c.Printf(cstr)
|
outputResult(cstr, outputToFile)
|
||||||
cjson.FreeCStr(cstr)
|
cjson.FreeCStr(cstr)
|
||||||
result.Delete()
|
result.Delete()
|
||||||
converter.Dispose()
|
converter.Dispose()
|
||||||
@@ -151,6 +163,20 @@ func check(err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func outputResult(result *c.Char, outputToFile bool) {
|
||||||
|
if outputToFile {
|
||||||
|
outputFile := "llcppg.sigfetch.json"
|
||||||
|
err := os.WriteFile(outputFile, []byte(c.GoString(result)), 0644)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error writing to output file: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
fmt.Printf("Results saved to %s\n", outputFile)
|
||||||
|
} else {
|
||||||
|
c.Printf(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func getHeaderFiles(cflags string, files []string) []string {
|
func getHeaderFiles(cflags string, files []string) []string {
|
||||||
prefix := cflags
|
prefix := cflags
|
||||||
prefix = strings.TrimPrefix(prefix, "-I")
|
prefix = strings.TrimPrefix(prefix, "-I")
|
||||||
@@ -161,12 +187,12 @@ func getHeaderFiles(cflags string, files []string) []string {
|
|||||||
return paths
|
return paths
|
||||||
}
|
}
|
||||||
|
|
||||||
func outputInfo(context *parse.Context) {
|
func outputInfo(context *parse.Context, outputToFile bool) {
|
||||||
info := context.Output()
|
info := context.Output()
|
||||||
str := info.Print()
|
str := info.Print()
|
||||||
defer cjson.FreeCStr(str)
|
defer cjson.FreeCStr(str)
|
||||||
defer info.Delete()
|
defer info.Delete()
|
||||||
c.Printf(str)
|
outputResult(str, outputToFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseBoolArg(arg, name string, defaultValue bool) bool {
|
func parseBoolArg(arg, name string, defaultValue bool) bool {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package parse
|
package parse
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -10,6 +9,7 @@ import (
|
|||||||
"github.com/goplus/llgo/c"
|
"github.com/goplus/llgo/c"
|
||||||
"github.com/goplus/llgo/c/cjson"
|
"github.com/goplus/llgo/c/cjson"
|
||||||
"github.com/goplus/llgo/c/clang"
|
"github.com/goplus/llgo/c/clang"
|
||||||
|
"github.com/goplus/llgo/chore/_xtool/llcppsymg/clangutils"
|
||||||
"github.com/goplus/llgo/chore/llcppg/ast"
|
"github.com/goplus/llgo/chore/llcppg/ast"
|
||||||
"github.com/goplus/llgo/chore/llcppg/token"
|
"github.com/goplus/llgo/chore/llcppg/token"
|
||||||
)
|
)
|
||||||
@@ -63,8 +63,8 @@ type Config struct {
|
|||||||
IsCpp bool
|
IsCpp bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConverter(config *Config) (*Converter, error) {
|
func NewConverter(config *clangutils.Config) (*Converter, error) {
|
||||||
index, unit, err := CreateTranslationUnit(config)
|
index, unit, err := clangutils.CreateTranslationUnit(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -78,56 +78,6 @@ func NewConverter(config *Config) (*Converter, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateTranslationUnit(config *Config) (*clang.Index, *clang.TranslationUnit, error) {
|
|
||||||
// default use the c/c++ standard of clang; c:gnu17 c++:gnu++17
|
|
||||||
// https://clang.llvm.org/docs/CommandGuide/clang.html
|
|
||||||
defaultArgs := []string{"-x", "c"}
|
|
||||||
if config.IsCpp {
|
|
||||||
defaultArgs = []string{"-x", "c++"}
|
|
||||||
}
|
|
||||||
allArgs := append(defaultArgs, config.Args...)
|
|
||||||
|
|
||||||
cArgs := make([]*c.Char, len(allArgs))
|
|
||||||
for i, arg := range allArgs {
|
|
||||||
cArgs[i] = c.AllocaCStr(arg)
|
|
||||||
}
|
|
||||||
|
|
||||||
index := clang.CreateIndex(0, 0)
|
|
||||||
|
|
||||||
var unit *clang.TranslationUnit
|
|
||||||
|
|
||||||
if config.Temp {
|
|
||||||
content := c.AllocaCStr(config.File)
|
|
||||||
tempFile := &clang.UnsavedFile{
|
|
||||||
Filename: c.Str("temp.h"),
|
|
||||||
Contents: content,
|
|
||||||
Length: c.Ulong(c.Strlen(content)),
|
|
||||||
}
|
|
||||||
|
|
||||||
unit = index.ParseTranslationUnit(
|
|
||||||
tempFile.Filename,
|
|
||||||
unsafe.SliceData(cArgs), c.Int(len(cArgs)),
|
|
||||||
tempFile, 1,
|
|
||||||
clang.DetailedPreprocessingRecord,
|
|
||||||
)
|
|
||||||
|
|
||||||
} else {
|
|
||||||
cFile := c.AllocaCStr(config.File)
|
|
||||||
unit = index.ParseTranslationUnit(
|
|
||||||
cFile,
|
|
||||||
unsafe.SliceData(cArgs), c.Int(len(cArgs)),
|
|
||||||
nil, 0,
|
|
||||||
clang.DetailedPreprocessingRecord,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if unit == nil {
|
|
||||||
return nil, nil, errors.New("failed to parse translation unit")
|
|
||||||
}
|
|
||||||
|
|
||||||
return index, unit, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ct *Converter) Dispose() {
|
func (ct *Converter) Dispose() {
|
||||||
ct.index.Dispose()
|
ct.index.Dispose()
|
||||||
ct.unit.Dispose()
|
ct.unit.Dispose()
|
||||||
@@ -259,14 +209,13 @@ func (ct *Converter) ParseComment(rawComment string) *ast.CommentGroup {
|
|||||||
lines := strings.Split(rawComment, "\n")
|
lines := strings.Split(rawComment, "\n")
|
||||||
commentGroup := &ast.CommentGroup{}
|
commentGroup := &ast.CommentGroup{}
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
commentGroup.List = append(commentGroup.List, &ast.Comment{Text: line})
|
commentGroup.List = append(commentGroup.List, &ast.Comment{Text: line + "\n"})
|
||||||
}
|
}
|
||||||
return commentGroup
|
return commentGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
// visit top decls (struct,class,function,enum & macro,include)
|
// visit top decls (struct,class,function,enum & macro,include)
|
||||||
func visitTop(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.ChildVisitResult {
|
func (ct *Converter) visitTop(cursor, parent clang.Cursor) clang.ChildVisitResult {
|
||||||
ct := (*Converter)(clientData)
|
|
||||||
ct.UpdateLoc(cursor)
|
ct.UpdateLoc(cursor)
|
||||||
|
|
||||||
curFile := ct.GetCurFile()
|
curFile := ct.GetCurFile()
|
||||||
@@ -300,7 +249,7 @@ func visitTop(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.Chil
|
|||||||
case clang.CursorTypedefDecl:
|
case clang.CursorTypedefDecl:
|
||||||
curFile.Decls = append(curFile.Decls, ct.ProcessTypeDefDecl(cursor))
|
curFile.Decls = append(curFile.Decls, ct.ProcessTypeDefDecl(cursor))
|
||||||
case clang.CursorNamespace:
|
case clang.CursorNamespace:
|
||||||
clang.VisitChildren(cursor, visitTop, c.Pointer(ct))
|
VisitChildren(cursor, ct.visitTop)
|
||||||
}
|
}
|
||||||
return clang.ChildVisit_Continue
|
return clang.ChildVisit_Continue
|
||||||
}
|
}
|
||||||
@@ -308,10 +257,19 @@ func visitTop(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.Chil
|
|||||||
func (ct *Converter) Convert() ([]*FileEntry, error) {
|
func (ct *Converter) Convert() ([]*FileEntry, error) {
|
||||||
cursor := ct.unit.Cursor()
|
cursor := ct.unit.Cursor()
|
||||||
// visit top decls (struct,class,function & macro,include)
|
// visit top decls (struct,class,function & macro,include)
|
||||||
clang.VisitChildren(cursor, visitTop, c.Pointer(ct))
|
VisitChildren(cursor, ct.visitTop)
|
||||||
return ct.Files, nil
|
return ct.Files, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Visitor func(cursor, parent clang.Cursor) clang.ChildVisitResult
|
||||||
|
|
||||||
|
func VisitChildren(cursor clang.Cursor, fn Visitor) c.Uint {
|
||||||
|
return clang.VisitChildren(cursor, func(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.ChildVisitResult {
|
||||||
|
cfn := *(*Visitor)(clientData)
|
||||||
|
return cfn(cursor, parent)
|
||||||
|
}, unsafe.Pointer(&fn))
|
||||||
|
}
|
||||||
|
|
||||||
func (ct *Converter) ProcessType(t clang.Type) ast.Expr {
|
func (ct *Converter) ProcessType(t clang.Type) ast.Expr {
|
||||||
if t.Kind >= clang.TypeFirstBuiltin && t.Kind <= clang.TypeLastBuiltin {
|
if t.Kind >= clang.TypeFirstBuiltin && t.Kind <= clang.TypeLastBuiltin {
|
||||||
return ct.ProcessBuiltinType(t)
|
return ct.ProcessBuiltinType(t)
|
||||||
@@ -519,38 +477,30 @@ func (ct *Converter) ProcessMethodAttributes(cursor clang.Cursor, fn *ast.FuncDe
|
|||||||
overridden.DisposeOverriddenCursors()
|
overridden.DisposeOverriddenCursors()
|
||||||
}
|
}
|
||||||
|
|
||||||
type visitEnumContext struct {
|
|
||||||
enum *[]*ast.EnumItem
|
|
||||||
converter *Converter
|
|
||||||
}
|
|
||||||
|
|
||||||
func visitEnum(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.ChildVisitResult {
|
|
||||||
ctx := (*visitEnumContext)(clientData)
|
|
||||||
if cursor.Kind == clang.CursorEnumConstantDecl {
|
|
||||||
name := cursor.String()
|
|
||||||
val := (*c.Char)(c.Malloc(unsafe.Sizeof(c.Char(0)) * 20))
|
|
||||||
c.Sprintf(val, c.Str("%lld"), cursor.EnumConstantDeclValue())
|
|
||||||
defer c.Free(unsafe.Pointer(val))
|
|
||||||
defer name.Dispose()
|
|
||||||
enum := &ast.EnumItem{
|
|
||||||
Name: &ast.Ident{Name: c.GoString(name.CStr())},
|
|
||||||
Value: &ast.BasicLit{
|
|
||||||
Kind: ast.IntLit,
|
|
||||||
Value: c.GoString(val),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
*ctx.enum = append(*ctx.enum, enum)
|
|
||||||
}
|
|
||||||
return clang.ChildVisit_Continue
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ct *Converter) ProcessEnumType(cursor clang.Cursor) *ast.EnumType {
|
func (ct *Converter) ProcessEnumType(cursor clang.Cursor) *ast.EnumType {
|
||||||
items := make([]*ast.EnumItem, 0)
|
items := make([]*ast.EnumItem, 0)
|
||||||
ctx := &visitEnumContext{
|
|
||||||
enum: &items,
|
VisitChildren(cursor, func(cursor, parent clang.Cursor) clang.ChildVisitResult {
|
||||||
converter: ct,
|
if cursor.Kind == clang.CursorEnumConstantDecl {
|
||||||
}
|
name := cursor.String()
|
||||||
clang.VisitChildren(cursor, visitEnum, c.Pointer(ctx))
|
defer name.Dispose()
|
||||||
|
|
||||||
|
val := (*c.Char)(c.Malloc(unsafe.Sizeof(c.Char(0)) * 20))
|
||||||
|
c.Sprintf(val, c.Str("%lld"), cursor.EnumConstantDeclValue())
|
||||||
|
defer c.Free(unsafe.Pointer(val))
|
||||||
|
|
||||||
|
enum := &ast.EnumItem{
|
||||||
|
Name: &ast.Ident{Name: c.GoString(name.CStr())},
|
||||||
|
Value: &ast.BasicLit{
|
||||||
|
Kind: ast.IntLit,
|
||||||
|
Value: c.GoString(val),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
items = append(items, enum)
|
||||||
|
}
|
||||||
|
return clang.ChildVisit_Continue
|
||||||
|
})
|
||||||
|
|
||||||
return &ast.EnumType{
|
return &ast.EnumType{
|
||||||
Items: items,
|
Items: items,
|
||||||
}
|
}
|
||||||
@@ -587,6 +537,8 @@ func (ct *Converter) ProcessInclude(cursor clang.Cursor) *ast.Include {
|
|||||||
return &ast.Include{Path: c.GoString(name.CStr())}
|
return &ast.Include{Path: c.GoString(name.CStr())}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo(zzy): after https://github.com/goplus/llgo/issues/804 has be resolved
|
||||||
|
// Change the following code to use the closure
|
||||||
type visitFieldContext struct {
|
type visitFieldContext struct {
|
||||||
params *ast.FieldList
|
params *ast.FieldList
|
||||||
converter *Converter
|
converter *Converter
|
||||||
@@ -851,23 +803,10 @@ func (ct *Converter) ProcessBuiltinType(t clang.Type) *ast.BuiltinType {
|
|||||||
// Constructs a complete scoping expression by traversing the semantic parents, starting from the given clang.Cursor
|
// Constructs a complete scoping expression by traversing the semantic parents, starting from the given clang.Cursor
|
||||||
// For anonymous decl of typedef references, use their anonymous name
|
// For anonymous decl of typedef references, use their anonymous name
|
||||||
func (ct *Converter) BuildScopingExpr(cursor clang.Cursor) ast.Expr {
|
func (ct *Converter) BuildScopingExpr(cursor clang.Cursor) ast.Expr {
|
||||||
parts := ct.BuildScopingParts(cursor)
|
parts := clangutils.BuildScopingParts(cursor)
|
||||||
return buildScopingFromParts(parts)
|
return buildScopingFromParts(parts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ct *Converter) BuildScopingParts(cursor clang.Cursor) []string {
|
|
||||||
var parts []string
|
|
||||||
// Traverse up the semantic parents
|
|
||||||
for cursor.IsNull() != 1 && cursor.Kind != clang.CursorTranslationUnit {
|
|
||||||
name := cursor.String()
|
|
||||||
qualified := c.GoString(name.CStr())
|
|
||||||
parts = append([]string{qualified}, parts...)
|
|
||||||
cursor = cursor.SemanticParent()
|
|
||||||
name.Dispose()
|
|
||||||
}
|
|
||||||
return parts
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ct *Converter) MarshalASTFiles() *cjson.JSON {
|
func (ct *Converter) MarshalASTFiles() *cjson.JSON {
|
||||||
return MarshalASTFiles(ct.Files)
|
return MarshalASTFiles(ct.Files)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,17 +2,17 @@ package cvttest
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
"github.com/goplus/llgo/c"
|
||||||
"github.com/goplus/llgo/c/cjson"
|
"github.com/goplus/llgo/c/cjson"
|
||||||
"github.com/goplus/llgo/c/clang"
|
"github.com/goplus/llgo/c/clang"
|
||||||
"github.com/goplus/llgo/chore/_xtool/llcppsigfetch/parse"
|
"github.com/goplus/llgo/chore/_xtool/llcppsigfetch/parse"
|
||||||
|
"github.com/goplus/llgo/chore/_xtool/llcppsymg/clangutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RunTest(testName string, testCases []string) {
|
func RunTest(testName string, testCases []string) {
|
||||||
for i, content := range testCases {
|
for i, content := range testCases {
|
||||||
converter, err := parse.NewConverter(&parse.Config{
|
converter, err := parse.NewConverter(&clangutils.Config{
|
||||||
File: content,
|
File: content,
|
||||||
Temp: true,
|
Temp: true,
|
||||||
IsCpp: true,
|
IsCpp: true,
|
||||||
@@ -63,7 +63,7 @@ type GetTypeOptions struct {
|
|||||||
// e.g. index.Dispose(), unit.Dispose()
|
// e.g. index.Dispose(), unit.Dispose()
|
||||||
func GetType(option *GetTypeOptions) (clang.Type, *clang.Index, *clang.TranslationUnit) {
|
func GetType(option *GetTypeOptions) (clang.Type, *clang.Index, *clang.TranslationUnit) {
|
||||||
code := fmt.Sprintf("%s placeholder;", option.TypeCode)
|
code := fmt.Sprintf("%s placeholder;", option.TypeCode)
|
||||||
index, unit, err := parse.CreateTranslationUnit(&parse.Config{
|
index, unit, err := clangutils.CreateTranslationUnit(&clangutils.Config{
|
||||||
File: code,
|
File: code,
|
||||||
Temp: true,
|
Temp: true,
|
||||||
Args: option.Args,
|
Args: option.Args,
|
||||||
@@ -73,22 +73,13 @@ func GetType(option *GetTypeOptions) (clang.Type, *clang.Index, *clang.Translati
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
cursor := unit.Cursor()
|
cursor := unit.Cursor()
|
||||||
visitType := &typeVisitData{typ: &clang.Type{}, expectTypeKind: option.ExpectTypeKind}
|
var typ clang.Type
|
||||||
|
parse.VisitChildren(cursor, func(child, parent clang.Cursor) clang.ChildVisitResult {
|
||||||
clang.VisitChildren(cursor, typeVisit, unsafe.Pointer(visitType))
|
if child.Kind == clang.CursorVarDecl && (option.ExpectTypeKind == clang.TypeInvalid || option.ExpectTypeKind == child.Type().Kind) {
|
||||||
return *visitType.typ, index, unit
|
typ = child.Type()
|
||||||
}
|
return clang.ChildVisit_Break
|
||||||
|
}
|
||||||
type typeVisitData struct {
|
return clang.ChildVisit_Continue
|
||||||
typ *clang.Type
|
})
|
||||||
expectTypeKind clang.TypeKind
|
return typ, index, unit
|
||||||
}
|
|
||||||
|
|
||||||
func typeVisit(cursor, parent clang.Cursor, clientData unsafe.Pointer) clang.ChildVisitResult {
|
|
||||||
visitData := (*typeVisitData)(clientData)
|
|
||||||
if cursor.Kind == clang.CursorVarDecl && (visitData.expectTypeKind == clang.TypeInvalid || cursor.Type().Kind == visitData.expectTypeKind) {
|
|
||||||
*visitData.typ = cursor.Type()
|
|
||||||
return clang.ChildVisit_Break
|
|
||||||
}
|
|
||||||
return clang.ChildVisit_Continue
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ TestDoc Case 3:
|
|||||||
"_Type": "CommentGroup",
|
"_Type": "CommentGroup",
|
||||||
"List": [{
|
"List": [{
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": "/// doc"
|
"Text": "/// doc\n"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"Parent": null,
|
"Parent": null,
|
||||||
@@ -148,7 +148,7 @@ TestDoc Case 4:
|
|||||||
"_Type": "CommentGroup",
|
"_Type": "CommentGroup",
|
||||||
"List": [{
|
"List": [{
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": "/** doc */"
|
"Text": "/** doc */\n"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"Parent": null,
|
"Parent": null,
|
||||||
@@ -197,7 +197,7 @@ TestDoc Case 5:
|
|||||||
"_Type": "CommentGroup",
|
"_Type": "CommentGroup",
|
||||||
"List": [{
|
"List": [{
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": "/*! doc */"
|
"Text": "/*! doc */\n"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"Parent": null,
|
"Parent": null,
|
||||||
@@ -246,10 +246,10 @@ TestDoc Case 6:
|
|||||||
"_Type": "CommentGroup",
|
"_Type": "CommentGroup",
|
||||||
"List": [{
|
"List": [{
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": "/// doc 1"
|
"Text": "/// doc 1\n"
|
||||||
}, {
|
}, {
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": "/// doc 2"
|
"Text": "/// doc 2\n"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"Parent": null,
|
"Parent": null,
|
||||||
@@ -298,10 +298,10 @@ TestDoc Case 7:
|
|||||||
"_Type": "CommentGroup",
|
"_Type": "CommentGroup",
|
||||||
"List": [{
|
"List": [{
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": "/*! doc 1 */"
|
"Text": "/*! doc 1 */\n"
|
||||||
}, {
|
}, {
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": "/*! doc 2 */"
|
"Text": "/*! doc 2 */\n"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"Parent": null,
|
"Parent": null,
|
||||||
@@ -350,10 +350,10 @@ TestDoc Case 8:
|
|||||||
"_Type": "CommentGroup",
|
"_Type": "CommentGroup",
|
||||||
"List": [{
|
"List": [{
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": "/** doc 1 */"
|
"Text": "/** doc 1 */\n"
|
||||||
}, {
|
}, {
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": "/** doc 1 */"
|
"Text": "/** doc 1 */\n"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"Parent": null,
|
"Parent": null,
|
||||||
@@ -402,16 +402,16 @@ TestDoc Case 9:
|
|||||||
"_Type": "CommentGroup",
|
"_Type": "CommentGroup",
|
||||||
"List": [{
|
"List": [{
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": "/**"
|
"Text": "/**\n"
|
||||||
}, {
|
}, {
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": " * doc 1"
|
"Text": " * doc 1\n"
|
||||||
}, {
|
}, {
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": " * doc 2"
|
"Text": " * doc 2\n"
|
||||||
}, {
|
}, {
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": " */"
|
"Text": " */\n"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"Parent": null,
|
"Parent": null,
|
||||||
@@ -478,7 +478,7 @@ TestDoc Case 10:
|
|||||||
"_Type": "CommentGroup",
|
"_Type": "CommentGroup",
|
||||||
"List": [{
|
"List": [{
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": "/// doc"
|
"Text": "/// doc\n"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"Comment": null,
|
"Comment": null,
|
||||||
@@ -500,7 +500,7 @@ TestDoc Case 10:
|
|||||||
"_Type": "CommentGroup",
|
"_Type": "CommentGroup",
|
||||||
"List": [{
|
"List": [{
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": "///< comment"
|
"Text": "///< comment\n"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"IsStatic": false,
|
"IsStatic": false,
|
||||||
@@ -521,7 +521,7 @@ TestDoc Case 10:
|
|||||||
"_Type": "CommentGroup",
|
"_Type": "CommentGroup",
|
||||||
"List": [{
|
"List": [{
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": "/*!< comment */"
|
"Text": "/*!< comment */\n"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"IsStatic": false,
|
"IsStatic": false,
|
||||||
@@ -572,13 +572,13 @@ TestDoc Case 11:
|
|||||||
"_Type": "CommentGroup",
|
"_Type": "CommentGroup",
|
||||||
"List": [{
|
"List": [{
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": "/** "
|
"Text": "/** \n"
|
||||||
}, {
|
}, {
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": " * static field doc"
|
"Text": " * static field doc\n"
|
||||||
}, {
|
}, {
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": " */"
|
"Text": " */\n"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"Comment": null,
|
"Comment": null,
|
||||||
@@ -600,7 +600,7 @@ TestDoc Case 11:
|
|||||||
"_Type": "CommentGroup",
|
"_Type": "CommentGroup",
|
||||||
"List": [{
|
"List": [{
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": "/*!< static field comment */"
|
"Text": "/*!< static field comment */\n"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"IsStatic": true,
|
"IsStatic": true,
|
||||||
@@ -620,13 +620,13 @@ TestDoc Case 11:
|
|||||||
"_Type": "CommentGroup",
|
"_Type": "CommentGroup",
|
||||||
"List": [{
|
"List": [{
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": "/** "
|
"Text": "/** \n"
|
||||||
}, {
|
}, {
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": " * field doc"
|
"Text": " * field doc\n"
|
||||||
}, {
|
}, {
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": " */"
|
"Text": " */\n"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"Comment": null,
|
"Comment": null,
|
||||||
@@ -648,7 +648,7 @@ TestDoc Case 11:
|
|||||||
"_Type": "CommentGroup",
|
"_Type": "CommentGroup",
|
||||||
"List": [{
|
"List": [{
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": "///< field comment"
|
"Text": "///< field comment\n"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"IsStatic": false,
|
"IsStatic": false,
|
||||||
@@ -669,7 +669,7 @@ TestDoc Case 11:
|
|||||||
"_Type": "CommentGroup",
|
"_Type": "CommentGroup",
|
||||||
"List": [{
|
"List": [{
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": "/*!< protected field comment */"
|
"Text": "/*!< protected field comment */\n"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"IsStatic": false,
|
"IsStatic": false,
|
||||||
@@ -690,13 +690,13 @@ TestDoc Case 11:
|
|||||||
"_Type": "CommentGroup",
|
"_Type": "CommentGroup",
|
||||||
"List": [{
|
"List": [{
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": "/** "
|
"Text": "/** \n"
|
||||||
}, {
|
}, {
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": " * method doc"
|
"Text": " * method doc\n"
|
||||||
}, {
|
}, {
|
||||||
"_Type": "Comment",
|
"_Type": "Comment",
|
||||||
"Text": " */"
|
"Text": " */\n"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"Parent": {
|
"Parent": {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/goplus/llgo/c/cjson"
|
"github.com/goplus/llgo/c/cjson"
|
||||||
|
"github.com/goplus/llgo/chore/_xtool/llcppsymg/clangutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Context struct {
|
type Context struct {
|
||||||
@@ -49,7 +50,7 @@ func (p *Context) processFile(path string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Context) parseFile(path string) ([]*FileEntry, error) {
|
func (p *Context) parseFile(path string) ([]*FileEntry, error) {
|
||||||
converter, err := NewConverter(&Config{
|
converter, err := NewConverter(&clangutils.Config{
|
||||||
File: path,
|
File: path,
|
||||||
Temp: false,
|
Temp: false,
|
||||||
IsCpp: p.IsCpp,
|
IsCpp: p.IsCpp,
|
||||||
|
|||||||
Reference in New Issue
Block a user