func (w *Writer) genTypeDef(d *cc.Decl) { w.writeDocString(d.Name, "") goName := cNameToGoUpper(d.Name) switch d.Type.Kind { case cc.Struct: if d.Type.Decls == nil || goName == "Path" { // Opaque typedef. w.Print(`type %s struct { Ptr *C.%s }`, goName, d.Name) cFinalizer := d.Name if strings.HasSuffix(cFinalizer, "_t") { cFinalizer = cFinalizer[:len(cFinalizer)-2] } cFinalizer += "_destroy" w.Print("func free%s(obj *%s) {", goName, goName) w.Print("C.%s(obj.Ptr)", cFinalizer) w.Print("}") w.Print("func wrap%s(p *C.%s) *%s {", goName, d.Name, goName) w.Print("ret := &%s{p}", goName) w.Print("runtime.SetFinalizer(ret, free%s)", goName) w.Print("return ret") w.Print("}") } else { sharedTypes[d.Name] = goName w.Print("type %s struct {", goName) for _, d := range d.Type.Decls { typ := cTypeToMap(d.Type) w.Print("%s %s", cNameToGoUpper(d.Name), typ.goType) } w.Print("}") } case cc.Enum: type constEntry struct { goName, cName string } consts := make([]constEntry, 0, len(d.Type.Decls)) for _, d := range d.Type.Decls { constName := d.Name if strings.HasPrefix(constName, "CAIRO_") { constName = constName[len("CAIRO_"):] } constName = cNameToGoUpper(strings.ToLower(d.Name)) consts = append(consts, constEntry{constName, d.Name}) } w.Print("type %s int", goName) w.Print("const (") for _, c := range consts { w.Print("%s %s = C.%s", c.goName, goName, c.cName) } w.Print(")") if goName != "Status" { w.Print("func (i %s) String() string {", goName) w.Print("switch i {") for _, c := range consts { w.Print("case %s: return \"%s\"", c.goName, c.goName) } w.Print("default: return fmt.Sprintf(\"%s(%%d)\", i)", goName) w.Print("}") w.Print("}") } default: panic("unhandled decl " + d.String()) } }
func (w *Writer) genTypeDef(d *cc.Decl) { w.writeDocString(d.Name, "") goName := cNameToGoUpper(d.Name) switch d.Type.Kind { case cc.Struct: if d.Type.Decls == nil || goName == "Path" { // Opaque typedef. w.Print(`type %s struct { Ptr *C.%s }`, goName, d.Name) cFinalizer := d.Name if strings.HasSuffix(cFinalizer, "_t") { cFinalizer = cFinalizer[:len(cFinalizer)-2] } cFinalizer += "_destroy" w.Print("func free%s(obj *%s) {", goName, goName) w.Print("C.%s(obj.Ptr)", cFinalizer) w.Print("}") w.Print("func wrap%s(p *C.%s) *%s {", goName, d.Name, goName) w.Print("ret := &%s{p}", goName) w.Print("runtime.SetFinalizer(ret, free%s)", goName) w.Print("return ret") w.Print("}") w.Print("// Wrap a C %s* found from some external source as a *%s. The Go side will destroy the reference when it's no longer used.", d.Name, goName) w.Print("func Wrap%s(p unsafe.Pointer) *%s {", goName, goName) w.Print("return wrap%s((*C.%s)(p))", goName, d.Name) w.Print("}") w.Print("// Construct a %s from a C %s* found from some exernal source. It is the caller's responsibility to ensure the pointer lives.", goName, d.Name) w.Print("func Borrow%s(p unsafe.Pointer) *%s {", goName, goName) w.Print("return &%s{(*C.%s)(p)}", goName, d.Name) w.Print("}") } else { sharedTypes[d.Name] = goName w.Print("type %s struct {", goName) for _, d := range d.Type.Decls { typ := cTypeToMap(d.Type) w.Print("%s %s", cNameToGoUpper(d.Name), typ.goType) } w.Print("}") } case cc.Enum: type constEntry struct { goName, cName string } consts := make([]constEntry, 0, len(d.Type.Decls)) for _, d := range d.Type.Decls { constName := d.Name if strings.HasPrefix(constName, "CAIRO_") { constName = constName[len("CAIRO_"):] } constName = cNameToGoUpper(strings.ToLower(d.Name)) consts = append(consts, constEntry{constName, d.Name}) } w.Print("type %s int", goName) w.Print("const (") for _, c := range consts { w.Print("%s %s = C.%s", c.goName, goName, c.cName) } w.Print(")") if goName != "Status" { w.Print("// String implements the Stringer interface, which is used in places like fmt's %%q. For all enums like this it returns the Go name of the constant.") w.Print("func (i %s) String() string {", goName) w.Print("switch i {") for _, c := range consts { w.Print("case %s: return \"%s\"", c.goName, c.goName) } w.Print("default: return fmt.Sprintf(\"%s(%%d)\", i)", goName) w.Print("}") w.Print("}") } default: panic("unhandled decl " + d.String()) } }