diff --git a/chore/_xtool/llcppsymg/_cmptest/clangutils_test/clangutils.go b/chore/_xtool/llcppsymg/_cmptest/clangutils_test/clangutils.go new file mode 100644 index 00000000..1dd06781 --- /dev/null +++ b/chore/_xtool/llcppsymg/_cmptest/clangutils_test/clangutils.go @@ -0,0 +1,119 @@ +package main + +import ( + "fmt" + "os" + + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/clang" + "github.com/goplus/llgo/chore/_xtool/llcppsymg/clangutils" +) + +func main() { + TestClangUtil() +} + +func TestClangUtil() { + testCases := []struct { + name string + content string + isTemp bool + isCpp bool + }{ + { + name: "C Header File", + content: ` + int test_function(int a, int b); + void another_function(void); + `, + isTemp: false, + isCpp: false, + }, + { + name: "C++ Temp File", + content: ` + class TestClass { + public: + void test_method(); + static int static_method(float f); + }; + + namespace TestNamespace { + void namespaced_function(); + } + `, + isTemp: true, + isCpp: true, + }, + } + + for _, tc := range testCases { + fmt.Printf("=== Test Case: %s ===\n", tc.name) + + var filePath string + var tempFile *os.File + if tc.isTemp { + filePath = tc.content + } else { + var err error + tempFile, err = os.CreateTemp("", "test_*.h") + if err != nil { + fmt.Printf("Failed to create temporary file: %v\n", err) + continue + } + + _, err = tempFile.Write([]byte(tc.content)) + if err != nil { + fmt.Printf("Failed to write to temporary file: %v\n", err) + tempFile.Close() + os.Remove(tempFile.Name()) + continue + } + tempFile.Close() + filePath = tempFile.Name() + } + + config := &clangutils.Config{ + File: filePath, + Temp: tc.isTemp, + IsCpp: tc.isCpp, + } + index, unit, err := clangutils.CreateTranslationUnit(config) + if err != nil { + fmt.Printf("CreateTranslationUnit failed: %v\n", err) + continue + } + + fmt.Println("CreateTranslationUnit succeeded") + + cursor := unit.Cursor() + + clangutils.VisitChildren(cursor, func(cursor, parent clang.Cursor) clang.ChildVisitResult { + switch cursor.Kind { + case clang.CursorFunctionDecl, clang.CursorCXXMethod: + funcName := cursor.String() + fmt.Printf("Function/Method: %s\n", c.GoString(funcName.CStr())) + parts := clangutils.BuildScopingParts(cursor) + fmt.Printf("Scoping parts: %v\n", parts) + funcName.Dispose() + case clang.CursorClassDecl: + className := cursor.String() + fmt.Printf("Class: %s\n", c.GoString(className.CStr())) + className.Dispose() + case clang.CursorNamespace: + namespaceName := cursor.String() + fmt.Printf("Namespace: %s\n", c.GoString(namespaceName.CStr())) + namespaceName.Dispose() + } + return clang.ChildVisit_Recurse + }) + index.Dispose() + unit.Dispose() + + if !tc.isTemp && tempFile != nil { + os.Remove(tempFile.Name()) + } + + fmt.Println() + } +} diff --git a/chore/_xtool/llcppsymg/_cmptest/clangutils_test/llgo.expect b/chore/_xtool/llcppsymg/_cmptest/clangutils_test/llgo.expect new file mode 100644 index 00000000..de8589e7 --- /dev/null +++ b/chore/_xtool/llcppsymg/_cmptest/clangutils_test/llgo.expect @@ -0,0 +1,23 @@ +#stdout +=== Test Case: C Header File === +CreateTranslationUnit succeeded +Function/Method: test_function +Scoping parts: [test_function] +Function/Method: another_function +Scoping parts: [another_function] + +=== Test Case: C++ Temp File === +CreateTranslationUnit succeeded +Class: TestClass +Function/Method: test_method +Scoping parts: [TestClass test_method] +Function/Method: static_method +Scoping parts: [TestClass static_method] +Namespace: TestNamespace +Function/Method: namespaced_function +Scoping parts: [TestNamespace namespaced_function] + + +#stderr + +#exit 0 diff --git a/chore/_xtool/llcppsymg/_cmptest/config_test/config.go b/chore/_xtool/llcppsymg/_cmptest/config_test/config.go new file mode 100644 index 00000000..6ef2e2d1 --- /dev/null +++ b/chore/_xtool/llcppsymg/_cmptest/config_test/config.go @@ -0,0 +1,63 @@ +package main + +import ( + "fmt" + "strings" + + "github.com/goplus/llgo/chore/_xtool/llcppsymg/config" +) + +func main() { + TestGetConf() +} + +func TestGetConf() { + testCases := []struct { + name string + input string + }{ + { + name: "SQLite configuration", + input: `{ + "name": "sqlite", + "cflags": "-I/opt/homebrew/opt/sqlite/include", + "include": ["sqlite3.h"], + "libs": "-L/opt/homebrew/opt/sqlite/lib -lsqlite3", + "trimPrefixes": ["sqlite3_"], + "cplusplus": false +}`, + }, + { + name: "Lua configuration", + input: `{ + "name": "lua", + "cflags": "-I/opt/homebrew/include/lua", + "include": ["lua.h"], + "libs": "-L/opt/homebrew/lib -llua -lm", + "trimPrefixes": ["lua_", "lua_"], + "cplusplus": false +}`, + }, + { + name: "Invalid JSON", + input: `{invalid json}`, + }, + } + + for _, tc := range testCases { + fmt.Printf("=== Test case: %s ===\n", tc.name) + result, err := config.GetConf([]byte(tc.input)) + + if err != nil { + fmt.Println("Error:", err.Error()) + } else { + fmt.Println("Name:", result.Config.Name) + fmt.Println("CFlags:", result.Config.CFlags) + fmt.Println("Libs:", result.Config.Libs) + fmt.Println("Include:", strings.Join(result.Config.Include, ", ")) + fmt.Println("TrimPrefixes:", strings.Join(result.Config.TrimPrefixes, ", ")) + fmt.Println("Cplusplus:", result.Config.Cplusplus) + } + fmt.Println() + } +} diff --git a/chore/_xtool/llcppsymg/_cmptest/config_test/llgo.expect b/chore/_xtool/llcppsymg/_cmptest/config_test/llgo.expect new file mode 100644 index 00000000..acbf814f --- /dev/null +++ b/chore/_xtool/llcppsymg/_cmptest/config_test/llgo.expect @@ -0,0 +1,24 @@ +#stdout +=== Test case: SQLite configuration === +Name: sqlite +CFlags: -I/opt/homebrew/opt/sqlite/include +Libs: -L/opt/homebrew/opt/sqlite/lib -lsqlite3 +Include: sqlite3.h +TrimPrefixes: sqlite3_ +Cplusplus: false + +=== Test case: Lua configuration === +Name: lua +CFlags: -I/opt/homebrew/include/lua +Libs: -L/opt/homebrew/lib -llua -lm +Include: lua.h +TrimPrefixes: lua_, lua_ +Cplusplus: false + +=== Test case: Invalid JSON === +Error: failed to parse config + + +#stderr + +#exit 0