Skip to content

Commit

Permalink
generate: iterate on function support
Browse files Browse the repository at this point in the history
  • Loading branch information
tmc committed Aug 21, 2023
1 parent 009a114 commit cb59698
Show file tree
Hide file tree
Showing 14 changed files with 226 additions and 78 deletions.
19 changes: 18 additions & 1 deletion generate/codegen/gen_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func (f *Function) GoReturn(currentModule *modules.Module) string {
if f.ReturnType == nil {
return ""
}
log.Printf("rendering GoReturn function return: %s %T", f.ReturnType, f.ReturnType)
return f.ReturnType.GoName(currentModule, true)
}

Expand Down Expand Up @@ -127,10 +128,26 @@ func (f *Function) WriteGoCallCode(currentModule *modules.Module, cw *CodeWriter
cw.WriteLine("}")
}

func (f *Function) WriteObjcWrapper(currentModule *modules.Module, cw *CodeWriter) {
if f.Deprecated {
return
cw.WriteLine("// deprecated")
}
returnTypeStr := f.Type.ReturnType.CName()
cw.WriteLineF("%v %v(%v) {", returnTypeStr, f.GoName, f.CArgs(currentModule))
cw.Indent()
var args []string
for _, p := range f.Parameters {
args = append(args, p.Name)
}
cw.WriteLineF("return %v(%v);", f.Type.Name, strings.Join(args, ", "))
cw.UnIndent()
cw.WriteLine("}")
}

func (f *Function) WriteCSignature(currentModule *modules.Module, cw *CodeWriter) {
var returnTypeStr string
rt := f.Type.ReturnType
log.Printf("rt: %T", rt)
returnTypeStr = rt.CName()
cw.WriteLineF("// %v %v(%v); ", returnTypeStr, f.GoName, f.CArgs(currentModule))
}
Expand Down
2 changes: 1 addition & 1 deletion generate/codegen/gen_struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

// Struct is code generator for objective-c struct
type Struct struct {
Type *typing.StructType
Type typing.Type
Name string // the first part of objc function name
GoName string
Deprecated bool // if has been deprecated
Expand Down
38 changes: 33 additions & 5 deletions generate/codegen/modulewriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func (m *ModuleWriter) WriteCode() {
m.WriteTypeAliases()
m.WriteStructs()
m.WriteFunctions()
m.WriteFunctionWrappers()
if m.Module.Package == "coreimage" {
// filter protocols maybe arent "real" protocols?
// get "cannot find protocol declaration" with protocol imports
Expand Down Expand Up @@ -117,19 +118,20 @@ func (m *ModuleWriter) WriteStructs() {
cw.WriteLine(")")

for _, s := range m.Structs {
if s.DocURL != "" {
cw.WriteLine(fmt.Sprintf("// %s [Full Topic]", s.Description))
cw.WriteLine(fmt.Sprintf("//\n// [Full Topic]: %s", s.DocURL))
}

// if Ref type, allias to unsafe.Pointer
if strings.HasSuffix(s.Name, "Ref") {
if s.DocURL != "" {
cw.WriteLine(fmt.Sprintf("// %s [Full Topic]", s.Description))
cw.WriteLine(fmt.Sprintf("//\n// [Full Topic]: %s", s.DocURL))
}

cw.WriteLineF("type %s unsafe.Pointer", s.GoName)
continue
}
}
}

// WriteFunctions writes the go code to call exposed functions.
func (m *ModuleWriter) WriteFunctions() {
if len(m.Functions) == 0 {
return
Expand Down Expand Up @@ -177,6 +179,32 @@ func (m *ModuleWriter) WriteFunctions() {
}
}

// WriteFunctionWrappers writes the objc code to wrap exposed functions.
// The cgo type system is unaware of objective c types so these wrappers must exist to allow
// us to call the functions and return appropritely.
func (m *ModuleWriter) WriteFunctionWrappers() {
if len(m.Functions) == 0 {
return
}

filePath := filepath.Join(m.PlatformDir, m.Module.Package, "functions.gen.m")
os.MkdirAll(filepath.Dir(filePath), 0755)
f, err := os.Create(filePath)
if err != nil {
panic(err)
}
defer f.Close()

cw := &CodeWriter{Writer: f, IndentStr: "\t"}
cw.WriteLine(AutoGeneratedMark)

//TODO: determine appropriate imports
cw.WriteLineF("#import \"%s\"", m.Module.Header)
for _, f := range m.Functions {
f.WriteObjcWrapper(&m.Module, cw)
}
}

func (m *ModuleWriter) WriteEnumAliases() {
enums := make([]*AliasInfo, len(m.EnumAliases))
copy(enums, m.EnumAliases)
Expand Down
3 changes: 2 additions & 1 deletion generate/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"log"

"github.com/progrium/macdriver/generate/codegen"
"github.com/progrium/macdriver/generate/modules"
"github.com/progrium/macdriver/generate/typing"
)

Expand Down Expand Up @@ -253,7 +254,7 @@ func (db *Generator) ToFunction(fw string, sym Symbol) *codegen.Function {
}
fn := &codegen.Function{
Name: sym.Name,
GoName: sym.Name,
GoName: modules.TrimPrefix(sym.Name),
Description: sym.Description,
DocURL: sym.DocURL(),
Type: fntyp,
Expand Down
6 changes: 3 additions & 3 deletions generate/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,11 @@ func (db *Generator) Generate(platform string, version int, rootDir string, fram
}
mw.Functions = append(mw.Functions, fn)
case "Struct":
fn := db.ToStruct(framework, s)
if fn == nil {
s := db.ToStruct(framework, s)
if s == nil {
continue
}
mw.Structs = append(mw.Structs, fn)
mw.Structs = append(mw.Structs, s)
}
}
mw.WriteCode()
Expand Down
7 changes: 1 addition & 6 deletions generate/struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (

"github.com/progrium/macdriver/generate/codegen"
"github.com/progrium/macdriver/generate/modules"
"github.com/progrium/macdriver/generate/typing"
)

func (db *Generator) ToStruct(fw string, sym Symbol) *codegen.Struct {
Expand All @@ -16,16 +15,12 @@ func (db *Generator) ToStruct(fw string, sym Symbol) *codegen.Struct {
return nil
}
typ := db.TypeFromSymbol(sym)
styp, ok := typ.(*typing.StructType)
if !ok {
return nil
}
s := &codegen.Struct{
Name: sym.Name,
GoName: modules.TrimPrefix(sym.Name),
Description: sym.Description,
DocURL: sym.DocURL(),
Type: styp,
Type: typ,
}

return s
Expand Down
21 changes: 15 additions & 6 deletions generate/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ func (db *Generator) TypeFromSymbol(sym Symbol) typing.Type {
}
case "Union":
return &typing.RefType{
Name: sym.Name,
Name: sym.Name,
GName: modules.TrimPrefix(sym.Name),
}
case "Type":
if sym.Type != "Type Alias" {
Expand All @@ -60,7 +61,8 @@ func (db *Generator) TypeFromSymbol(sym Symbol) typing.Type {
// sym.Name == "NSZone" ||
sym.Name == "MusicSequence" {
return &typing.RefType{
Name: sym.Name,
Name: sym.Name,
GName: modules.TrimPrefix(sym.Name),
}
}
st, err := sym.Parse()
Expand All @@ -70,7 +72,8 @@ func (db *Generator) TypeFromSymbol(sym Symbol) typing.Type {
}
if st.Struct != nil {
return &typing.RefType{
Name: st.Struct.Name,
Name: st.Struct.Name,
GName: modules.TrimPrefix(sym.Name),
}
}
if st.TypeAlias == nil {
Expand All @@ -91,7 +94,9 @@ func (db *Generator) TypeFromSymbol(sym Symbol) typing.Type {
case "Struct":
if strings.HasSuffix(sym.Name, "Ref") {
return &typing.RefType{
Name: sym.Name,
Name: sym.Name,
GName: modules.TrimPrefix(sym.Name),
Module: modules.Get(module),
}
}
return &typing.StructType{
Expand All @@ -100,7 +105,8 @@ func (db *Generator) TypeFromSymbol(sym Symbol) typing.Type {
Module: modules.Get(module),
}
case "Function":
if sym.Name != "CGDisplayCreateImage" {
if sym.Name != "CGDisplayCreateImage" &&
sym.Name != "CGMainDisplayID" {
return nil
}
typ, err := sym.Parse()
Expand Down Expand Up @@ -219,7 +225,10 @@ func (db *Generator) ParseType(ti declparse.TypeInfo) (typ typing.Type) {
}
ref = true
case "NSZone", "ipc_port_t":
typ = &typing.RefType{Name: ti.Name}
typ = &typing.RefType{
Name: ti.Name,
GName: modules.TrimPrefix(ti.Name),
}
ref = true
case "NSDictionary":
dt := &typing.DictType{}
Expand Down
18 changes: 12 additions & 6 deletions generate/typing/ref_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,23 @@ import (

// for weird struct refs like those ending in "Ref"
type RefType struct {
Name string // c and objc type name
// GName string // the go struct name
// Module *modules.Module // the module
Name string // c and objc type name
GName string // the go struct name
Module *modules.Module // the module
}

func (s *RefType) GoImports() set.Set[string] {
return set.New("unsafe")
if s.Module == nil {
return set.New("unsafe")
}
return set.New("github.com/progrium/macdriver/macos/" + s.Module.Package)
}

func (s *RefType) GoName(currentModule *modules.Module, receiveFromObjc bool) string {
return "unsafe.Pointer"
if s.Module == nil {
return "unsafe.Pointer"
}
return FullGoName(*s.Module, s.GName, *currentModule)
}

func (s *RefType) ObjcName() string {
Expand All @@ -30,5 +36,5 @@ func (s *RefType) CName() string {
}

func (s *RefType) DeclareModule() *modules.Module {
return nil
return s.Module
}
14 changes: 8 additions & 6 deletions macos/coregraphics/aliastypes.gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ package coregraphics
import (
"unsafe"

"github.com/progrium/macdriver/macos/corefoundation"
"github.com/progrium/macdriver/macos/iosurface"
"github.com/progrium/macdriver/objc"
)

Expand Down Expand Up @@ -46,12 +48,12 @@ type DataProviderReleaseBytePointerCallback = func(info unsafe.Pointer, pointer
// Draws a pattern cell. [Full Topic]
//
// [Full Topic]: https://developer.apple.com/documentation/coregraphics/cgpatterndrawpatterncallback?language=objc
type PatternDrawPatternCallback = func(info unsafe.Pointer, context unsafe.Pointer)
type PatternDrawPatternCallback = func(info unsafe.Pointer, context ContextRef)

// Passes messages generated during a PostScript conversion process. [Full Topic]
//
// [Full Topic]: https://developer.apple.com/documentation/coregraphics/cgpsconvertermessagecallback?language=objc
type PSConverterMessageCallback = func(info unsafe.Pointer, message unsafe.Pointer)
type PSConverterMessageCallback = func(info unsafe.Pointer, message corefoundation.StringRef)

// A client-supplied callback function that’s invoked whenever the configuration of a local display is changed. [Full Topic]
//
Expand All @@ -66,7 +68,7 @@ type PSConverterProgressCallback = func(info unsafe.Pointer)
// A client-supplied callback function that’s invoked whenever an associated event tap receives a Quartz event. [Full Topic]
//
// [Full Topic]: https://developer.apple.com/documentation/coregraphics/cgeventtapcallback?language=objc
type EventTapCallBack = func(proxy unsafe.Pointer, type_ EventType, event unsafe.Pointer, userInfo unsafe.Pointer) unsafe.Pointer
type EventTapCallBack = func(proxy unsafe.Pointer, type_ EventType, event EventRef, userInfo unsafe.Pointer) EventRef

// Copies data from a Core Graphics-supplied buffer into a data consumer. [Full Topic]
//
Expand Down Expand Up @@ -111,7 +113,7 @@ type PSConverterReleaseInfoCallback = func(info unsafe.Pointer)
// Performs custom tasks at the beginning of each page in a PostScript conversion process. [Full Topic]
//
// [Full Topic]: https://developer.apple.com/documentation/coregraphics/cgpsconverterbeginpagecallback?language=objc
type PSConverterBeginPageCallback = func(info unsafe.Pointer, pageNumber uint, pageInfo unsafe.Pointer)
type PSConverterBeginPageCallback = func(info unsafe.Pointer, pageNumber uint, pageInfo corefoundation.DictionaryRef)

// Performs custom clean-up tasks when Core Graphics deallocates a CGFunctionRef object. [Full Topic]
//
Expand All @@ -136,12 +138,12 @@ type ErrorCallback = func()
// Performs custom tasks at the end of each page of a PostScript conversion process. [Full Topic]
//
// [Full Topic]: https://developer.apple.com/documentation/coregraphics/cgpsconverterendpagecallback?language=objc
type PSConverterEndPageCallback = func(info unsafe.Pointer, pageNumber uint, pageInfo unsafe.Pointer)
type PSConverterEndPageCallback = func(info unsafe.Pointer, pageNumber uint, pageInfo corefoundation.DictionaryRef)

// A block called when a data stream has a new frame event to process. [Full Topic]
//
// [Full Topic]: https://developer.apple.com/documentation/coregraphics/cgdisplaystreamframeavailablehandler?language=objc
type DisplayStreamFrameAvailableHandler = func(status DisplayStreamFrameStatus, displayTime uint64, frameSurface unsafe.Pointer, updateRef unsafe.Pointer)
type DisplayStreamFrameAvailableHandler = func(status DisplayStreamFrameStatus, displayTime uint64, frameSurface iosurface.Ref, updateRef DisplayStreamUpdateRef)

// Performs custom operations on the supplied input data to produce output data. [Full Topic]
//
Expand Down
20 changes: 13 additions & 7 deletions macos/coregraphics/functions.gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,22 @@ package coregraphics
// #import <stdint.h>
// #import <stdbool.h>
// #import <CoreGraphics/CGGeometry.h>
// void * CGDisplayCreateImage(uint32_t displayID);
// uint32_t MainDisplayID();
// void * DisplayCreateImage(uint32_t displayID);
import "C"
import (
"unsafe"
)

// Returns the display ID of the main display. [Full Topic]
//
// [Full Topic]: https://developer.apple.com/documentation/coregraphics/1455620-cgmaindisplayid?language=objc
func MainDisplayID() DirectDisplayID {
rv := C.MainDisplayID()
return DirectDisplayID(rv)
}

// Returns an image containing the contents of the specified display. [Full Topic]
//
// [Full Topic]: https://developer.apple.com/documentation/coregraphics/1455691-cgdisplaycreateimage?language=objc
func DisplayCreateImage(displayID DirectDisplayID) unsafe.Pointer {
rv := C.CGDisplayCreateImage(C.uint32_t(displayID))
return unsafe.Pointer(rv)
func DisplayCreateImage(displayID DirectDisplayID) ImageRef {
rv := C.DisplayCreateImage(C.uint32_t(displayID))
return ImageRef(rv)
}
9 changes: 9 additions & 0 deletions macos/coregraphics/functions.gen.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// AUTO-GENERATED CODE, DO NOT MODIFY

#import "CoreGraphics/CoreGraphics.h"
uint32_t MainDisplayID() {
return CGMainDisplayID();
}
void * DisplayCreateImage(uint32_t displayID) {
return CGDisplayCreateImage(displayID);
}
6 changes: 0 additions & 6 deletions macos/coregraphics/functions.m

This file was deleted.

Loading

0 comments on commit cb59698

Please sign in to comment.