diff --git a/_demo/cjsondemo/demo.go b/_demo/cjsondemo/demo.go index 0fdfa4fa..8f52e9a4 100644 --- a/_demo/cjsondemo/demo.go +++ b/_demo/cjsondemo/demo.go @@ -2,7 +2,7 @@ package main import ( "github.com/goplus/llgo/c" - cjson "github.com/goplus/llpkg/cjson" + "github.com/goplus/llpkg/cjson" ) func main() { diff --git a/_llcppgtest/cjson/conf/linux/llcppg.cfg b/_llcppgtest/cjson/conf/linux/llcppg.cfg index 4b68317a..02614da1 100644 --- a/_llcppgtest/cjson/conf/linux/llcppg.cfg +++ b/_llcppgtest/cjson/conf/linux/llcppg.cfg @@ -11,5 +11,15 @@ }, "trimPrefixes": ["cJSON_", "cJSONUtils_"], "cplusplus": false, - "mix":true + "mix":true, + "symMap": { + "cJSON_PrintUnformatted":".CStr", + "cJSON_CreateObject":"Object", + "cJSON_CreateArray":"Array", + "cJSON_CreateString":"String", + "cJSON_free":"FreeCStr", + "cJSON_AddItemToArray":".AddItem", + "cJSON_AddItemToObject":".SetItem", + "cJSON_free":"FreeCStr" + } } diff --git a/_llcppgtest/cjson/demo/hello/hello.go b/_llcppgtest/cjson/demo/hello/hello.go index e9e7bbe3..fcb1ddb6 100644 --- a/_llcppgtest/cjson/demo/hello/hello.go +++ b/_llcppgtest/cjson/demo/hello/hello.go @@ -1,9 +1,10 @@ package main import ( - "cjson" "unsafe" + "cjson" + "github.com/goplus/llgo/c" ) diff --git a/_llcppgtest/cjson/demo/readobj/readobj.go b/_llcppgtest/cjson/demo/readobj/readobj.go index 8ac3ad92..e4a68cba 100644 --- a/_llcppgtest/cjson/demo/readobj/readobj.go +++ b/_llcppgtest/cjson/demo/readobj/readobj.go @@ -1,9 +1,10 @@ package main import ( - "cjson" "fmt" + "cjson" + "github.com/goplus/llgo/c" ) diff --git a/_llcppgtest/cjson/llcppg.cfg b/_llcppgtest/cjson/llcppg.cfg index 6bd6fb11..c1bc20cd 100644 --- a/_llcppgtest/cjson/llcppg.cfg +++ b/_llcppgtest/cjson/llcppg.cfg @@ -10,5 +10,15 @@ "cJSON": "JSON" }, "trimPrefixes": ["cJSON_", "cJSONUtils_"], - "cplusplus": false + "cplusplus": false, + "symMap": { + "cJSON_PrintUnformatted":".CStr", + "cJSON_CreateObject":"Object", + "cJSON_CreateArray":"Array", + "cJSON_CreateString":"String", + "cJSON_free":"FreeCStr", + "cJSON_AddItemToArray":".AddItem", + "cJSON_AddItemToObject":".SetItem", + "cJSON_free":"FreeCStr" + } } diff --git a/_llcppgtest/cjson/llcppg.symb.json b/_llcppgtest/cjson/llcppg.symb.json deleted file mode 100644 index 43190f03..00000000 --- a/_llcppgtest/cjson/llcppg.symb.json +++ /dev/null @@ -1,42 +0,0 @@ -[ - { - "mangle": "cJSON_PrintUnformatted", - "c++": "cJSON_PrintUnformatted(const cJSON *)", - "go": "(*CJSON).CStr" - }, - { - "mangle": "cJSON_CreateObject", - "c++": "cJSON_CreateObject()", - "go": "Object" - }, - { - "mangle": "cJSON_CreateArray", - "c++": "cJSON_free()", - "go": "Array" - }, - { - "mangle": "cJSON_CreateString", - "c++": "cJSON_CreateString(const char *)", - "go": "String" - }, - { - "mangle": "cJSON_free", - "c++": "cJSON_free(void *)", - "go": "FreeCStr" - }, - { - "mangle": "cJSON_AddItemToArray", - "c++": "cJSON_AddItemToArray(cJSON *, cJSON *)", - "go": "(*CJSON).AddItem" - }, - { - "mangle": "cJSON_AddItemToObject", - "c++": "cJSON_AddItemToObject(cJSON *, const char *, cJSON *)", - "go": "(*CJSON).SetItem" - }, - { - "mangle": "cJSON_free", - "c++": "cJSON_free(void *)", - "go": "FreeCStr" - } -] diff --git a/_llcppgtest/raylib/llcppg.symb.json b/_llcppgtest/raylib/llcppg.symb.json deleted file mode 100644 index 8a030351..00000000 --- a/_llcppgtest/raylib/llcppg.symb.json +++ /dev/null @@ -1,7 +0,0 @@ -[ - { - "mangle": "ClearBackground", - "c++": "ClearBackground(Color)", - "go": "ClearBackground" - } -] diff --git a/_llcppgtest/sqlite/conf/linux/llcppg.cfg b/_llcppgtest/sqlite/conf/linux/llcppg.cfg index 8ca619c3..34906064 100644 --- a/_llcppgtest/sqlite/conf/linux/llcppg.cfg +++ b/_llcppgtest/sqlite/conf/linux/llcppg.cfg @@ -8,5 +8,8 @@ ], "trimPrefixes": ["sqlite3_","SQLITE_"], "cplusplus": false, - "mix":true + "mix":true, + "symMap":{ + "sqlite3_finalize":".Close" + } } diff --git a/_llcppgtest/sqlite/llcppg.cfg b/_llcppgtest/sqlite/llcppg.cfg index 6b3a8a37..0a447123 100644 --- a/_llcppgtest/sqlite/llcppg.cfg +++ b/_llcppgtest/sqlite/llcppg.cfg @@ -7,5 +7,8 @@ "sqlite3.h" ], "trimPrefixes": ["sqlite3_","SQLITE_"], - "cplusplus": false + "cplusplus": false, + "symMap":{ + "sqlite3_finalize":".Close" + } } diff --git a/_llcppgtest/sqlite/llcppg.symb.json b/_llcppgtest/sqlite/llcppg.symb.json deleted file mode 100644 index 97abf438..00000000 --- a/_llcppgtest/sqlite/llcppg.symb.json +++ /dev/null @@ -1,7 +0,0 @@ -[ - { - "mangle": "sqlite3_finalize", - "c++": "sqlite3_finalize(sqlite3_stmt *)", - "go": "(*Stmt).Close" - } -] diff --git a/_llcppgtest/zlib/conf/linux/llcppg.cfg b/_llcppgtest/zlib/conf/linux/llcppg.cfg index 6aaebd66..f4af172e 100644 --- a/_llcppgtest/zlib/conf/linux/llcppg.cfg +++ b/_llcppgtest/zlib/conf/linux/llcppg.cfg @@ -9,5 +9,12 @@ "trimPrefixes": ["Z_"], "cplusplus": false, "mix":true, - "deps":["c/os"] + "deps":["c/os"], + "symMap":{ + "compress":"Compress", + "compress2":"Compress2", + "uncompress":"Uncompress", + "uncompress2":"Uncompress2", + "compressBound":"CompressBound" + } } diff --git a/_llcppgtest/zlib/llcppg.cfg b/_llcppgtest/zlib/llcppg.cfg index bbfecc31..0549c239 100644 --- a/_llcppgtest/zlib/llcppg.cfg +++ b/_llcppgtest/zlib/llcppg.cfg @@ -8,5 +8,12 @@ ], "trimPrefixes": ["Z_"], "cplusplus": false, - "deps":["c/os"] + "deps":["c/os"], + "symMap":{ + "compress":"Compress", + "compress2":"Compress2", + "uncompress":"Uncompress", + "uncompress2":"Uncompress2", + "compressBound":"CompressBound" + } } diff --git a/_llcppgtest/zlib/llcppg.symb.json b/_llcppgtest/zlib/llcppg.symb.json deleted file mode 100644 index 25fef00c..00000000 --- a/_llcppgtest/zlib/llcppg.symb.json +++ /dev/null @@ -1,27 +0,0 @@ -[ - { - "mangle": "compress", - "c++": "compress(Bytef *, uLongf *, const Bytef *, uLong)", - "go": "Compress" - }, - { - "mangle": "compress2", - "c++": "compress2(Bytef *, uLongf *, const Bytef *, uLong, int)", - "go": "Compress2" - }, - { - "mangle": "uncompress", - "c++": "uncompress(Bytef *, uLongf *, const Bytef *, uLong)", - "go": "Uncompress" - }, - { - "mangle": "uncompress2", - "c++": "uncompress2(Bytef *, uLongf *, const Bytef *, uLong *)", - "go": "Uncompress2" - }, - { - "mangle": "compressBound", - "c++": "compressBound(uLong)", - "go": "CompressBound" - } -] diff --git a/_xtool/llcppsigfetch/dbg/debug.go b/_xtool/llcppsigfetch/dbg/debug.go index 5d74bbc2..adce6783 100644 --- a/_xtool/llcppsigfetch/dbg/debug.go +++ b/_xtool/llcppsigfetch/dbg/debug.go @@ -5,8 +5,13 @@ type dbgFlags = int var flags dbgFlags const ( - DbgParse dbgFlags = 1 << iota - DbgFlagAll = DbgParse + DbgParse dbgFlags = 1 << iota + DbgVisitTop + DbgProcess + DbgGetCurFile + DbgMacro + DbgFileType + DbgFlagAll = DbgParse ) func SetDebugParse() { @@ -20,3 +25,43 @@ func GetDebugParse() bool { func SetDebugAll() { flags = DbgFlagAll } + +func SetDebugVisitTop() { + flags |= DbgVisitTop +} + +func GetDebugVisitTop() bool { + return flags&DbgVisitTop != 0 +} + +func SetDebugProcess() { + flags |= DbgProcess +} + +func GetDebugProcess() bool { + return flags&DbgProcess != 0 +} + +func SetDebugGetCurFile() { + flags |= DbgGetCurFile +} + +func GetDebugGetCurFile() bool { + return flags&DbgGetCurFile != 0 +} + +func SetDebugMacro() { + flags |= DbgMacro +} + +func GetDebugMacro() bool { + return flags&DbgMacro != 0 +} + +func SetDebugFileType() { + flags |= DbgFileType +} + +func GetDebugFileType() bool { + return flags&DbgFileType != 0 +} diff --git a/_xtool/llcppsigfetch/dbg/debug_test.go b/_xtool/llcppsigfetch/dbg/debug_test.go new file mode 100644 index 00000000..2997d708 --- /dev/null +++ b/_xtool/llcppsigfetch/dbg/debug_test.go @@ -0,0 +1,129 @@ +package dbg + +import "testing" + +func TestSetDebugParse(t *testing.T) { + tests := []struct { + name string + }{ + { + name: "TestSetDebugParse", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugParse() + if !GetDebugParse() { + t.Errorf("GetDebugParse() = %v, want %v", false, true) + } + }) + } +} + +func TestSetDebugAll(t *testing.T) { + tests := []struct { + name string + }{ + { + name: "TestSetDebugAll", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugAll() + if flags != DbgFlagAll { + t.Errorf("flags = %v, want %v", flags, DbgFlagAll) + } + }) + } +} + +func TestSetDebugVisitTop(t *testing.T) { + tests := []struct { + name string + }{ + { + name: "TestSetDebugVisitTop", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugVisitTop() + if !GetDebugVisitTop() { + t.Errorf("GetDebugVisitTop() = %v, want %v", false, true) + } + }) + } +} + +func TestSetDebugProcess(t *testing.T) { + tests := []struct { + name string + }{ + { + name: "TestSetDebugProcess", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugProcess() + if !GetDebugProcess() { + t.Errorf("GetDebugProcess() = %v, want %v", false, true) + } + }) + } +} + +func TestSetDebugGetCurFile(t *testing.T) { + tests := []struct { + name string + }{ + { + name: "TestSetDebugGetCurFile", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugGetCurFile() + if !GetDebugGetCurFile() { + t.Errorf("GetDebugGetCurFile() = %v, want %v", false, true) + } + }) + } +} + +func TestSetDebugMacro(t *testing.T) { + tests := []struct { + name string + }{ + { + name: "TestSetDebugMacro", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugMacro() + if !GetDebugMacro() { + t.Errorf("GetDebugMacro() = %v, want %v", false, true) + } + }) + } +} + +func TestSetDebugFileType(t *testing.T) { + tests := []struct { + name string + }{ + { + name: "TestSetDebugFileType", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugFileType() + if !GetDebugFileType() { + t.Errorf("GetDebugFileType() = %v, want %v", false, true) + } + }) + } +} diff --git a/_xtool/llcppsigfetch/parse/cvt.go b/_xtool/llcppsigfetch/parse/cvt.go index e8acdd17..e6856c01 100644 --- a/_xtool/llcppsigfetch/parse/cvt.go +++ b/_xtool/llcppsigfetch/parse/cvt.go @@ -155,10 +155,14 @@ func (ct *Converter) InFile(cursor clang.Cursor) bool { var file clang.String loc.PresumedLocation(&file, nil, nil) filePath := clang.GoString(file) - ct.logf("GetCurFile: PresumedLocation %s cursor.Location() %s\n", filePath, clang.GoString(loc.File().FileName())) + if dbg.GetDebugGetCurFile() { + ct.logf("GetCurFile: PresumedLocation %s cursor.Location() %s\n", filePath, clang.GoString(loc.File().FileName())) + } if filePath == "" || filePath == "" { //todo(zzy): For some built-in macros, there is no file. - ct.logln("GetCurFile: NO FILE") + if dbg.GetDebugGetCurFile() { + ct.logln("GetCurFile: NO FILE") + } return false } return true @@ -229,7 +233,9 @@ func (ct *Converter) visitTop(cursor, parent clang.Cursor) clang.ChildVisitResul inFile := ct.InFile(cursor) name := toStr(cursor.String()) - ct.logf("visitTop: Cursor: %s\n", name) + if dbg.GetDebugVisitTop() { + ct.logf("visitTop: Cursor: %s\n", name) + } if !inFile { return clang.ChildVisit_Continue @@ -243,17 +249,23 @@ func (ct *Converter) visitTop(cursor, parent clang.Cursor) clang.ChildVisitResul return clang.ChildVisit_Continue } ct.Pkg.File.Includes = append(ct.Pkg.File.Includes, include) - ct.logln("visitTop: ProcessInclude END ", include.Path) + if dbg.GetDebugVisitTop() { + ct.logln("visitTop: ProcessInclude END ", include.Path) + } case clang.CursorMacroDefinition: macro := ct.ProcessMacro(cursor) if cursor.IsMacroBuiltin() == 0 { ct.Pkg.File.Macros = append(ct.Pkg.File.Macros, macro) } - ct.logln("visitTop: ProcessMacro END ", macro.Name, "Tokens Length:", len(macro.Tokens)) + if dbg.GetDebugVisitTop() { + ct.logln("visitTop: ProcessMacro END ", macro.Name, "Tokens Length:", len(macro.Tokens)) + } case clang.CursorEnumDecl: enum := ct.ProcessEnumDecl(cursor) ct.Pkg.File.Decls = append(ct.Pkg.File.Decls, enum) - ct.logf("visitTop: ProcessEnumDecl END") + if dbg.GetDebugVisitTop() { + ct.logf("visitTop: ProcessEnumDecl END") + } if enum.Name != nil { ct.logln(enum.Name.Name) } else { @@ -264,11 +276,15 @@ func (ct *Converter) visitTop(cursor, parent clang.Cursor) clang.ChildVisitResul classDecl := ct.ProcessClassDecl(cursor) ct.Pkg.File.Decls = append(ct.Pkg.File.Decls, classDecl) // class havent anonymous situation - ct.logln("visitTop: ProcessClassDecl END", classDecl.Name.Name) + if dbg.GetDebugVisitTop() { + ct.logln("visitTop: ProcessClassDecl END", classDecl.Name.Name) + } case clang.CursorStructDecl: structDecl := ct.ProcessStructDecl(cursor) ct.Pkg.File.Decls = append(ct.Pkg.File.Decls, structDecl) - ct.logf("visitTop: ProcessStructDecl END") + if dbg.GetDebugVisitTop() { + ct.logf("visitTop: ProcessStructDecl END") + } if structDecl.Name != nil { ct.logln(structDecl.Name.Name) } else { @@ -277,7 +293,9 @@ func (ct *Converter) visitTop(cursor, parent clang.Cursor) clang.ChildVisitResul case clang.CursorUnionDecl: unionDecl := ct.ProcessUnionDecl(cursor) ct.Pkg.File.Decls = append(ct.Pkg.File.Decls, unionDecl) - ct.logf("visitTop: ProcessUnionDecl END") + if dbg.GetDebugVisitTop() { + ct.logf("visitTop: ProcessUnionDecl END") + } if unionDecl.Name != nil { ct.logln(unionDecl.Name.Name) } else { @@ -288,14 +306,18 @@ func (ct *Converter) visitTop(cursor, parent clang.Cursor) clang.ChildVisitResul // Example: void MyClass::myMethod() { ... } out-of-class method funcDecl := ct.ProcessFuncDecl(cursor) ct.Pkg.File.Decls = append(ct.Pkg.File.Decls, funcDecl) - ct.logln("visitTop: ProcessFuncDecl END", funcDecl.Name.Name, funcDecl.MangledName, "isStatic:", funcDecl.IsStatic, "isInline:", funcDecl.IsInline) + if dbg.GetDebugVisitTop() { + ct.logln("visitTop: ProcessFuncDecl END", funcDecl.Name.Name, funcDecl.MangledName, "isStatic:", funcDecl.IsStatic, "isInline:", funcDecl.IsInline) + } case clang.CursorTypedefDecl: typedefDecl := ct.ProcessTypeDefDecl(cursor) if typedefDecl == nil { return clang.ChildVisit_Continue } ct.Pkg.File.Decls = append(ct.Pkg.File.Decls, typedefDecl) - ct.logln("visitTop: ProcessTypeDefDecl END", typedefDecl.Name.Name) + if dbg.GetDebugVisitTop() { + ct.logln("visitTop: ProcessTypeDefDecl END", typedefDecl.Name.Name) + } case clang.CursorNamespace: clangutils.VisitChildren(cursor, ct.visitTop) } @@ -315,7 +337,9 @@ func (ct *Converter) ProcessType(t clang.Type) ast.Expr { defer ct.decIndent() typeName, typeKind := getTypeDesc(t) - ct.logln("ProcessType: TypeName:", typeName, "TypeKind:", typeKind) + if dbg.GetDebugProcess() { + ct.logln("ProcessType: TypeName:", typeName, "TypeKind:", typeKind) + } if t.Kind >= clang.TypeFirstBuiltin && t.Kind <= clang.TypeLastBuiltin { return ct.ProcessBuiltinType(t) @@ -333,21 +357,29 @@ func (ct *Converter) ProcessType(t clang.Type) ast.Expr { switch t.Kind { case clang.TypePointer: name, kind := getTypeDesc(t.PointeeType()) - ct.logln("ProcessType: PointerType Pointee TypeName:", name, "TypeKind:", kind) + if dbg.GetDebugProcess() { + ct.logln("ProcessType: PointerType Pointee TypeName:", name, "TypeKind:", kind) + } expr = &ast.PointerType{X: ct.ProcessType(t.PointeeType())} case clang.TypeLValueReference: name, kind := getTypeDesc(t.NonReferenceType()) - ct.logln("ProcessType: LvalueRefType NonReference TypeName:", name, "TypeKind:", kind) + if dbg.GetDebugProcess() { + ct.logln("ProcessType: LvalueRefType NonReference TypeName:", name, "TypeKind:", kind) + } expr = &ast.LvalueRefType{X: ct.ProcessType(t.NonReferenceType())} case clang.TypeRValueReference: name, kind := getTypeDesc(t.NonReferenceType()) - ct.logln("ProcessType: RvalueRefType NonReference TypeName:", name, "TypeKind:", kind) + if dbg.GetDebugProcess() { + ct.logln("ProcessType: RvalueRefType NonReference TypeName:", name, "TypeKind:", kind) + } expr = &ast.RvalueRefType{X: ct.ProcessType(t.NonReferenceType())} case clang.TypeFunctionProto, clang.TypeFunctionNoProto: // treating TypeFunctionNoProto as a general function without parameters // function type will only collect return type, params will be collected in ProcessFuncDecl name, kind := getTypeDesc(t) - ct.logln("ProcessType: FunctionType TypeName:", name, "TypeKind:", kind) + if dbg.GetDebugProcess() { + ct.logln("ProcessType: FunctionType TypeName:", name, "TypeKind:", kind) + } expr = ct.ProcessFunctionType(t) case clang.TypeConstantArray, clang.TypeIncompleteArray, clang.TypeVariableArray, clang.TypeDependentSizedArray: if t.Kind == clang.TypeConstantArray { @@ -366,7 +398,9 @@ func (ct *Converter) ProcessType(t clang.Type) ast.Expr { } default: name, kind := getTypeDesc(t) - ct.logln("ProcessType: Unknown Type TypeName:", name, "TypeKind:", kind) + if dbg.GetDebugProcess() { + ct.logln("ProcessType: Unknown Type TypeName:", name, "TypeKind:", kind) + } } return expr } @@ -378,15 +412,18 @@ func (ct *Converter) ProcessFunctionType(t clang.Type) *ast.FuncType { ct.incIndent() defer ct.decIndent() typeName, typeKind := getTypeDesc(t) - ct.logln("ProcessFunctionType: TypeName:", typeName, "TypeKind:", typeKind) + if dbg.GetDebugProcess() { + ct.logln("ProcessFunctionType: TypeName:", typeName, "TypeKind:", typeKind) + } // Note: Attempting to get the type declaration for a function type will result in CursorNoDeclFound // cursor := t.TypeDeclaration() // This would return CursorNoDeclFound resType := t.ResultType() name, kind := getTypeDesc(resType) - ct.logln("ProcessFunctionType: ResultType TypeName:", name, "TypeKind:", kind) - + if dbg.GetDebugProcess() { + ct.logln("ProcessFunctionType: ResultType TypeName:", name, "TypeKind:", kind) + } ret := ct.ProcessType(resType) params := &ast.FieldList{} numArgs := t.NumArgTypes() @@ -412,8 +449,9 @@ func (ct *Converter) ProcessTypeDefDecl(cursor clang.Cursor) *ast.TypedefDecl { ct.incIndent() defer ct.decIndent() name, kind := getCursorDesc(cursor) - ct.logln("ProcessTypeDefDecl: CursorName:", name, "CursorKind:", kind, "CursorTypeKind:", toStr(cursor.Type().Kind.String())) - + if dbg.GetDebugProcess() { + ct.logln("ProcessTypeDefDecl: CursorName:", name, "CursorKind:", kind, "CursorTypeKind:", toStr(cursor.Type().Kind.String())) + } typ := ct.ProcessUnderlyingType(cursor) // For cases like: typedef struct { int x; } Name; // libclang incorrectly reports the anonymous structure as a named structure @@ -436,15 +474,18 @@ func (ct *Converter) ProcessUnderlyingType(cursor clang.Cursor) ast.Expr { underlyingTyp := cursor.TypedefDeclUnderlyingType() if underlyingTyp.Kind != clang.TypeElaborated { - ct.logln("ProcessUnderlyingType: not elaborated") + if dbg.GetDebugProcess() { + ct.logln("ProcessUnderlyingType: not elaborated") + } return ct.ProcessType(underlyingTyp) } referTypeCursor := underlyingTyp.TypeDeclaration() defName := toStr(cursor.String()) underName := toStr(referTypeCursor.String()) - ct.logln("ProcessUnderlyingType: defName:", defName, "underName:", underName) - + if dbg.GetDebugProcess() { + ct.logln("ProcessUnderlyingType: defName:", defName, "underName:", underName) + } // For a typedef like "typedef struct xxx xxx;", the underlying type declaration // can appear in two locations: // 1. Inside the typedef itself when the struct is defined inline @@ -453,7 +494,9 @@ func (ct *Converter) ProcessUnderlyingType(cursor clang.Cursor) ast.Expr { // Therefore, we shouldn't use declaration location to determine whether to remove // extra typedef nodes if defName == underName { - ct.logln("ProcessUnderlyingType: is self reference") + if dbg.GetDebugProcess() { + ct.logln("ProcessUnderlyingType: is self reference") + } return nil } @@ -498,27 +541,34 @@ func (ct *Converter) ProcessFuncDecl(cursor clang.Cursor) *ast.FuncDecl { defer ct.decIndent() name, kind := getCursorDesc(cursor) mangledName := toStr(cursor.Mangling()) - ct.logln("ProcessFuncDecl: CursorName:", name, "CursorKind:", kind, "mangledName:", mangledName) - + if dbg.GetDebugProcess() { + ct.logln("ProcessFuncDecl: CursorName:", name, "CursorKind:", kind, "mangledName:", mangledName) + } // function type will only collect return type // ProcessType can't get the field names,will collect in follows fnType := cursor.Type() typName, typKind := getTypeDesc(fnType) - ct.logln("ProcessFuncDecl: TypeName:", typName, "TypeKind:", typKind) - + if dbg.GetDebugProcess() { + ct.logln("ProcessFuncDecl: TypeName:", typName, "TypeKind:", typKind) + } typeToProcess := fnType if fnType.Kind == clang.TypeElaborated { typeToProcess = ct.getActualType(fnType) actualTypeName, actualTypeKind := getTypeDesc(typeToProcess) - ct.logln("ProcessFuncDecl: ActualType TypeName:", actualTypeName, "TypeKind:", actualTypeKind) + if dbg.GetDebugProcess() { + ct.logln("ProcessFuncDecl: ActualType TypeName:", actualTypeName, "TypeKind:", actualTypeKind) + } } funcType, ok := ct.ProcessType(typeToProcess).(*ast.FuncType) if !ok { - ct.logln("ProcessFuncDecl: failed to process function type") + if dbg.GetDebugProcess() { + ct.logln("ProcessFuncDecl: failed to process function type") + } return nil } - ct.logln("ProcessFuncDecl: ProcessFieldList") - + if dbg.GetDebugProcess() { + ct.logln("ProcessFuncDecl: ProcessFieldList") + } // For function type references (e.g. `typedef void (fntype)(); fntype foo;`), // params are already processed in ProcessType via CanonicalType if fnType.Kind != clang.TypeElaborated { @@ -551,7 +601,9 @@ func (ct *Converter) ProcessFuncDecl(cursor clang.Cursor) *ast.FuncDecl { } if isMethod(cursor) { - ct.logln("ProcessFuncDecl: is method, ProcessMethodAttributes") + if dbg.GetDebugProcess() { + ct.logln("ProcessFuncDecl: is method, ProcessMethodAttributes") + } ct.ProcessMethodAttributes(cursor, funcDecl) } else { if cursor.StorageClass() == clang.SCStatic { @@ -628,8 +680,9 @@ func (ct *Converter) ProcessEnumType(cursor clang.Cursor) *ast.EnumType { func (ct *Converter) ProcessEnumDecl(cursor clang.Cursor) *ast.EnumTypeDecl { cursorName, cursorKind := getCursorDesc(cursor) - ct.logln("ProcessEnumDecl: CursorName:", cursorName, "CursorKind:", cursorKind) - + if dbg.GetDebugProcess() { + ct.logln("ProcessEnumDecl: CursorName:", cursorName, "CursorKind:", cursorKind) + } decl := &ast.EnumTypeDecl{ DeclBase: ct.CreateDeclBase(cursor), Type: ct.ProcessEnumType(cursor), @@ -638,9 +691,13 @@ func (ct *Converter) ProcessEnumDecl(cursor clang.Cursor) *ast.EnumTypeDecl { anony := cursor.IsAnonymous() if anony == 0 { decl.Name = &ast.Ident{Name: cursorName} - ct.logln("ProcessEnumDecl: has name", cursorName) + if dbg.GetDebugProcess() { + ct.logln("ProcessEnumDecl: has name", cursorName) + } } else { - ct.logln("ProcessRecordDecl: is anonymous") + if dbg.GetDebugProcess() { + ct.logln("ProcessRecordDecl: is anonymous") + } } return decl @@ -675,7 +732,9 @@ func (ct *Converter) createBaseField(cursor clang.Cursor) *ast.Field { typ := cursor.Type() typeName, typeKind := getTypeDesc(typ) - ct.logf("createBaseField: ProcessType %s TypeKind: %s", typeName, typeKind) + if dbg.GetDebugProcess() { + ct.logf("createBaseField: ProcessType %s TypeKind: %s", typeName, typeKind) + } field := &ast.Field{ Type: ct.ProcessType(typ), @@ -700,7 +759,9 @@ func (ct *Converter) ProcessFieldList(cursor clang.Cursor) *ast.FieldList { ct.incIndent() defer ct.decIndent() flds := &ast.FieldList{} - ct.logln("ProcessFieldList: VisitChildren") + if dbg.GetDebugProcess() { + ct.logln("ProcessFieldList: VisitChildren") + } clangutils.VisitChildren(cursor, func(subcsr, parent clang.Cursor) clang.ChildVisitResult { switch subcsr.Kind { case clang.CursorFieldDecl: @@ -711,7 +772,9 @@ func (ct *Converter) ProcessFieldList(cursor clang.Cursor) *ast.FieldList { // struct A { // int a, b; // }; - ct.logln("ProcessFieldList: CursorFieldDecl") + if dbg.GetDebugProcess() { + ct.logln("ProcessFieldList: CursorFieldDecl") + } field := ct.createBaseField(subcsr) field.Access = ast.AccessSpecifier(subcsr.CXXAccessSpecifier()) flds.List = append(flds.List, field) @@ -748,8 +811,9 @@ func (ct *Converter) ProcessRecordDecl(cursor clang.Cursor) *ast.TypeDecl { ct.incIndent() defer ct.decIndent() cursorName, cursorKind := getCursorDesc(cursor) - ct.logln("ProcessRecordDecl: CursorName:", cursorName, "CursorKind:", cursorKind) - + if dbg.GetDebugProcess() { + ct.logln("ProcessRecordDecl: CursorName:", cursorName, "CursorKind:", cursorKind) + } decl := &ast.TypeDecl{ DeclBase: ct.CreateDeclBase(cursor), Type: ct.ProcessRecordType(cursor), @@ -758,9 +822,13 @@ func (ct *Converter) ProcessRecordDecl(cursor clang.Cursor) *ast.TypeDecl { anony := cursor.IsAnonymousRecordDecl() if anony == 0 { decl.Name = &ast.Ident{Name: cursorName} - ct.logln("ProcessRecordDecl: has name", cursorName) + if dbg.GetDebugProcess() { + ct.logln("ProcessRecordDecl: has name", cursorName) + } } else { - ct.logln("ProcessRecordDecl: is anonymous") + if dbg.GetDebugProcess() { + ct.logln("ProcessRecordDecl: is anonymous") + } } return decl @@ -776,8 +844,9 @@ func (ct *Converter) ProcessUnionDecl(cursor clang.Cursor) *ast.TypeDecl { func (ct *Converter) ProcessClassDecl(cursor clang.Cursor) *ast.TypeDecl { cursorName, cursorKind := getCursorDesc(cursor) - ct.logln("ProcessClassDecl: CursorName:", cursorName, "CursorKind:", cursorKind) - + if dbg.GetDebugProcess() { + ct.logln("ProcessClassDecl: CursorName:", cursorName, "CursorKind:", cursorKind) + } // Pushing class scope before processing its type and popping after base := ct.CreateDeclBase(cursor) typ := ct.ProcessRecordType(cursor) @@ -796,15 +865,20 @@ func (ct *Converter) ProcessRecordType(cursor clang.Cursor) *ast.RecordType { defer ct.decIndent() cursorName, cursorKind := getCursorDesc(cursor) - ct.logln("ProcessRecordType: CursorName:", cursorName, "CursorKind:", cursorKind) - + if dbg.GetDebugProcess() { + ct.logln("ProcessRecordType: CursorName:", cursorName, "CursorKind:", cursorKind) + } tag := toTag(cursor.Kind) - ct.logln("ProcessRecordType: toTag", tag) + if dbg.GetDebugProcess() { + ct.logln("ProcessRecordType: toTag", tag) + ct.logln("ProcessRecordType: ProcessFieldList") + } - ct.logln("ProcessRecordType: ProcessFieldList") fields := ct.ProcessFieldList(cursor) - ct.logln("ProcessRecordType: ProcessMethods") + if dbg.GetDebugProcess() { + ct.logln("ProcessRecordType: ProcessMethods") + } methods := ct.ProcessMethods(cursor) return &ast.RecordType{ @@ -827,8 +901,9 @@ func (ct *Converter) ProcessElaboratedType(t clang.Type) ast.Expr { ct.incIndent() defer ct.decIndent() typeName, typeKind := getTypeDesc(t) - ct.logln("ProcessElaboratedType: TypeName:", typeName, "TypeKind:", typeKind) - + if dbg.GetDebugProcess() { + ct.logln("ProcessElaboratedType: TypeName:", typeName, "TypeKind:", typeKind) + } decl := t.TypeDeclaration() if decl.IsAnonymous() != 0 { @@ -856,11 +931,15 @@ func (ct *Converter) ProcessElaboratedType(t clang.Type) ast.Expr { func (ct *Converter) ProcessTypeDefType(t clang.Type) ast.Expr { cursor := t.TypeDeclaration() - ct.logln("ProcessTypeDefType: Typedef TypeDeclaration", toStr(cursor.String()), toStr(t.String())) + if dbg.GetDebugProcess() { + ct.logln("ProcessTypeDefType: Typedef TypeDeclaration", toStr(cursor.String()), toStr(t.String())) + } if name := toStr(cursor.String()); name != "" { return &ast.Ident{Name: name} } - ct.logln("ProcessTypeDefType: typedef type have no name") + if dbg.GetDebugProcess() { + ct.logln("ProcessTypeDefType: typedef type have no name") + } return nil } @@ -868,8 +947,9 @@ func (ct *Converter) ProcessBuiltinType(t clang.Type) *ast.BuiltinType { ct.incIndent() defer ct.decIndent() typeName, typeKind := getTypeDesc(t) - ct.logln("ProcessBuiltinType: TypeName:", typeName, "TypeKind:", typeKind) - + if dbg.GetDebugProcess() { + ct.logln("ProcessBuiltinType: TypeName:", typeName, "TypeKind:", typeKind) + } kind := ast.Void var flags ast.TypeFlag diff --git a/_xtool/llcppsigfetch/parse/parse.go b/_xtool/llcppsigfetch/parse/parse.go index 51cb49c9..341869b3 100644 --- a/_xtool/llcppsigfetch/parse/parse.go +++ b/_xtool/llcppsigfetch/parse/parse.go @@ -68,7 +68,7 @@ func Do(cfg *ParseConfig) (*Converter, error) { libclangFlags = append(libclangFlags, "-resource-dir="+ClangResourceDir, "-I"+path.Join(ClangResourceDir, "include")) } pkgHfiles := config.PkgHfileInfo(cfg.Conf, libclangFlags) - if dbg.GetDebugParse() { + if dbg.GetDebugFileType() { fmt.Fprintln(os.Stderr, "interfaces", pkgHfiles.Inters) fmt.Fprintln(os.Stderr, "implements", pkgHfiles.Impls) fmt.Fprintln(os.Stderr, "thirdhfile", pkgHfiles.Thirds) @@ -90,7 +90,7 @@ func Do(cfg *ParseConfig) (*Converter, error) { if err != nil { return nil, err } - if dbg.GetDebugParse() { + if dbg.GetDebugMacro() { fmt.Fprintln(os.Stderr, "Have %d Macros", len(pkg.File.Macros)) for _, macro := range pkg.File.Macros { fmt.Fprintf(os.Stderr, "Macro %s", macro.Name) diff --git a/_xtool/llcppsymg/_cmptest/config_test/config.go b/_xtool/llcppsymg/_cmptest/config_test/config.go index c77d88bb..8a29b34f 100644 --- a/_xtool/llcppsymg/_cmptest/config_test/config.go +++ b/_xtool/llcppsymg/_cmptest/config_test/config.go @@ -116,16 +116,15 @@ func TestGenDylibPaths() { fmt.Println("=== Test GenDylibPaths ===") tempDir := os.TempDir() - tempDefaultPath := filepath.Join(tempDir, "symblib") + tempDefaultPath, err := os.MkdirTemp(tempDir, "symblib") + if err != nil { + fmt.Println(err) + return + } affix := ".dylib" if runtime.GOOS == "linux" { affix = ".so" } - err := os.MkdirAll(tempDefaultPath, 0755) - if err != nil { - fmt.Printf("Failed to create temp default path: %v\n", err) - return - } dylib1 := filepath.Join(tempDir, "libsymb1"+affix) dylib2 := filepath.Join(tempDir, "libsymb2"+affix) @@ -264,11 +263,14 @@ func TestGenHeaderFilePath() { fmt.Println("=== Test GenHeaderFilePath ===") tempDir := os.TempDir() - temDir2 := filepath.Join(tempDir, "include") + temDir2, err := os.MkdirTemp(tempDir, "include") + if err != nil { + fmt.Println(err) + return + } tempFile1 := filepath.Join(tempDir, "test1.h") tempFile2 := filepath.Join(tempDir, "test2.h") tempFile3 := filepath.Join(temDir2, "test3.h") - os.MkdirAll(temDir2, 0755) os.Create(tempFile1) os.Create(tempFile2) os.Create(tempFile3) diff --git a/_xtool/llcppsymg/_cmptest/names_test/names.go b/_xtool/llcppsymg/_cmptest/names_test/names.go index 2a6f0ced..6786995d 100644 --- a/_xtool/llcppsymg/_cmptest/names_test/names.go +++ b/_xtool/llcppsymg/_cmptest/names_test/names.go @@ -17,9 +17,12 @@ func main() { func TestToGoName() { fmt.Println("=== Test ToGoName ===") - process1 := parse.NewSymbolProcessor([]string{}, []string{"lua_", "luaL_"}) - process2 := parse.NewSymbolProcessor([]string{}, []string{"sqlite3_", "sqlite3_"}) - process3 := parse.NewSymbolProcessor([]string{}, []string{"INI"}) + config1 := parse.NewConfig([]string{}, []string{"lua_", "luaL_"}, []string{}, false, nil) + process1 := parse.NewSymbolProcessor(config1) + config2 := parse.NewConfig([]string{}, []string{"sqlite3_", "sqlite3_"}, []string{}, false, nil) + process2 := parse.NewSymbolProcessor(config2) + config3 := parse.NewConfig([]string{}, []string{"INI"}, []string{}, false, nil) + process3 := parse.NewSymbolProcessor(config3) testCases := []struct { processor *parse.SymbolProcessor diff --git a/_xtool/llcppsymg/_cmptest/parse_test/parse.go b/_xtool/llcppsymg/_cmptest/parse_test/parse.go index 7112f76c..68175c39 100644 --- a/_xtool/llcppsymg/_cmptest/parse_test/parse.go +++ b/_xtool/llcppsymg/_cmptest/parse_test/parse.go @@ -17,7 +17,8 @@ func main() { func TestNewSymbolProcessor() { fmt.Println("=== Test NewSymbolProcessor ===") - process := parse.NewSymbolProcessor([]string{}, []string{"lua_", "luaL_"}) + config := parse.NewConfig([]string{}, []string{"lua_", "luaL_"}, []string{}, false, nil) + process := parse.NewSymbolProcessor(config) fmt.Printf("Before: No prefixes After: Prefixes: %v\n", process.Prefixes) fmt.Println() } @@ -45,7 +46,8 @@ func TestGenMethodName() { func TestAddSuffix() { fmt.Println("=== Test AddSuffix ===") - process := parse.NewSymbolProcessor([]string{}, []string{"INI"}) + config := parse.NewConfig([]string{}, []string{"INI"}, []string{}, false, nil) + process := parse.NewSymbolProcessor(config) methods := []string{ "INIReader", "INIReader", @@ -157,7 +159,8 @@ int(lua_sizecomp)(size_t s, int idx1, int idx2, int op); for _, tc := range testCases { fmt.Printf("=== Test Case: %s ===\n", tc.name) - symbolMap, err := parse.ParseHeaderFile([]string{tc.content}, tc.prefixes, []string{}, tc.isCpp, true) + config := parse.NewConfig([]string{tc.content}, tc.prefixes, []string{}, tc.isCpp, nil) + symbolMap, err := parse.ParseHeaderFile(config, true) if err != nil { fmt.Printf("Error: %v\n", err) diff --git a/_xtool/llcppsymg/_cmptest/symbol_test/llgo.expect b/_xtool/llcppsymg/_cmptest/symbol_test/llgo.expect index dbe89b8d..160558fd 100644 --- a/_xtool/llcppsymg/_cmptest/symbol_test/llgo.expect +++ b/_xtool/llcppsymg/_cmptest/symbol_test/llgo.expect @@ -14,13 +14,6 @@ Mangle: _ZNK9INIReader10ParseErrorEv, CPP: INIReader::ParseError(), Go: (*Reader Mangle: _ZNK9INIReader12GetInteger64ERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEES8_x, CPP: INIReader::GetInteger64(const std::string &, const std::string &, int64_t), Go: (*Reader).GetInteger64 Mangle: _ZNK9INIReader7GetRealERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEES8_d, CPP: INIReader::GetReal(const std::string &, const std::string &, double), Go: (*Reader).GetReal -=== Test ReadExistingSymbolTable === -Symbols read from the file: -Symbol Map GoName: (*Reader).Init__1, ProtoName In HeaderFile: INIReader::INIReader(const char *, size_t), MangledName: _ZN9INIReaderC1EPKcm -Symbol Map GoName: (*Reader).GetBoolean, ProtoName In HeaderFile: INIReader::GetBoolean(const std::string &, const std::string &, bool), MangledName: _ZNK9INIReader10GetBooleanERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEES8_b -Symbol Map GoName: (*Reader).ParseError, ProtoName In HeaderFile: INIReader::ParseError(), MangledName: _ZNK9INIReader10ParseErrorEv -Havent existed symb file - === Test GenSymbolTableData === [{ "mangle": "lua_absindex", @@ -37,7 +30,7 @@ Havent existed symb file }, { "mangle": "lua_callk", "c++": "lua_callk(lua_State *, int, int, lua_KContext, lua_KFunction)", - "go": "ModifiedCallk" + "go": "Callk" }] diff --git a/_xtool/llcppsymg/_cmptest/symbol_test/symbol.go b/_xtool/llcppsymg/_cmptest/symbol_test/symbol.go index 047b4fa1..b87bea16 100644 --- a/_xtool/llcppsymg/_cmptest/symbol_test/symbol.go +++ b/_xtool/llcppsymg/_cmptest/symbol_test/symbol.go @@ -13,7 +13,6 @@ import ( func main() { TestGetCommonSymbols() - TestReadExistingSymbolTable() TestGenSymbolTableData() } @@ -136,13 +135,7 @@ func TestGenSymbolTableData() { {Mangle: "lua_callk", CPP: "lua_callk(lua_State *, int, int, lua_KContext, lua_KFunction)", Go: "Callk"}, } - existingSymbols := map[string]llcppg.SymbolInfo{ - "lua_absindex": {Mangle: "lua_absindex", CPP: "lua_absindex(lua_State *, int)", Go: "Absindex"}, - "lua_arith": {Mangle: "lua_arith", CPP: "lua_arith(lua_State *, int)", Go: "Arith"}, - "lua_callk": {Mangle: "lua_callk", CPP: "lua_callk(lua_State *, int, int, lua_KContext, lua_KFunction)", Go: "ModifiedCallk"}, - } - - data, err := symbol.GenSymbolTableData(commonSymbols, existingSymbols) + data, err := symbol.GenSymbolTableData(commonSymbols) if err != nil { fmt.Printf("Error generating symbol table data: %v\n", err) return diff --git a/_xtool/llcppsymg/_cmptest/symg_test/cjson/cJSON.h b/_xtool/llcppsymg/_cmptest/symg_test/cjson/cJSON.h index 1af68d98..7cca0742 100644 --- a/_xtool/llcppsymg/_cmptest/symg_test/cjson/cJSON.h +++ b/_xtool/llcppsymg/_cmptest/symg_test/cjson/cJSON.h @@ -28,4 +28,6 @@ CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item); CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length); /* Delete a cJSON entity and all subentities. */ CJSON_PUBLIC(void) cJSON_Delete(cJSON *item); +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean); #endif diff --git a/_xtool/llcppsymg/_cmptest/symg_test/cjson/llcppg.cfg b/_xtool/llcppsymg/_cmptest/symg_test/cjson/llcppg.cfg index 9865015d..ccc79d8a 100644 --- a/_xtool/llcppsymg/_cmptest/symg_test/cjson/llcppg.cfg +++ b/_xtool/llcppsymg/_cmptest/symg_test/cjson/llcppg.cfg @@ -5,5 +5,10 @@ "cJSON.h" ], "trimPrefixes": ["cJSON_"], - "cplusplus": false + "cplusplus": false, + "symMap": { + "cJSON_AddArrayToObject":".AddArrayToObj", + "cJSON_AddBoolToObject":"AddBoolToObj", + "cJSON_AddNumberToObject":"-" + } } diff --git a/_xtool/llcppsymg/_cmptest/symg_test/llgo.expect b/_xtool/llcppsymg/_cmptest/symg_test/llgo.expect index 4e11fa27..3c079426 100644 --- a/_xtool/llcppsymg/_cmptest/symg_test/llgo.expect +++ b/_xtool/llcppsymg/_cmptest/symg_test/llgo.expect @@ -15,7 +15,7 @@ }, { "mangle": "_ZNK9INIReader10ParseErrorEv", "c++": "INIReader::ParseError()", - "go": "(*Reader).ModifyedParseError" + "go": "(*Reader).ParseError" }, { "mangle": "_ZNK9INIReader3GetEPKcS1_S1_", "c++": "INIReader::Get(const char *, const char *, const char *)", @@ -41,6 +41,14 @@ }] === Test Case: cjson === [{ + "mangle": "cJSON_AddArrayToObject", + "c++": "cJSON_AddArrayToObject(cJSON *const, const char *const)", + "go": "(*CJSON).AddArrayToObj" + }, { + "mangle": "cJSON_AddBoolToObject", + "c++": "cJSON_AddBoolToObject(cJSON *const, const char *const, const int)", + "go": "AddBoolToObj" + }, { "mangle": "cJSON_Delete", "c++": "cJSON_Delete(cJSON *)", "go": "(*CJSON).Delete" @@ -73,6 +81,12 @@ "c++": "gpg_strsource(gpg_error_t)", "go": "ErrorT.Strsource" }] +=== Test Case: sqlite === +[{ + "mangle": "sqlite3_finalize", + "c++": "sqlite3_finalize(sqlite3_stmt *)", + "go": "(*Stmt).Close" + }] #stderr diff --git a/_xtool/llcppsymg/_cmptest/symg_test/sqlite3/llcppg.cfg b/_xtool/llcppsymg/_cmptest/symg_test/sqlite3/llcppg.cfg new file mode 100644 index 00000000..6f33938f --- /dev/null +++ b/_xtool/llcppsymg/_cmptest/symg_test/sqlite3/llcppg.cfg @@ -0,0 +1,11 @@ +{ + "name": "sqlite", + "include": [ + "sqlite3.h" + ], + "trimPrefixes": ["sqlite3_","SQLITE_"], + "cplusplus": false, + "symMap":{ + "sqlite3_finalize":".Close" + } +} diff --git a/_llcppgtest/sqlite/conf/linux/llcppg.symb.json b/_xtool/llcppsymg/_cmptest/symg_test/sqlite3/llcppg.symb.json similarity index 100% rename from _llcppgtest/sqlite/conf/linux/llcppg.symb.json rename to _xtool/llcppsymg/_cmptest/symg_test/sqlite3/llcppg.symb.json diff --git a/_xtool/llcppsymg/_cmptest/symg_test/sqlite3/sqlite3.h b/_xtool/llcppsymg/_cmptest/symg_test/sqlite3/sqlite3.h new file mode 100644 index 00000000..d5cc7459 --- /dev/null +++ b/_xtool/llcppsymg/_cmptest/symg_test/sqlite3/sqlite3.h @@ -0,0 +1,13 @@ + +#ifndef __SQlITE3_H__ +#define __SQlITE3_H__ + +#ifndef SQLITE_API +# define SQLITE_API +#endif + +typedef struct sqlite3_stmt sqlite3_stmt; + +SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); + +#endif \ No newline at end of file diff --git a/_xtool/llcppsymg/_cmptest/symg_test/symg.go b/_xtool/llcppsymg/_cmptest/symg_test/symg.go index c407f927..d82d0117 100644 --- a/_xtool/llcppsymg/_cmptest/symg_test/symg.go +++ b/_xtool/llcppsymg/_cmptest/symg_test/symg.go @@ -16,6 +16,7 @@ import ( func main() { TestParseHeaderFile() } + func TestParseHeaderFile() { testCases := []struct { name string @@ -52,6 +53,9 @@ func TestParseHeaderFile() { "cJSON_Delete", // mock multiple symbols "cJSON_Delete", + "cJSON_AddArrayToObject", + "cJSON_AddBoolToObject", + "cJSON_AddNumberToObject", }, }, { @@ -70,6 +74,13 @@ func TestParseHeaderFile() { "gpg_strerror", }, }, + { + name: "sqlite", + path: "./sqlite3", + dylibSymbols: []string{ + "sqlite3_finalize", + }, + }, } for _, tc := range testCases { @@ -92,7 +103,8 @@ func TestParseHeaderFile() { cfg.CFlags = "-I" + projPath pkgHfileInfo := config.PkgHfileInfo(cfg.Config, []string{}) - headerSymbolMap, err := parse.ParseHeaderFile(pkgHfileInfo.CurPkgFiles(), cfg.TrimPrefixes, strings.Fields(cfg.CFlags), cfg.Cplusplus, false) + config := parse.NewConfig(pkgHfileInfo.CurPkgFiles(), cfg.TrimPrefixes, strings.Fields(cfg.CFlags), cfg.Cplusplus, cfg.SymMap) + headerSymbolMap, err := parse.ParseHeaderFile(config, false) if err != nil { fmt.Println("Error:", err) } @@ -106,7 +118,7 @@ func TestParseHeaderFile() { for _, symb := range tc.dylibSymbols { dylibsymbs = append(dylibsymbs, &nm.Symbol{Name: symbol.AddSymbolPrefixUnder(symb, cfg.Cplusplus)}) } - symbolData, err := symbol.GenerateAndUpdateSymbolTable(dylibsymbs, headerSymbolMap, filepath.Join(projPath, llcppg.LLCPPG_SYMB)) + symbolData, err := symbol.GenerateSymbolTable(dylibsymbs, headerSymbolMap, filepath.Join(projPath, llcppg.LLCPPG_SYMB)) if err != nil { fmt.Println("Error:", err) } diff --git a/_xtool/llcppsymg/config/config.go b/_xtool/llcppsymg/config/config.go index 25d74988..1a985b50 100644 --- a/_xtool/llcppsymg/config/config.go +++ b/_xtool/llcppsymg/config/config.go @@ -33,8 +33,13 @@ func GetConf(data []byte) (Conf, error) { TrimPrefixes: GetStringArrayItem(parsedConf, "trimPrefixes"), Cplusplus: GetBoolItem(parsedConf, "cplusplus"), Mix: GetBoolItem(parsedConf, "mix"), + SymMap: GetMapItem[string](parsedConf, "symMap"), } + //cannot use GetMapItem[string](parsedConf, "symMap") + // (value of type MapType[string]) as []string value + // in struct literal (compile) + return Conf{ JSON: parsedConf, Config: config, @@ -54,6 +59,50 @@ func GetStringItem(obj *cjson.JSON, key string, defval string) (value string) { return GetString(item) } +func GetItemValue(item *cjson.JSON) (any, bool) { + if item.IsArray() != 0 { + return item, false + } else if item.IsBool() != 0 { + if item.IsTrue() != 0 { + return true, true + } + return false, true + } else if item.IsNumber() != 0 { + return float64(item.GetNumberValue()), true + } else if item.IsObject() != 0 { + return item, false + } else if item.IsNull() != 0 { + return nil, false + } else if item.IsInvalid() != 0 { + return nil, false + } else if item.IsRaw() != 0 { + return item, false + } else if item.IsString() != 0 { + return GetString(item), true + } + return nil, false +} + +func GetMapItem[ValueType any](obj *cjson.JSON, mapItemKey string) map[string]ValueType { + cStrOfMapItemKey := c.AllocaCStr(mapItemKey) + mapObj := obj.GetObjectItem(cStrOfMapItemKey) + if mapObj == nil { + return nil + } + m := make(map[string]ValueType) + for child := mapObj.Child; child != nil; child = child.Next { + key := c.GoString(child.String) + value, ok := GetItemValue(child) + if ok { + tValue, ok := value.(ValueType) + if ok { + m[key] = tValue + } + } + } + return m +} + func GetStringArrayItem(obj *cjson.JSON, key string) (value []string) { item := obj.GetObjectItemCaseSensitive(c.AllocaCStr(key)) if item == nil { diff --git a/_xtool/llcppsymg/dbg/debug.go b/_xtool/llcppsymg/dbg/debug.go index de27a3ad..f11aefc8 100644 --- a/_xtool/llcppsymg/dbg/debug.go +++ b/_xtool/llcppsymg/dbg/debug.go @@ -7,7 +7,12 @@ var flags dbgFlags const ( DbgSymbol dbgFlags = 1 << iota DbgParseIsMethod //print parse.go isMethod debug log info - DbgFlagAll = DbgSymbol | DbgParseIsMethod + DbgEditSymMap //print user edit sym map info + DbgVisitTop //print visitTop + DbgCollectFuncInfo + DbgNewSymbol + DbgFileType + DbgFlagAll = DbgSymbol | DbgParseIsMethod ) func SetDebugSymbol() { @@ -25,3 +30,43 @@ func SetDebugParseIsMethod() { func GetDebugParseIsMethod() bool { return flags&DbgParseIsMethod != 0 } + +func SetDebugEditSymMap() { + flags |= DbgEditSymMap +} + +func GetDebugEditSymMap() bool { + return flags&DbgEditSymMap != 0 +} + +func SetDebugVisitTop() { + flags |= DbgVisitTop +} + +func GetDebugVisitTop() bool { + return flags&DbgVisitTop != 0 +} + +func SetDebugCollectFuncInfo() { + flags |= DbgCollectFuncInfo +} + +func GetDebugCollectFuncInfo() bool { + return flags&DbgCollectFuncInfo != 0 +} + +func SetDebugNewSymbol() { + flags |= DbgNewSymbol +} + +func GetDebugNewSymbol() bool { + return flags&DbgNewSymbol != 0 +} + +func SetDebugFileType() { + flags |= DbgFileType +} + +func GetDebugFileType() bool { + return flags&DbgFileType != 0 +} diff --git a/_xtool/llcppsymg/dbg/debug_test.go b/_xtool/llcppsymg/dbg/debug_test.go new file mode 100644 index 00000000..94dc11d6 --- /dev/null +++ b/_xtool/llcppsymg/dbg/debug_test.go @@ -0,0 +1,131 @@ +package dbg + +import ( + "testing" +) + +func TestSetDebugSymbol(t *testing.T) { + tests := []struct { + name string + }{ + { + name: "TestSetDebugSymbol", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugSymbol() + if !GetDebugSymbol() { + t.Errorf("GetDebugSymbol() = got %v, want %v", false, true) + } + }) + } +} + +func TestSetDebugParseIsMethod(t *testing.T) { + tests := []struct { + name string + }{ + { + name: "TestSetDebugParseIsMethod", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugParseIsMethod() + if !GetDebugParseIsMethod() { + t.Errorf("GetDebugParseIsMethod() = got %v, want %v", false, true) + } + }) + } +} + +func TestSetDebugEditSymMap(t *testing.T) { + tests := []struct { + name string + }{ + { + name: "TestSetDebugEditSymMap", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugEditSymMap() + if !GetDebugEditSymMap() { + t.Errorf("GetDebugEditSymMap() = %v, want %v", false, true) + } + }) + } +} + +func TestSetDebugVisitTop(t *testing.T) { + tests := []struct { + name string + }{ + { + "TestSetDebugVisitTop", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugVisitTop() + if !GetDebugVisitTop() { + t.Errorf("GetDebugVisitTop() = %v, want %v", false, true) + } + }) + } +} + +func TestSetDebugCollectFuncInfo(t *testing.T) { + tests := []struct { + name string + }{ + { + name: "TestSetDebugCollectFuncInfo", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugCollectFuncInfo() + if !GetDebugCollectFuncInfo() { + t.Errorf("GetDebugCollectFuncInfo() got = %v, want %v", false, true) + } + }) + } +} + +func TestSetDebugNewSymbol(t *testing.T) { + tests := []struct { + name string + }{ + { + name: "TestSetDebugNewSymbol", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugNewSymbol() + if !GetDebugNewSymbol() { + t.Errorf("GetDebugNewSymbol() = %v, want %v", false, true) + } + }) + } +} + +func TestSetDebugFileType(t *testing.T) { + tests := []struct { + name string + }{ + { + name: "TestSetDebugFileType", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugFileType() + if !GetDebugFileType() { + t.Errorf("GetDebugFileType() = %v, want %v", false, true) + } + }) + } +} diff --git a/_xtool/llcppsymg/llcppsymg.go b/_xtool/llcppsymg/llcppsymg.go index 18836ba7..c5048973 100644 --- a/_xtool/llcppsymg/llcppsymg.go +++ b/_xtool/llcppsymg/llcppsymg.go @@ -51,10 +51,6 @@ func main() { check(err) defer conf.Delete() - if ags.VerboseParseIsMethod { - dbg.SetDebugParseIsMethod() - } - if ags.Verbose { dbg.SetDebugSymbol() if ags.UseStdin { @@ -62,30 +58,29 @@ func main() { } else { fmt.Println("Config From File", ags.CfgFile) } - fmt.Println("Name:", conf.Name) - fmt.Println("CFlags:", conf.CFlags) - fmt.Println("Libs:", conf.Libs) - fmt.Println("Include:", conf.Include) - fmt.Println("TrimPrefixes:", conf.TrimPrefixes) - fmt.Println("Cplusplus:", conf.Cplusplus) + fmt.Printf("%s\n", conf.Config.String()) } if err != nil { fmt.Fprintln(os.Stderr, "Failed to parse config file:", ags.CfgFile) } + symbols, err := symbol.ParseDylibSymbols(conf.Libs) check(err) pkgHfiles := config.PkgHfileInfo(conf.Config, []string{}) - if dbg.GetDebugSymbol() { + if dbg.GetDebugFileType() { fmt.Println("interfaces", pkgHfiles.Inters) fmt.Println("implements", pkgHfiles.Impls) fmt.Println("thirdhfile", pkgHfiles.Thirds) } - headerInfos, err := parse.ParseHeaderFile(pkgHfiles.CurPkgFiles(), conf.TrimPrefixes, strings.Fields(conf.CFlags), conf.Cplusplus, false) + + config := parse.NewConfig(pkgHfiles.CurPkgFiles(), + conf.TrimPrefixes, strings.Fields(conf.CFlags), conf.Cplusplus, conf.SymMap) + headerInfos, err := parse.ParseHeaderFile(config, false) check(err) - symbolData, err := symbol.GenerateAndUpdateSymbolTable(symbols, headerInfos, llcppg.LLCPPG_SYMB) + symbolData, err := symbol.GenerateSymbolTable(symbols, headerInfos, llcppg.LLCPPG_SYMB) check(err) err = os.WriteFile(llcppg.LLCPPG_SYMB, symbolData, 0644) diff --git a/_xtool/llcppsymg/parse/parse.go b/_xtool/llcppsymg/parse/parse.go index 8dac8138..494f9d33 100644 --- a/_xtool/llcppsymg/parse/parse.go +++ b/_xtool/llcppsymg/parse/parse.go @@ -18,9 +18,31 @@ type SymbolInfo struct { ProtoName string } +type Config struct { + Files []string + Prefixes []string + Cflags []string + IsCpp bool + SymMap map[string]string +} + +func NewConfig(files, prefixes, cflags []string, + isCpp bool, + symMap map[string]string) *Config { + if symMap == nil { + symMap = make(map[string]string) + } + return &Config{Files: files, Prefixes: prefixes, Cflags: cflags, IsCpp: isCpp, SymMap: symMap} +} + +func (p *Config) String() string { + return fmt.Sprintf( + "Files:%v\nPrefixes:%v\nCflags:%v\nSymMap:%v\nIsCpp:%v", p.Files, p.Prefixes, p.Cflags, p.SymMap, p.IsCpp, + ) +} + type SymbolProcessor struct { - Files []string - Prefixes []string + *Config SymbolMap map[string]*SymbolInfo NameCounts map[string]int // for independent files,signal that the file has been processed @@ -37,10 +59,9 @@ func panicSourceLocation(loc clang.SourceLocation, prefix string) { panic(logString) } -func NewSymbolProcessor(Files []string, Prefixes []string) *SymbolProcessor { +func NewSymbolProcessor(conf *Config) *SymbolProcessor { return &SymbolProcessor{ - Files: Files, - Prefixes: Prefixes, + Config: conf, SymbolMap: make(map[string]*SymbolInfo), NameCounts: make(map[string]int), processedFiles: make(map[string]struct{}), @@ -175,7 +196,24 @@ func (p *SymbolProcessor) isMethod(cur clang.Cursor, isArg bool) (bool, bool, st return isInCurPkg, false, goName } -func (p *SymbolProcessor) genGoName(cursor clang.Cursor) string { +func (p *SymbolProcessor) userEditGoName(manglingName string) (goName string, isEditted, isMethod bool) { + goName, isEditted = p.SymMap[manglingName] + if isEditted { + goName, isMethod = strings.CutPrefix(goName, ".") + } + return goName, isEditted, isMethod +} + +func (p *SymbolProcessor) genGoName(cursor clang.Cursor, mangleName string) string { + + edittedGoName, isEdittedGoName, isEdittedMethodName := p.userEditGoName(mangleName) + + if dbg.GetDebugEditSymMap() && isEdittedGoName { + fmt.Println("edittedGoName:", edittedGoName) + fmt.Println("isEdittedGoName", isEdittedGoName) + fmt.Println("isEdittedMethodName", isEdittedMethodName) + } + originName := clang.GoString(cursor.String()) isDestructor := cursor.Kind == clang.CursorDestructor var convertedName string @@ -191,11 +229,28 @@ func (p *SymbolProcessor) genGoName(cursor clang.Cursor) string { } else if cursor.Kind == clang.CursorFunctionDecl { numArgs := cursor.NumArguments() if numArgs > 0 { + // only method can be used with editted method name. if ok, isPtr, typeName := p.isMethod(cursor.Argument(0), true); ok { - return p.AddSuffix(p.GenMethodName(typeName, convertedName, isDestructor, isPtr)) + if isEdittedGoName { + if isEdittedMethodName { + genName := p.GenMethodName(typeName, edittedGoName, isDestructor, isPtr) + if dbg.GetDebugEditSymMap() { + fmt.Println("genMethodName:", genName) + } + return genName + } + } else { + return p.AddSuffix(p.GenMethodName(typeName, convertedName, isDestructor, isPtr)) + } } } } + if isEdittedGoName && edittedGoName != "" { + if dbg.GetDebugEditSymMap() { + fmt.Println("genFuncName:", edittedGoName) + } + return edittedGoName + } return p.AddSuffix(convertedName) } @@ -224,23 +279,31 @@ func (p *SymbolProcessor) collectFuncInfo(cursor clang.Cursor) { // On Linux, C++ symbols typically have one leading underscore // On macOS, C++ symbols may have two leading underscores // For consistency, we remove the first leading underscore on macOS - if dbg.GetDebugSymbol() { + if dbg.GetDebugCollectFuncInfo() { fmt.Printf("collectFuncInfo: %s %s\n", clang.GoString(cursor.Mangling()), clang.GoString(cursor.String())) } - symbolName := clang.GoString(cursor.Mangling()) + + manglingName := clang.GoString(cursor.Mangling()) if runtime.GOOS == "darwin" { - symbolName = strings.TrimPrefix(symbolName, "_") + manglingName = strings.TrimPrefix(manglingName, "_") } // In C, multiple declarations of the same function are allowed. // Functions with identical signatures will have the same mangled name. // We treat them as the same function rather than overloads, so we only // process the first occurrence and skip subsequent declarations. - if _, exists := p.SymbolMap[symbolName]; exists { + if _, exists := p.SymbolMap[manglingName]; exists { return } - p.SymbolMap[symbolName] = &SymbolInfo{ - GoName: p.genGoName(cursor), + + // ignore + goName := p.genGoName(cursor, manglingName) + if goName == "-" || len(goName) == 0 { + return + } + + p.SymbolMap[manglingName] = &SymbolInfo{ + GoName: goName, ProtoName: p.genProtoName(cursor), } } @@ -248,7 +311,7 @@ func (p *SymbolProcessor) collectFuncInfo(cursor clang.Cursor) { func (p *SymbolProcessor) visitTop(cursor, parent clang.Cursor) clang.ChildVisitResult { filename := clang.GoString(cursor.Location().File().FileName()) if _, ok := p.processedFiles[filename]; ok { - if dbg.GetDebugSymbol() { + if dbg.GetDebugVisitTop() && p.isSelfFile(filename) { fmt.Printf("visitTop: %s has been processed: \n", filename) } return clang.ChildVisit_Continue @@ -257,7 +320,7 @@ func (p *SymbolProcessor) visitTop(cursor, parent clang.Cursor) clang.ChildVisit return clang.ChildVisit_Continue } p.processingFiles[filename] = struct{}{} - if dbg.GetDebugSymbol() && filename != "" { + if dbg.GetDebugVisitTop() && p.isSelfFile(filename) { fmt.Printf("visitTop: %s\n", filename) } switch cursor.Kind { @@ -278,12 +341,12 @@ func (p *SymbolProcessor) collect(cfg *clangutils.Config) error { filename = clangutils.TEMP_FILE } if _, ok := p.processedFiles[filename]; ok { - if dbg.GetDebugSymbol() { + if dbg.GetDebugSymbol() && p.isSelfFile(filename) { fmt.Printf("%s has been processed: \n", filename) } return nil } - if dbg.GetDebugSymbol() { + if dbg.GetDebugSymbol() && p.isSelfFile(filename) { fmt.Printf("create translation unit: \nfile:%s\nIsCpp:%v\nTemp:%v\nArgs:%v\n", filename, cfg.IsCpp, cfg.Temp, cfg.Args) } _, unit, err := clangutils.CreateTranslationUnit(cfg) @@ -291,7 +354,7 @@ func (p *SymbolProcessor) collect(cfg *clangutils.Config) error { return errors.New("Unable to parse translation unit for file " + filename) } cursor := unit.Cursor() - if dbg.GetDebugSymbol() { + if dbg.GetDebugVisitTop() && p.isSelfFile(filename) { fmt.Printf("%s start collect \n", filename) } clangutils.VisitChildren(cursor, p.visitTop) @@ -303,19 +366,22 @@ func (p *SymbolProcessor) collect(cfg *clangutils.Config) error { return nil } -func ParseHeaderFile(files []string, prefixes []string, cflags []string, isCpp bool, isTemp bool) (map[string]*SymbolInfo, error) { +func ParseHeaderFile(conf *Config, isTemp bool) (map[string]*SymbolInfo, error) { + if dbg.GetDebugEditSymMap() { + fmt.Println(conf) + } index := clang.CreateIndex(0, 0) if isTemp { - files = append(files, clangutils.TEMP_FILE) + conf.Files = append(conf.Files, clangutils.TEMP_FILE) } - processer := NewSymbolProcessor(files, prefixes) - for _, file := range files { + processer := NewSymbolProcessor(conf) + for _, file := range conf.Files { processer.collect(&clangutils.Config{ File: file, Temp: isTemp, - IsCpp: isCpp, + IsCpp: conf.IsCpp, Index: index, - Args: cflags, + Args: conf.Cflags, }) } index.Dispose() diff --git a/_xtool/llcppsymg/symbol/symbol.go b/_xtool/llcppsymg/symbol/symbol.go index 52b8f687..fc950d83 100644 --- a/_xtool/llcppsymg/symbol/symbol.go +++ b/_xtool/llcppsymg/symbol/symbol.go @@ -158,35 +158,15 @@ func ReadExistingSymbolTable(fileName string) (map[string]llcppg.SymbolInfo, boo return existingSymbols, true } -func GenSymbolTableData(commonSymbols []*llcppg.SymbolInfo, existingSymbols map[string]llcppg.SymbolInfo) ([]byte, error) { - if len(existingSymbols) > 0 { - if dbg.GetDebugSymbol() { - fmt.Println("GenSymbolTableData:generate symbol table with exist symbol table") - } - for i := range commonSymbols { - if existingSymbol, exists := existingSymbols[commonSymbols[i].Mangle]; exists && commonSymbols[i].Go != existingSymbol.Go { - if dbg.GetDebugSymbol() { - fmt.Println("symbol", commonSymbols[i].Mangle, "already exist, use exist symbol", existingSymbol.Go) - } - commonSymbols[i].Go = existingSymbol.Go - } else { - if dbg.GetDebugSymbol() { - fmt.Println("new symbol", commonSymbols[i].Mangle, "-", commonSymbols[i].CPP, "-", commonSymbols[i].Go) - } - } - } - } else { - if dbg.GetDebugSymbol() { - fmt.Println("GenSymbolTableData:generate symbol table without symbol table") - for _, symbol := range commonSymbols { - fmt.Println("new symbol", symbol.Mangle, "-", symbol.CPP, "-", symbol.Go) - } +func GenSymbolTableData(commonSymbols []*llcppg.SymbolInfo) ([]byte, error) { + if dbg.GetDebugNewSymbol() { + fmt.Println("GenSymbolTableData:generate symbol table without symbol table") + for _, symbol := range commonSymbols { + fmt.Println("new symbol", symbol.Mangle, "-", symbol.CPP, "-", symbol.Go) } } - root := cjson.Array() defer root.Delete() - for _, symbol := range commonSymbols { item := cjson.Object() item.SetItem(c.Str("mangle"), cjson.String(c.AllocaCStr(symbol.Mangle))) @@ -194,7 +174,6 @@ func GenSymbolTableData(commonSymbols []*llcppg.SymbolInfo, existingSymbols map[ item.SetItem(c.Str("go"), cjson.String(c.AllocaCStr(symbol.Go))) root.AddItem(item) } - cStr := root.Print() if cStr == nil { return nil, errors.New("symbol table is empty") @@ -204,18 +183,13 @@ func GenSymbolTableData(commonSymbols []*llcppg.SymbolInfo, existingSymbols map[ return result, nil } -func GenerateAndUpdateSymbolTable(symbols []*nm.Symbol, headerInfos map[string]*parse.SymbolInfo, symbFile string) ([]byte, error) { +func GenerateSymbolTable(symbols []*nm.Symbol, headerInfos map[string]*parse.SymbolInfo, symbFile string) ([]byte, error) { commonSymbols := GetCommonSymbols(symbols, headerInfos) if dbg.GetDebugSymbol() { fmt.Println("GenerateAndUpdateSymbolTable:", len(commonSymbols), "common symbols") } - existSymbols, exist := ReadExistingSymbolTable(symbFile) - if exist && dbg.GetDebugSymbol() { - fmt.Println("GenerateAndUpdateSymbolTable:current path have exist symbol table", symbFile) - } - - symbolData, err := GenSymbolTableData(commonSymbols, existSymbols) + symbolData, err := GenSymbolTableData(commonSymbols) if err != nil { return nil, err } diff --git a/cmd/gogensig/convert/package.go b/cmd/gogensig/convert/package.go index b1531741..5c1b75e7 100644 --- a/cmd/gogensig/convert/package.go +++ b/cmd/gogensig/convert/package.go @@ -146,7 +146,7 @@ func (p *Package) SetCurFile(hfile *HeaderFile) { // for third hfile not register to gogen.Package if curFile.FileType != llcppg.Third { fileName := curFile.ToGoFileName(p.conf.Name) - if dbg.GetDebugLog() { + if dbg.GetDebugSetCurFile() { log.Printf("SetCurFile: %s File in Current Package: %v\n", fileName, curFile.FileType) } p.p.SetCurFile(fileName, true) @@ -263,12 +263,12 @@ func pubMethodName(recv types.Type, fnSpec *GoFuncSpec) string { func (p *Package) NewFuncDecl(funcDecl *ast.FuncDecl) error { isThird, anony := p.handleType(funcDecl.Name, funcDecl.Loc) if isThird { - if dbg.GetDebugLog() { + if dbg.GetDebugNew() { log.Printf("NewFuncDecl: %v is a function of third header file\n", funcDecl.Name) } return nil } - if dbg.GetDebugLog() { + if dbg.GetDebugNew() { log.Printf("NewFuncDecl: %v\n", funcDecl.Name) } if anony { @@ -281,7 +281,9 @@ func (p *Package) NewFuncDecl(funcDecl *ast.FuncDecl) error { return err } if fnSpec.IsIgnore() { - log.Printf("NewFuncDecl: %v is ignored\n", funcDecl.Name) + if dbg.GetDebugNew() { + log.Printf("NewFuncDecl: %v is ignored\n", funcDecl.Name) + } return nil } @@ -324,12 +326,12 @@ func (p *Package) funcIsDefined(fnSpec *GoFuncSpec, funcDecl *ast.FuncDecl) (rec func (p *Package) NewTypeDecl(typeDecl *ast.TypeDecl) error { skip, anony := p.handleType(typeDecl.Name, typeDecl.Loc) if skip { - if dbg.GetDebugLog() { + if dbg.GetDebugNew() { log.Printf("NewTypeDecl: %s type of third header\n", typeDecl.Name) } return nil } - if dbg.GetDebugLog() { + if dbg.GetDebugNew() { log.Printf("NewTypeDecl: %v\n", typeDecl.Name) } if anony { @@ -429,12 +431,12 @@ func (p *Package) emptyTypeDecl(name string, doc *ast.CommentGroup) *gogen.TypeD func (p *Package) NewTypedefDecl(typedefDecl *ast.TypedefDecl) error { skip, _ := p.handleType(typedefDecl.Name, typedefDecl.Loc) if skip { - if dbg.GetDebugLog() { + if dbg.GetDebugNew() { log.Printf("NewTypedefDecl: %v is a typedef of third header file\n", typedefDecl.Name) } return nil } - if dbg.GetDebugLog() { + if dbg.GetDebugNew() { log.Printf("NewTypedefDecl: %v\n", typedefDecl.Name) } name, changed, err := p.DeclName(typedefDecl.Name.Name, true) @@ -452,7 +454,7 @@ func (p *Package) NewTypedefDecl(typedefDecl *ast.TypedefDecl) error { deferInit := p.handleTyperefIncomplete(typedefDecl.Type, typeSpecdecl, typedefDecl.Name.Name) if deferInit { - if dbg.GetDebugLog() { + if dbg.GetDebugNew() { log.Printf("NewTypedefDecl: %s defer init\n", name) } return nil @@ -520,12 +522,12 @@ func (p *Package) NewTypedefs(name string, typ types.Type) *gogen.TypeDecl { func (p *Package) NewEnumTypeDecl(enumTypeDecl *ast.EnumTypeDecl) error { skip, _ := p.handleType(enumTypeDecl.Name, enumTypeDecl.Loc) if skip { - if dbg.GetDebugLog() { + if dbg.GetDebugNew() { log.Printf("NewEnumTypeDecl: %v is a enum type of system header file\n", enumTypeDecl.Name) } return nil } - if dbg.GetDebugLog() { + if dbg.GetDebugNew() { log.Printf("NewEnumTypeDecl: %v\n", enumTypeDecl.Name) } enumType, err := p.createEnumType(enumTypeDecl.Name) @@ -598,7 +600,7 @@ func (p *Package) NewMacro(macro *ast.Macro) error { if err != nil { return err } - if dbg.GetDebugLog() { + if dbg.GetDebugNew() { log.Printf("NewMacro: %s = %s\n", name, value) } if str, err := litToString(value); err == nil { @@ -668,7 +670,7 @@ func (p *Package) WritePkgFiles() error { func (p *Package) Write(headerFile string) error { fileName := names.HeaderFileToGo(headerFile) filePath := filepath.Join(p.GetOutputDir(), fileName) - if dbg.GetDebugLog() { + if dbg.GetDebugWrite() { log.Printf("Write HeaderFile [%s] from gogen:[%s] to [%s]\n", headerFile, fileName, filePath) } return p.writeToFile(fileName, filePath) diff --git a/cmd/gogensig/dbg/debug.go b/cmd/gogensig/dbg/debug.go index b920fc93..f9229a17 100644 --- a/cmd/gogensig/dbg/debug.go +++ b/cmd/gogensig/dbg/debug.go @@ -8,7 +8,11 @@ const ( DbgSymbolNotFound dbgFlags = 1 << iota DbgError // print when error ocur DbgLog // print log info - DbgFlagAll = 0 | DbgError | DbgLog + DbgSetCurFile + DbgNew + DbgWrite + DbgUnmarshalling + DbgFlagAll = 0 | DbgError | DbgLog ) func SetDebugSymbolNotFound() { @@ -38,3 +42,35 @@ func GetDebugLog() bool { func SetDebugAll() { flags = DbgFlagAll } + +func SetDebugSetCurFile() { + flags |= DbgSetCurFile +} + +func GetDebugSetCurFile() bool { + return flags&DbgSetCurFile != 0 +} + +func SetDebugNew() { + flags |= DbgNew +} + +func GetDebugNew() bool { + return flags&DbgNew != 0 +} + +func SetDebugWrite() { + flags |= DbgWrite +} + +func GetDebugWrite() bool { + return flags&DbgWrite != 0 +} + +func SetDebugUnmarshalling() { + flags |= DbgUnmarshalling +} + +func GetDebugUnmarshalling() bool { + return flags&DbgUnmarshalling != 0 +} diff --git a/cmd/gogensig/dbg/debug_test.go b/cmd/gogensig/dbg/debug_test.go new file mode 100644 index 00000000..dd6672cc --- /dev/null +++ b/cmd/gogensig/dbg/debug_test.go @@ -0,0 +1,147 @@ +package dbg + +import ( + "testing" +) + +func TestSetDebugSymbolNotFound(t *testing.T) { + tests := []struct { + name string + }{{ + "TestSetDebugSymbolNotFound", + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugSymbolNotFound() + if !GetDebugSymbolNotFound() { + t.Errorf("GetDebugSymbolNotFound() = %v, want %v", false, true) + } + }) + } +} + +func TestSetDebugError(t *testing.T) { + tests := []struct { + name string + }{ + { + "TestSetDebugError", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugError() + if !GetDebugError() { + t.Errorf("GetDebugError() = %v, want %v", false, true) + } + }) + } +} + +func TestSetDebugLog(t *testing.T) { + tests := []struct { + name string + }{ + { + name: "TestSetDebugLog", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugLog() + if !GetDebugLog() { + t.Errorf("GetDebugLog() = %v, want %v", false, true) + } + }) + } +} + +func TestSetDebugAll(t *testing.T) { + tests := []struct { + name string + }{ + { + name: "TestSetDebugAll", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugAll() + if flags != DbgFlagAll { + t.Errorf("flags = %v, want %v", flags, DbgFlagAll) + } + }) + } +} + +func TestSetDebugSetCurFile(t *testing.T) { + tests := []struct { + name string + }{ + { + name: "TestSetDebugSetCurFile", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugSetCurFile() + if !GetDebugSetCurFile() { + t.Errorf("GetDebugSetCurFile() = %v, want %v", false, true) + } + }) + } +} + +func TestSetDebugNew(t *testing.T) { + tests := []struct { + name string + }{ + { + name: "TestSetDebugNew", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugNew() + if !GetDebugNew() { + t.Errorf("GetDebugNew() = %v, want %v", false, true) + } + }) + } +} + +func TestSetDebugWrite(t *testing.T) { + tests := []struct { + name string + }{ + { + name: "TestSetDebugWrite", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugWrite() + if !GetDebugWrite() { + t.Errorf("GetDebugWrite() = %v, want %v", false, true) + } + }) + } +} + +func TestSetDebugUnmarshalling(t *testing.T) { + tests := []struct { + name string + }{ + { + name: "TestSetDebugUnmarshalling", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetDebugUnmarshalling() + if !GetDebugUnmarshalling() { + t.Errorf("GetDebugUnmarshalling() = %v, want %v", false, true) + } + }) + } +} diff --git a/cmd/gogensig/unmarshal/unmarshal.go b/cmd/gogensig/unmarshal/unmarshal.go index 578237cb..494dace3 100644 --- a/cmd/gogensig/unmarshal/unmarshal.go +++ b/cmd/gogensig/unmarshal/unmarshal.go @@ -7,6 +7,7 @@ import ( "reflect" "github.com/goplus/llcppg/ast" + "github.com/goplus/llcppg/cmd/gogensig/dbg" "github.com/goplus/llcppg/llcppg" ) @@ -667,7 +668,9 @@ func File(data []byte) (ast.Node, error) { for i, declData := range fileData.Decls { declNode, err := Node(declData) if err != nil { - fmt.Fprintf(os.Stderr, "error unmarshalling %d Decl in File: %v\n%s\n", i, err, string(declData)) + if dbg.GetDebugUnmarshalling() { + fmt.Fprintf(os.Stderr, "error unmarshalling %d Decl in File: %v\n%s\n", i, err, string(declData)) + } continue } decl, ok := declNode.(ast.Decl) diff --git a/cmd/llcppcfg/llcppgcfg/cfg_test.go b/cmd/llcppcfg/llcppgcfg/cfg_test.go index 46fcc333..05011097 100644 --- a/cmd/llcppcfg/llcppgcfg/cfg_test.go +++ b/cmd/llcppcfg/llcppgcfg/cfg_test.go @@ -500,6 +500,8 @@ func TestNewLLCppConfig(t *testing.T) { Cplusplus: false, Impl: []llcppg.ImplFiles{*llcppg.NewImplFiles()}, KeepUnderScore: false, + SymMap: map[string]string{}, + TypeMap: map[string]string{}, }, }, } diff --git a/cmd/llcppcfg/llcppgcfg/cfg_test_data/bdw-gc/llcppg.cfg b/cmd/llcppcfg/llcppgcfg/cfg_test_data/bdw-gc/llcppg.cfg index 86b5399a..3a52867b 100644 --- a/cmd/llcppcfg/llcppgcfg/cfg_test_data/bdw-gc/llcppg.cfg +++ b/cmd/llcppcfg/llcppgcfg/cfg_test_data/bdw-gc/llcppg.cfg @@ -36,5 +36,7 @@ } } ], - "mix": false + "mix": false, + "symMap": {}, + "typeMap": {} } diff --git a/cmd/llcppcfg/llcppgcfg/cfg_test_data/cjson/llcppg.cfg b/cmd/llcppcfg/llcppgcfg/cfg_test_data/cjson/llcppg.cfg index d6ada6fa..d93fd7e3 100644 --- a/cmd/llcppcfg/llcppgcfg/cfg_test_data/cjson/llcppg.cfg +++ b/cmd/llcppcfg/llcppgcfg/cfg_test_data/cjson/llcppg.cfg @@ -19,5 +19,7 @@ } } ], - "mix": false + "mix": false, + "symMap": {}, + "typeMap": {} } diff --git a/cmd/llcppcfg/llcppgcfg/cfg_test_data/libffi/llcppg.cfg b/cmd/llcppcfg/llcppgcfg/cfg_test_data/libffi/llcppg.cfg index ed7a269f..9389c479 100644 --- a/cmd/llcppcfg/llcppgcfg/cfg_test_data/libffi/llcppg.cfg +++ b/cmd/llcppcfg/llcppgcfg/cfg_test_data/libffi/llcppg.cfg @@ -18,5 +18,7 @@ } } ], - "mix": false + "mix": false, + "symMap": {}, + "typeMap": {} } diff --git a/llcppg/llcppg.go b/llcppg/llcppg.go index f75e5882..7e926ae1 100644 --- a/llcppg/llcppg.go +++ b/llcppg/llcppg.go @@ -1,6 +1,11 @@ package llcppg -import "github.com/goplus/llcppg/ast" +import ( + "fmt" + "strings" + + "github.com/goplus/llcppg/ast" +) const LLCPPG_CFG = "llcppg.cfg" const LLCPPG_SYMB = "llcppg.symb.json" @@ -33,12 +38,25 @@ type Config struct { KeepUnderScore bool `json:"keepUnderScore"` Impl []ImplFiles `json:"impl"` Mix bool `json:"mix"` - SymMap map[string]string `json:"symMap,omitempty"` - TypeMap map[string]string `json:"typeMap,omitempty"` + SymMap map[string]string `json:"symMap"` + TypeMap map[string]string `json:"typeMap"` } func NewDefaultConfig() *Config { - return &Config{Impl: []ImplFiles{*NewImplFiles()}} + cfg := &Config{SymMap: make(map[string]string), TypeMap: make(map[string]string), Impl: []ImplFiles{*NewImplFiles()}} + return cfg +} + +func (p *Config) String() string { + strBuilder := strings.Builder{} + strBuilder.WriteString("Name:" + p.Name + "\n") + strBuilder.WriteString("CFlags:" + p.CFlags + "\n") + strBuilder.WriteString("Libs:" + p.Libs + "\n") + strBuilder.WriteString("Include:" + fmt.Sprintln(p.Include)) + strBuilder.WriteString("TrimPrefixes:" + fmt.Sprintln(p.TrimPrefixes)) + strBuilder.WriteString("Cplusplus:" + fmt.Sprintln(p.Cplusplus)) + strBuilder.WriteString("SymMap:" + fmt.Sprintln(p.SymMap)) + return strBuilder.String() } type SymbolInfo struct {