Skip to content

Commit

Permalink
add an optional expression which can be used to default a slice length
Browse files Browse the repository at this point in the history
you can add a configuration in the yaml file for the expression to use:

```yaml
TRANSLATOR:
  LenFields:
    MyStruct.some_data: some_size
```
  • Loading branch information
James Strachan authored and xlab committed May 25, 2023
1 parent 561696b commit 591bf68
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 21 deletions.
15 changes: 12 additions & 3 deletions generator/gen_bindings.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,8 @@ The caller is responsible for freeing the this memory via C.free.`, name, cgoSpe
}
return mem
}`, name, sizeofConst)
fmt.Fprintln(buf, "\n")
fmt.Fprintln(buf)
fmt.Fprintln(buf)
fmt.Fprintf(buf, `const %s = unsafe.Sizeof([1]%s{})`, sizeofConst, cgoSpec)

helper.Source = buf.String()
Expand Down Expand Up @@ -787,7 +788,7 @@ func (gen *Generator) proxyArgToGo(memTip tl.Tip, varName, ptrName string,
}

func (gen *Generator) proxyValueToGo(memTip tl.Tip, varName, ptrName string,
goSpec tl.GoTypeSpec, cgoSpec tl.CGoSpec) (proxy string, nillable bool) {
goSpec tl.GoTypeSpec, cgoSpec tl.CGoSpec, lenField string) (proxy string, nillable bool) {
nillable = true

if goSpec.IsGoString() {
Expand Down Expand Up @@ -829,7 +830,15 @@ func (gen *Generator) proxyValueToGo(memTip tl.Tip, varName, ptrName string,
fmt.Fprintf(buf, "hx%2x := (*sliceHeader)(unsafe.Pointer(&%s))\n", postfix, varName)
fmt.Fprintf(buf, "hx%2x.Data = unsafe.Pointer(%s)\n", postfix, ptrName)
fmt.Fprintf(buf, "hx%2x.Cap = %s\n", postfix, gen.maxMem)
fmt.Fprintf(buf, "// hx%2x.Len = ?\n", postfix)

// check if we have a configuration for a custom length property
idx := strings.LastIndex(ptrName, ".")
if lenField != "" && idx > 0 {
// replace the `x.refxxxxx.some_field` suffix with the lenField name
fmt.Fprintf(buf, "hx%2x.Len = int(%s)\n", postfix, ptrName[0:idx+1]+lenField)
} else {
fmt.Fprintf(buf, "// hx%2x.Len = ? %s %s\n", postfix, varName, ptrName)
}
proxy = buf.String()
return
case isPlain: // ex: byte, [4]byte
Expand Down
24 changes: 17 additions & 7 deletions generator/gen_struct_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,15 +208,16 @@ func (gen *Generator) getRawStructHelpers(goStructName []byte, cStructName strin
goSpec.Pointers += 1
cgoSpec.Pointers += 1
}
fmt.Fprintf(buf,"func (s *%s) Get%s() %s {\n", goStructName, goName, goSpec)
toProxy, _ := gen.proxyValueToGo(memTip, "ret", "&s." + m.Name, goSpec, cgoSpec)
fmt.Fprintf(buf,"\tvar ret %s\n", goSpec)
fmt.Fprintf(buf,"\t%s\n",toProxy)
fmt.Fprintf(buf, "func (s *%s) Get%s() %s {\n", goStructName, goName, goSpec)
lenField := getLenField(gen, structSpec, m)
toProxy, _ := gen.proxyValueToGo(memTip, "ret", "&s."+m.Name, goSpec, cgoSpec, lenField)
fmt.Fprintf(buf, "\tvar ret %s\n", goSpec)
fmt.Fprintf(buf, "\t%s\n", toProxy)
fmt.Fprintf(buf, "\treturn ret\n")
fmt.Fprintf(buf, "}\n")
helpers = append(helpers, &Helper{
Name: fmt.Sprintf("%s.Get%s", goStructName, goName),
Description: fmt.Sprintf("Get%s returns a reference to C object within a struct",goName),
Name: fmt.Sprintf("%s.Get%s", goStructName, goName),
Description: fmt.Sprintf("Get%s returns a reference to C object within a struct", goName),
Source: buf.String(),
})
}
Expand Down Expand Up @@ -345,8 +346,17 @@ func (gen *Generator) getDerefSource(goStructName []byte, cStructName string, sp
goName := "x." + string(gen.tr.TransformName(tl.TargetType, m.Name, public))
cgoName := fmt.Sprintf("x.ref%2x.%s", crc, m.Name)
cgoSpec := gen.tr.CGoSpec(m.Spec, false)
toProxy, _ := gen.proxyValueToGo(memTip, goName, cgoName, goSpec, cgoSpec)
lenField := getLenField(gen, structSpec, m)
toProxy, _ := gen.proxyValueToGo(memTip, goName, cgoName, goSpec, cgoSpec, lenField)
fmt.Fprintln(buf, toProxy)
}
return buf.Bytes()
}

func getLenField(gen *Generator, structSpec *tl.CStructSpec, m *tl.CDecl) string {
lenField := ""
if gen.tr.LenFields() != nil {
lenField = gen.tr.LenFields()[structSpec.Typedef+"."+m.Name]
}
return lenField
}
29 changes: 18 additions & 11 deletions translator/translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ type Translator struct {
builtinTypemap2 CTypeMap
ignoredFiles map[string]struct{}

valueMap map[string]Value
exprMap map[string]string
tagMap map[string]*CDecl
valueMap map[string]Value
exprMap map[string]string
tagMap map[string]*CDecl
lenFields map[string]string

defines []*CDecl
typedefs []*CDecl
Expand Down Expand Up @@ -78,14 +79,15 @@ func (t TipSpecRx) Self() Tip {
}

type Config struct {
Rules Rules `yaml:"Rules"`
ConstRules ConstRules `yaml:"ConstRules"`
PtrTips PtrTips `yaml:"PtrTips"`
TypeTips TypeTips `yaml:"TypeTips"`
MemTips MemTips `yaml:"MemTips"`
Typemap CTypeMap `yaml:"Typemap"`
ConstCharIsString *bool `yaml:"ConstCharIsString"`
ConstUCharIsString *bool `yaml:"ConstUCharIsString"`
Rules Rules `yaml:"Rules"`
ConstRules ConstRules `yaml:"ConstRules"`
PtrTips PtrTips `yaml:"PtrTips"`
TypeTips TypeTips `yaml:"TypeTips"`
MemTips MemTips `yaml:"MemTips"`
Typemap CTypeMap `yaml:"Typemap"`
ConstCharIsString *bool `yaml:"ConstCharIsString"`
ConstUCharIsString *bool `yaml:"ConstUCharIsString"`
LenFields map[string]string `yaml:"LenFields"`

IgnoredFiles []string `yaml:"-"`
LongIs64Bit bool `yaml:"-"`
Expand Down Expand Up @@ -122,6 +124,7 @@ func New(cfg *Config) (*Translator, error) {
valueMap: make(map[string]Value),
exprMap: make(map[string]string),
tagMap: make(map[string]*CDecl),
lenFields: cfg.LenFields,
typedefsSet: make(map[string]struct{}),
typedefKinds: make(map[string]CTypeKind),
ignoredFiles: make(map[string]struct{}),
Expand Down Expand Up @@ -1016,6 +1019,10 @@ func (t *Translator) TagMap() map[string]*CDecl {
return t.tagMap
}

func (t *Translator) LenFields() map[string]string {
return t.lenFields
}

func (t *Translator) ExpressionMap() map[string]string {
return t.exprMap
}
Expand Down

0 comments on commit 591bf68

Please sign in to comment.