-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathexample_converting_enums_test.go
74 lines (64 loc) · 1.85 KB
/
example_converting_enums_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package bindgen_test
import (
"bytes"
"fmt"
"strings"
"github.com/gorgonia/bindgen"
"modernc.org/cc"
)
// genEnums represents a list of enums we want to generate
var genEnums = map[bindgen.TypeKey]struct{}{
{Kind: cc.Enum, Name: "error"}: {},
}
var enumMappings = map[bindgen.TypeKey]string{
{Kind: cc.Enum, Name: "error"}: "Status",
}
// This is an example of how to convert enums.
func Example_convertingEnums() {
t, err := bindgen.Parse(bindgen.Model(), "testdata/dummy.h")
if err != nil {
panic(err)
}
enums := func(decl *cc.Declarator) bool {
name := bindgen.NameOf(decl)
kind := decl.Type.Kind()
tk := bindgen.TypeKey{Kind: kind, Name: name}
if _, ok := genEnums[tk]; ok {
return true
}
return false
}
decls, err := bindgen.Get(t, enums)
if err != nil {
panic(err)
}
var buf bytes.Buffer
for _, d := range decls {
// first write the type
// type ___ int
// This is possible because cznic/cc parses all enums as int.
//
// you are clearly free to add your own mapping.
e := d.(*bindgen.Enum)
tk := bindgen.TypeKey{Kind: cc.Enum, Name: e.Name}
fmt.Fprintf(&buf, "type %v int\nconst (\n", enumMappings[tk])
// then write the const definitions:
// const(...)
for _, a := range e.Type.EnumeratorList() {
// this is a straightforwards mapping of the C defined name. The name is kept exactly the same, with a lowecase mapping
// in real life, you might not want this, (for example, you may not want to export the names, which are typically in all caps),
// or you might want different names
enumName := string(a.DefTok.S())
goName := strings.ToLower(enumName)
fmt.Fprintf(&buf, "%v %v = C.%v\n", goName, enumMappings[tk], enumName)
}
buf.Write([]byte(")\n"))
}
fmt.Println(buf.String())
// Output:
// type Status int
// const (
// success Status = C.SUCCESS
// failure Status = C.FAILURE
// )
}