Skip to content

Commit

Permalink
gogensig:read llcppg.pub
Browse files Browse the repository at this point in the history
  • Loading branch information
luoliwoshang committed Nov 11, 2024
1 parent 189ea7b commit 11238b0
Show file tree
Hide file tree
Showing 10 changed files with 196 additions and 79 deletions.
27 changes: 22 additions & 5 deletions chore/gogensig/cmptest/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import (
)

// The validateFunc is used to validate the generated file,
func RunTest(t *testing.T, pkgName string, isCpp bool, symbolEntries []config.SymbolEntry, cppgConf *cppgtypes.Config, originalCode, expectedOutput string, validateFunc func(t *testing.T, pkg *convert.Package)) {
RunTestWithCheckEqual(t, pkgName, isCpp, symbolEntries, cppgConf, originalCode, expectedOutput, validateFunc, CheckResult)
func RunTest(t *testing.T, pkgName string, isCpp bool, symbolEntries []config.SymbolEntry, public map[string]string, cppgConf *cppgtypes.Config, originalCode, expectedOutput string, validateFunc func(t *testing.T, pkg *convert.Package)) {
RunTestWithCheckEqual(t, pkgName, isCpp, symbolEntries, public, cppgConf, originalCode, expectedOutput, validateFunc, CheckResult)
}

func CheckResult(t *testing.T, expected, content string) {
Expand All @@ -27,7 +27,7 @@ func CheckResult(t *testing.T, expected, content string) {
}

// RunTestWithCheckEqual initializes a test Go project with local llgo dependency
func RunTestWithCheckEqual(t *testing.T, pkgName string, isCpp bool, symbolEntries []config.SymbolEntry, cppgConf *cppgtypes.Config, originalCode, expectedOutput string, validateFunc func(t *testing.T, pkg *convert.Package), checkEqual func(t *testing.T, expected, content string)) {
func RunTestWithCheckEqual(t *testing.T, pkgName string, isCpp bool, symbolEntries []config.SymbolEntry, public map[string]string, cppgConf *cppgtypes.Config, originalCode, expectedOutput string, validateFunc func(t *testing.T, pkg *convert.Package), checkEqual func(t *testing.T, expected, content string)) {
t.Helper()

tempDir, err := os.MkdirTemp("", "gogensig-test")
Expand Down Expand Up @@ -67,6 +67,10 @@ func RunTestWithCheckEqual(t *testing.T, pkgName string, isCpp bool, symbolEntri
if err != nil {
t.Fatal(err)
}
pubPath, err := CreatePubFile(public)
if err != nil {
t.Fatal(err)
}

// The result file will be generated in a directory based on the package name.
// For example, if the package name is "typeref", the result file will be generated in a directory named "typeref".
Expand All @@ -85,6 +89,7 @@ func RunTestWithCheckEqual(t *testing.T, pkgName string, isCpp bool, symbolEntri
SymbFile: symbolpath,
CfgFile: cfgPath,
OutputDir: outputDir,
PubFile: pubPath,
},
})
if err != nil {
Expand Down Expand Up @@ -131,15 +136,27 @@ func CreateCppgConfFile(config *cppgtypes.Config) (string, error) {
return CreateJSONFile("llcppg.cfg", config)
}

func CreatePubFile(public map[string]string) (string, error) {
filePath := filepath.Join(os.TempDir(), "llcppg.pub")
file, err := os.Create(filePath)
if err != nil {
return "", err
}
defer file.Close()
err = config.WritePubFile(filePath, public)
if err != nil {
return "", err
}
return filePath, nil
}

func CreateJSONFile(filename string, data interface{}) (string, error) {
filePath := filepath.Join(os.TempDir(), filename)

file, err := os.Create(filePath)
if err != nil {
return "", err
}
defer file.Close()

encoder := json.NewEncoder(file)
encoder.SetIndent("", " ")
return filePath, encoder.Encode(data)
Expand Down
58 changes: 58 additions & 0 deletions chore/gogensig/config/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io"
"os"
"os/exec"
"sort"
"strings"

"github.com/goplus/llgo/chore/gogensig/unmarshal"
Expand All @@ -27,6 +28,11 @@ func GetCppgCfgFromPath(filePath string) (*cppgtypes.Config, error) {
return conf, nil
}

// llcppg.pub
func GetPubFromPath(filePath string) (map[string]string, error) {
return ReadPubFile(filePath)
}

func GetCppgSigfetchFromByte(data []byte) (unmarshal.FileSet, error) {
return unmarshal.UnmarshalFileSet(data)
}
Expand Down Expand Up @@ -69,6 +75,58 @@ func ReadFile(filePath string) ([]byte, error) {
return io.ReadAll(jsonFile)
}

func ReadPubFile(pubfile string) (ret map[string]string, err error) {
b, err := os.ReadFile(pubfile)
if err != nil {
if os.IsNotExist(err) {
return make(map[string]string), nil
}
return
}

text := string(b)
lines := strings.Split(text, "\n")
ret = make(map[string]string, len(lines))
for i, line := range lines {
flds := strings.Fields(line)
goName := ""
switch len(flds) {
case 1:
case 2:
goName = flds[1]
case 0:
continue
default:
err = fmt.Errorf("%s:%d: too many fields", pubfile, i+1)
return
}
ret[flds[0]] = goName
}
return
}

func WritePubFile(file string, public map[string]string) (err error) {
if len(public) == 0 {
return
}
f, err := os.Create(file)
if err != nil {
return
}
defer f.Close()
ret := make([]string, 0, len(public))
for name, goName := range public {
if goName == "" {
ret = append(ret, name)
} else {
ret = append(ret, name+" "+goName)
}
}
sort.Strings(ret)
_, err = f.WriteString(strings.Join(ret, "\n"))
return
}

func RunCommand(dir, cmdName string, args ...string) error {
execCmd := exec.Command(cmdName, args...)
execCmd.Stdout = os.Stdout
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,85 @@ func TestRunCommand(t *testing.T) {
t.Fatal(err)
}
}

func TestGetPubFromPath(t *testing.T) {
pub, err := config.GetPubFromPath("./_testinput/llcppg.pub")
if err != nil {
t.Fatal(err)
}
if len(pub) != 3 {
t.Fatalf("expect 3 entries, got %d", len(pub))
}
if pub["file"] != "FILE" || pub["err"] != "Err" || pub["stdio"] != "" {
t.Fatalf("expect file, err, stdio, got %v", pub)
}
}

func TestGetPubFromPathError(t *testing.T) {
pub, err := config.GetPubFromPath("./_testinput/llcppg.txt")
if !(pub != nil && len(pub) == 0 && err == nil) {
t.Fatalf("expect empty map for llcppg.txt")
}
temp, err := os.CreateTemp("", "config_test")
if err != nil {
t.Fatal(err)
}
defer os.Remove(temp.Name())
content := `a b c`
_, err = temp.WriteString(content)
if err != nil {
t.Fatal(err)
}
_, err = config.GetPubFromPath(temp.Name())
if err == nil {
t.Fatalf("expect error, got nil")
}
}

func TestWritePubFile(t *testing.T) {
pub := map[string]string{
"file": "FILE",
"err": "Err",
"stdio": "",
}
tempDir, err := os.MkdirTemp("", "config_test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tempDir)
pubFile := filepath.Join(tempDir, "llcppg.pub")
err = config.WritePubFile(pubFile, pub)
if err != nil {
t.Fatal(err)
}
content, err := os.ReadFile(pubFile)
if err != nil {
t.Fatal(err)
}
expect :=
`err Err
file FILE
stdio`
if string(content) != expect {
t.Fatalf("expect %s, got %s", expect, string(content))
}

notExistFilePath := filepath.Join(tempDir, "not_exit_dir", "not_exist_file.pub")
err = config.WritePubFile(notExistFilePath, pub)
if err == nil {
t.Fatalf("expect error, got nil")
}
if !os.IsNotExist(err) {
t.Fatalf("expect os.IsNotExist error, got %v", err)
}

notExistFile := filepath.Join(tempDir, "not_exist_file.pub")
err = config.WritePubFile(notExistFile, make(map[string]string, 0))
if err != nil {
t.Fatalf("expect no error, got %v", err)
}
_, err = os.Stat(notExistFile)
if err != nil && !os.IsNotExist(err) {
t.Fatalf("expect file %s, got error %v", notExistFile, err)
}
}
1 change: 1 addition & 0 deletions chore/gogensig/convert/basic/basic.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func ConvertProcesser(cfg *Config) (*processor.DocFileSetProcessor, *convert.Pac
SymbFile: cfg.SymbFile,
CfgFile: cfg.CfgFile,
OutputDir: cfg.OutputDir,
PubFile: cfg.PubFile,
})
if err != nil {
return nil, nil, err
Expand Down
7 changes: 7 additions & 0 deletions chore/gogensig/convert/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type AstConvertConfig struct {
PkgName string
SymbFile string // llcppg.symb.json
CfgFile string // llcppg.cfg
PubFile string // llcppg.pub
OutputDir string
}

Expand All @@ -45,12 +46,18 @@ func NewAstConvert(config *AstConvertConfig) (*AstConvert, error) {
conf = &cppgtypes.Config{}
}

public, err := cfg.GetPubFromPath(config.PubFile)
if err != nil {
return nil, err
}

pkg := NewPackage(&PackageConfig{
PkgPath: ".",
Name: config.PkgName,
OutputDir: config.OutputDir,
SymbolTable: symbTable,
CppgConf: conf,
Public: public,
})
p.Pkg = pkg
return p, nil
Expand Down
24 changes: 12 additions & 12 deletions chore/gogensig/convert/convert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
)

func TestUnion(t *testing.T) {
cmptest.RunTest(t, "union", false, []config.SymbolEntry{}, &cppgtypes.Config{}, `
cmptest.RunTest(t, "union", false, []config.SymbolEntry{}, map[string]string{}, &cppgtypes.Config{}, `
typedef union __u
{
int a;
Expand All @@ -42,7 +42,7 @@ type U X__u
func TestReferStdSizeT(t *testing.T) {
cmptest.RunTest(t, "size_t", false, []config.SymbolEntry{
{MangleName: "testSize", CppName: "testSize", GoName: "TestSize"},
}, &cppgtypes.Config{}, `
}, map[string]string{}, &cppgtypes.Config{}, `
#include <stddef.h>
void testSize(size_t a);
Expand All @@ -62,9 +62,7 @@ func TestCommentSlashSlashSlash(t *testing.T) {
CppName: "ExecuteFoo",
GoName: "CustomExecuteFoo",
},
},
&cppgtypes.Config{},
`
}, map[string]string{}, &cppgtypes.Config{}, `
/// Foo comment
struct Foo { int a; double b; bool c; };
Expand All @@ -90,7 +88,7 @@ func CustomExecuteFoo(a c.Int, b Foo) c.Int
}

func TestEnum(t *testing.T) {
cmptest.RunTestWithCheckEqual(t, "spectrum", true, []config.SymbolEntry{}, &cppgtypes.Config{
cmptest.RunTestWithCheckEqual(t, "spectrum", true, []config.SymbolEntry{}, map[string]string{}, &cppgtypes.Config{
Cplusplus: true,
},
`
Expand Down Expand Up @@ -215,7 +213,7 @@ func TestStructDeclRef(t *testing.T) {
CppName: "ExecuteFoo",
GoName: "CustomExecuteFoo",
},
},
}, map[string]string{},
&cppgtypes.Config{},
`
struct Foo { int a; double b; bool c; };
Expand Down Expand Up @@ -246,7 +244,7 @@ func TestCustomStruct(t *testing.T) {
{MangleName: "lua_newthread", CppName: "lua_newthread", GoName: "Newthread"},
{MangleName: "lua_closethread", CppName: "lua_closethread", GoName: "Closethread"},
{MangleName: "lua_resetthread", CppName: "lua_resetthread", GoName: "Resetthread"},
}, &cppgtypes.Config{
}, map[string]string{}, &cppgtypes.Config{
TrimPrefixes: []string{"lua_"},
Include: []string{"temp.h"},
// prefix only remove in the llcppg.cfg includes
Expand Down Expand Up @@ -282,7 +280,7 @@ func Resetthread(L *State) c.Int
func TestAvoidKeyword(t *testing.T) {
cmptest.RunTest(t, "avoid", false, []config.SymbolEntry{
{MangleName: "lua_sethook", CppName: "lua_sethook", GoName: "Sethook"},
}, &cppgtypes.Config{}, `
}, map[string]string{}, &cppgtypes.Config{}, `
typedef struct lua_State lua_State;
typedef void (*lua_Hook)(lua_State *L, lua_Debug *ar);
void(lua_sethook)(lua_State *L, lua_Hook func, int mask, int count);
Expand Down Expand Up @@ -332,7 +330,7 @@ func TestSkipBuiltinTypedefine(t *testing.T) {
{MangleName: "testInt", CppName: "testInt", GoName: "TestInt"},
{MangleName: "testUint", CppName: "testUint", GoName: "TestUint"},
{MangleName: "testFile", CppName: "testFile", GoName: "TestFile"},
}, &cppgtypes.Config{
}, map[string]string{}, &cppgtypes.Config{
Deps: []string{
"github.com/goplus/llgo/chore/gogensig/convert/testdata/stdint",
"github.com/goplus/llgo/chore/gogensig/convert/testdata/stdio",
Expand Down Expand Up @@ -383,6 +381,8 @@ func TestFile(f *stdio.FILE)
func TestPubFile(t *testing.T) {
cmptest.RunTest(t, "pub", false, []config.SymbolEntry{
{MangleName: "func", CppName: "func", GoName: "Func"},
}, map[string]string{
"data": "CustomData",
}, &cppgtypes.Config{
Include: []string{"temp.h"},
}, `
Expand Down Expand Up @@ -421,7 +421,7 @@ type Capital struct {
Y c.Int
}
type Data struct {
type CustomData struct {
Str [20]int8
}
type Uint_t c.Uint
Expand All @@ -438,7 +438,7 @@ func Func(a c.Int, b c.Int)
expectedPub := `
Capital
color Color
data Data
data CustomData
point Point
uint_t Uint_t
`
Expand Down
Loading

0 comments on commit 11238b0

Please sign in to comment.