Performance improvements (do not parse addresses or locations unless
location tracking is enabled). Allow profiling option. Add some comments and clean-ups to types/*.go.
This commit is contained in:
parent
49fd749fe3
commit
8de87cddb7
|
@ -8,6 +8,8 @@ import (
|
||||||
"github.com/elliotchance/c2go/util"
|
"github.com/elliotchance/c2go/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var TrackPositions bool = false
|
||||||
|
|
||||||
// Node represents any node in the AST.
|
// Node represents any node in the AST.
|
||||||
type Node interface {
|
type Node interface {
|
||||||
Address() Address
|
Address() Address
|
||||||
|
@ -27,6 +29,9 @@ type Address uint64
|
||||||
// ParseAddress returns the integer representation of the hexadecimal address
|
// ParseAddress returns the integer representation of the hexadecimal address
|
||||||
// (like 0x7f8a1d8ccfd0). If the address cannot be parsed, 0 is returned.
|
// (like 0x7f8a1d8ccfd0). If the address cannot be parsed, 0 is returned.
|
||||||
func ParseAddress(address string) Address {
|
func ParseAddress(address string) Address {
|
||||||
|
if !TrackPositions {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
addr, _ := strconv.ParseUint(address, 0, 64)
|
addr, _ := strconv.ParseUint(address, 0, 64)
|
||||||
|
|
||||||
return Address(addr)
|
return Address(addr)
|
||||||
|
@ -318,7 +323,6 @@ func groupsFromRegex(rx, line string) map[string]string {
|
||||||
rx = fullRegexp + "[\\s]*$"
|
rx = fullRegexp + "[\\s]*$"
|
||||||
|
|
||||||
re := util.GetRegex(rx)
|
re := util.GetRegex(rx)
|
||||||
|
|
||||||
match := re.FindStringSubmatch(line)
|
match := re.FindStringSubmatch(line)
|
||||||
if len(match) == 0 {
|
if len(match) == 0 {
|
||||||
panic("could not match regexp with string\n" + rx + "\n" + line + "\n")
|
panic("could not match regexp with string\n" + rx + "\n" + line + "\n")
|
||||||
|
|
|
@ -20,7 +20,7 @@ func parseBinaryOperator(line string) *BinaryOperator {
|
||||||
Addr: ParseAddress(groups["address"]),
|
Addr: ParseAddress(groups["address"]),
|
||||||
Pos: NewPositionFromString(groups["position"]),
|
Pos: NewPositionFromString(groups["position"]),
|
||||||
Type: groups["type1"],
|
Type: groups["type1"],
|
||||||
Type2: groups["type2"],
|
//Type2: groups["type2"],
|
||||||
Operator: groups["operator"],
|
Operator: groups["operator"],
|
||||||
ChildNodes: []Node{},
|
ChildNodes: []Node{},
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ func parseCStyleCastExpr(line string) *CStyleCastExpr {
|
||||||
Addr: ParseAddress(groups["address"]),
|
Addr: ParseAddress(groups["address"]),
|
||||||
Pos: NewPositionFromString(groups["position"]),
|
Pos: NewPositionFromString(groups["position"]),
|
||||||
Type: groups["type1"],
|
Type: groups["type1"],
|
||||||
Type2: groups["type2"],
|
//Type2: groups["type2"],
|
||||||
Kind: groups["kind"],
|
Kind: groups["kind"],
|
||||||
ChildNodes: []Node{},
|
ChildNodes: []Node{},
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,19 +27,19 @@ func parseEnumConstantDecl(line string) *EnumConstantDecl {
|
||||||
line,
|
line,
|
||||||
)
|
)
|
||||||
|
|
||||||
type2 := groups["type2"]
|
/*type2 := groups["type2"]
|
||||||
if type2 != "" {
|
if type2 != "" {
|
||||||
type2 = type2[2 : len(type2)-1]
|
type2 = type2[2 : len(type2)-1]
|
||||||
}
|
}*/
|
||||||
|
|
||||||
return &EnumConstantDecl{
|
return &EnumConstantDecl{
|
||||||
Addr: ParseAddress(groups["address"]),
|
Addr: ParseAddress(groups["address"]),
|
||||||
Pos: NewPositionFromString(groups["position"]),
|
Pos: NewPositionFromString(groups["position"]),
|
||||||
Position2: groups["position2"],
|
//Position2: groups["position2"],
|
||||||
Referenced: len(groups["referenced"]) > 0,
|
Referenced: len(groups["referenced"]) > 0,
|
||||||
Name: strings.TrimSpace(groups["name"]),
|
Name: strings.TrimSpace(groups["name"]),
|
||||||
Type: removeQuotes(groups["type"]),
|
Type: removeQuotes(groups["type"]),
|
||||||
Type2: type2,
|
//Type2: type2,
|
||||||
ChildNodes: []Node{},
|
ChildNodes: []Node{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,18 +26,18 @@ func parseEnumDecl(line string) *EnumDecl {
|
||||||
line,
|
line,
|
||||||
)
|
)
|
||||||
|
|
||||||
type2 := groups["type2"]
|
/*type2 := groups["type2"]
|
||||||
if type2 != "" {
|
if type2 != "" {
|
||||||
type2 = type2[2 : len(type2)-1]
|
type2 = type2[2 : len(type2)-1]
|
||||||
}
|
}*/
|
||||||
|
|
||||||
return &EnumDecl{
|
return &EnumDecl{
|
||||||
Addr: ParseAddress(groups["address"]),
|
Addr: ParseAddress(groups["address"]),
|
||||||
Pos: NewPositionFromString(groups["position"]),
|
Pos: NewPositionFromString(groups["position"]),
|
||||||
Position2: groups["position2"],
|
//Position2: groups["position2"],
|
||||||
Name: strings.TrimSpace(groups["name"]),
|
Name: strings.TrimSpace(groups["name"]),
|
||||||
Type: removeQuotes(groups["type"]),
|
Type: removeQuotes(groups["type"]),
|
||||||
Type2: type2,
|
//Type2: type2,
|
||||||
ChildNodes: []Node{},
|
ChildNodes: []Node{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ func parseObjCCategoryDecl(line string) *ObjCCategoryDecl {
|
||||||
return &ObjCCategoryDecl{
|
return &ObjCCategoryDecl{
|
||||||
Addr: ParseAddress(groups["address"]),
|
Addr: ParseAddress(groups["address"]),
|
||||||
Pos: NewPositionFromString(groups["position"]),
|
Pos: NewPositionFromString(groups["position"]),
|
||||||
Position2: strings.TrimSpace(groups["position2"]),
|
//Position2: strings.TrimSpace(groups["position2"]),
|
||||||
Name: strings.TrimSpace(groups["name"]),
|
Name: strings.TrimSpace(groups["name"]),
|
||||||
ChildNodes: []Node{},
|
ChildNodes: []Node{},
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,17 +25,10 @@ func parseObjCInterfaceDecl(line string) *ObjCInterfaceDecl {
|
||||||
line,
|
line,
|
||||||
)
|
)
|
||||||
|
|
||||||
/*fmt.Println(line)
|
|
||||||
fmt.Println("prev = ",groups["prev"])
|
|
||||||
fmt.Println("position = ",groups["position"])
|
|
||||||
fmt.Println("position2 = ",groups["position2"])
|
|
||||||
fmt.Println("implicit = ",len(groups["implicit"])>0)
|
|
||||||
fmt.Println("name = ",groups["name"])*/
|
|
||||||
|
|
||||||
return &ObjCInterfaceDecl{
|
return &ObjCInterfaceDecl{
|
||||||
Addr: ParseAddress(groups["address"]),
|
Addr: ParseAddress(groups["address"]),
|
||||||
Pos: NewPositionFromString(groups["position"]),
|
Pos: NewPositionFromString(groups["position"]),
|
||||||
Position2: strings.TrimSpace(groups["position2"]),
|
//Position2: strings.TrimSpace(groups["position2"]),
|
||||||
Name: strings.TrimSpace(groups["name"]),
|
Name: strings.TrimSpace(groups["name"]),
|
||||||
Implicit: len(groups["implicit"])>0,
|
Implicit: len(groups["implicit"])>0,
|
||||||
ChildNodes: []Node{},
|
ChildNodes: []Node{},
|
||||||
|
|
|
@ -42,13 +42,13 @@ func parseObjCMethodDecl(line string) *ObjCMethodDecl {
|
||||||
return &ObjCMethodDecl{
|
return &ObjCMethodDecl{
|
||||||
Addr: ParseAddress(groups["address"]),
|
Addr: ParseAddress(groups["address"]),
|
||||||
Pos: NewPositionFromString(groups["position"]),
|
Pos: NewPositionFromString(groups["position"]),
|
||||||
Position2: strings.TrimSpace(groups["position2"]),
|
//Position2: strings.TrimSpace(groups["position2"]),
|
||||||
Implicit: len(groups["implicit"])>0,
|
Implicit: len(groups["implicit"]) > 0,
|
||||||
ClassMethod: groups["methodtype"] == " +",
|
ClassMethod: groups["methodtype"] == " +",
|
||||||
Name: parts[0],
|
Name: parts[0],
|
||||||
Parameters: params,
|
Parameters: params,
|
||||||
Type: strings.TrimSpace(groups["type"]),
|
Type: strings.TrimSpace(groups["type"]),
|
||||||
Type2: strings.TrimSpace(groups["type2"]),
|
//Type2: strings.TrimSpace(groups["type2"]),
|
||||||
Attr: strings.TrimSpace(groups["attr"]),
|
Attr: strings.TrimSpace(groups["attr"]),
|
||||||
ChildNodes: []Node{},
|
ChildNodes: []Node{},
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,8 +33,8 @@ func parseObjCPropertyDecl(line string) *ObjCPropertyDecl {
|
||||||
Pos: NewPositionFromString(groups["position"]),
|
Pos: NewPositionFromString(groups["position"]),
|
||||||
Position2: strings.TrimSpace(groups["position2"]),
|
Position2: strings.TrimSpace(groups["position2"]),
|
||||||
Name: strings.TrimSpace(groups["name"]),
|
Name: strings.TrimSpace(groups["name"]),
|
||||||
Type: strings.TrimSpace(groups["type"]),
|
Type: groups["type"],
|
||||||
Type2: strings.TrimSpace(groups["type2"]),
|
//Type2: strings.TrimSpace(groups["type2"]),
|
||||||
Attr: strings.TrimSpace(groups["attr"]),
|
Attr: strings.TrimSpace(groups["attr"]),
|
||||||
ChildNodes: []Node{},
|
ChildNodes: []Node{},
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ func parseObjCProtocolDecl(line string) *ObjCProtocolDecl {
|
||||||
return &ObjCProtocolDecl{
|
return &ObjCProtocolDecl{
|
||||||
Addr: ParseAddress(groups["address"]),
|
Addr: ParseAddress(groups["address"]),
|
||||||
Pos: NewPositionFromString(groups["position"]),
|
Pos: NewPositionFromString(groups["position"]),
|
||||||
Position2: strings.TrimSpace(groups["position2"]),
|
//Position2: strings.TrimSpace(groups["position2"]),
|
||||||
Name: strings.TrimSpace(groups["name"]),
|
Name: strings.TrimSpace(groups["name"]),
|
||||||
ChildNodes: []Node{},
|
ChildNodes: []Node{},
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,10 +32,10 @@ func parseObjCTypeParamDecl(line string) *ObjCTypeParamDecl {
|
||||||
line,
|
line,
|
||||||
)
|
)
|
||||||
|
|
||||||
type2 := groups["type2"]
|
/*type2 := groups["type2"]
|
||||||
if type2 != "" {
|
if type2 != "" {
|
||||||
type2 = type2[2 : len(type2)-1]
|
type2 = type2[2 : len(type2)-1]
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if strings.Index(groups["position"], "<invalid sloc>") > -1 {
|
if strings.Index(groups["position"], "<invalid sloc>") > -1 {
|
||||||
groups["position"] = "<invalid sloc>"
|
groups["position"] = "<invalid sloc>"
|
||||||
|
@ -45,10 +45,10 @@ func parseObjCTypeParamDecl(line string) *ObjCTypeParamDecl {
|
||||||
return &ObjCTypeParamDecl{
|
return &ObjCTypeParamDecl{
|
||||||
Addr: ParseAddress(groups["address"]),
|
Addr: ParseAddress(groups["address"]),
|
||||||
Pos: NewPositionFromString(groups["position"]),
|
Pos: NewPositionFromString(groups["position"]),
|
||||||
Position2: strings.TrimSpace(groups["position2"]),
|
//Position2: strings.TrimSpace(groups["position2"]),
|
||||||
Name: strings.TrimSpace(groups["name"]),
|
Name: strings.TrimSpace(groups["name"]),
|
||||||
Type: groups["type"],
|
Type: groups["type"],
|
||||||
Type2: type2,
|
//Type2: type2,
|
||||||
IsReferenced: len(groups["referenced"]) > 0,
|
IsReferenced: len(groups["referenced"]) > 0,
|
||||||
IsCovariant: len(groups["covariant"]) > 0,
|
IsCovariant: len(groups["covariant"]) > 0,
|
||||||
IsBounded : len(groups["bounded"]) > 0,
|
IsBounded : len(groups["bounded"]) > 0,
|
||||||
|
|
|
@ -32,23 +32,23 @@ func parseParmVarDecl(line string) *ParmVarDecl {
|
||||||
line,
|
line,
|
||||||
)
|
)
|
||||||
|
|
||||||
type2 := groups["type2"]
|
/*type2 := groups["type2"]
|
||||||
if type2 != "" {
|
if type2 != "" {
|
||||||
type2 = type2[2 : len(type2)-1]
|
type2 = type2[2 : len(type2)-1]
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if strings.Index(groups["position"], "<invalid sloc>") > -1 {
|
/*if strings.Index(groups["position"], "<invalid sloc>") > -1 {
|
||||||
groups["position"] = "<invalid sloc>"
|
groups["position"] = "<invalid sloc>"
|
||||||
groups["position2"] = "<invalid sloc>"
|
groups["position2"] = "<invalid sloc>"
|
||||||
}
|
}*/
|
||||||
|
|
||||||
return &ParmVarDecl{
|
return &ParmVarDecl{
|
||||||
Addr: ParseAddress(groups["address"]),
|
Addr: ParseAddress(groups["address"]),
|
||||||
Pos: NewPositionFromString(groups["position"]),
|
Pos: NewPositionFromString(groups["position"]),
|
||||||
Position2: strings.TrimSpace(groups["position2"]),
|
//Position2: strings.TrimSpace(groups["position2"]),
|
||||||
Name: strings.TrimSpace(groups["name"]),
|
Name: strings.TrimSpace(groups["name"]),
|
||||||
Type: groups["type"],
|
Type: groups["type"],
|
||||||
Type2: type2,
|
//Type2: type2,
|
||||||
IsUsed: len(groups["used"]) > 0,
|
IsUsed: len(groups["used"]) > 0,
|
||||||
IsReferenced: len(groups["referenced"]) > 0,
|
IsReferenced: len(groups["referenced"]) > 0,
|
||||||
IsRegister: len(groups["register"]) > 0,
|
IsRegister: len(groups["register"]) > 0,
|
||||||
|
|
|
@ -33,6 +33,9 @@ func (p Position) GetSimpleLocation() (loc string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPositionFromString(s string) Position {
|
func NewPositionFromString(s string) Position {
|
||||||
|
if !TrackPositions {
|
||||||
|
return Position{}
|
||||||
|
}
|
||||||
re := util.GetRegex(`<invalid sloc>|<scratch space>|<built-in>`)
|
re := util.GetRegex(`<invalid sloc>|<scratch space>|<built-in>`)
|
||||||
if re.MatchString(s) || s == "" {
|
if re.MatchString(s) || s == "" {
|
||||||
return Position{}
|
return Position{}
|
||||||
|
|
|
@ -25,7 +25,7 @@ func parseUnavailableAttr(line string) *UnavailableAttr {
|
||||||
return &UnavailableAttr{
|
return &UnavailableAttr{
|
||||||
Addr: ParseAddress(groups["address"]),
|
Addr: ParseAddress(groups["address"]),
|
||||||
Pos: NewPositionFromString(groups["position"]),
|
Pos: NewPositionFromString(groups["position"]),
|
||||||
Position2: strings.TrimSpace(groups["position2"]),
|
//Position2: strings.TrimSpace(groups["position2"]),
|
||||||
Content: strings.TrimSpace(groups["content"]),
|
Content: strings.TrimSpace(groups["content"]),
|
||||||
ChildNodes: []Node{},
|
ChildNodes: []Node{},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package ast
|
package ast
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
//"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Unknown is node represents an unknown node.
|
// Unknown is node represents an unknown node.
|
||||||
|
@ -30,7 +30,7 @@ func parseUnknown(name, line string) *Unknown {
|
||||||
Name: name,
|
Name: name,
|
||||||
Addr: ParseAddress(groups["address"]),
|
Addr: ParseAddress(groups["address"]),
|
||||||
Pos: NewPositionFromString(groups["position"]),
|
Pos: NewPositionFromString(groups["position"]),
|
||||||
Position2: strings.TrimSpace(groups["position2"]),
|
//Position2: strings.TrimSpace(groups["position2"]),
|
||||||
Content: groups["content"],
|
Content: groups["content"],
|
||||||
ChildNodes: []Node{},
|
ChildNodes: []Node{},
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,12 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"regexp"
|
"regexp"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"runtime/pprof"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
|
@ -16,8 +18,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var Debug = false
|
var Debug = false
|
||||||
|
var Profile = false
|
||||||
|
|
||||||
type conf struct {
|
type conf struct {
|
||||||
|
Positions bool
|
||||||
Package string
|
Package string
|
||||||
Inputfiles []string
|
Inputfiles []string
|
||||||
Classes []string
|
Classes []string
|
||||||
|
@ -158,9 +162,7 @@ func Start() (err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Preprocess NOT DONE
|
// Generate AST
|
||||||
|
|
||||||
// 3. Generate AST
|
|
||||||
cargs := []string{"-xobjective-c", "-Xclang", "-ast-dump",
|
cargs := []string{"-xobjective-c", "-Xclang", "-ast-dump",
|
||||||
"-fsyntax-only","-fno-color-diagnostics"}
|
"-fsyntax-only","-fno-color-diagnostics"}
|
||||||
cargs = append(cargs,Config.Inputfiles...)
|
cargs = append(cargs,Config.Inputfiles...)
|
||||||
|
@ -185,7 +187,12 @@ func Start() (err error) {
|
||||||
|
|
||||||
// Converting to nodes
|
// Converting to nodes
|
||||||
fmt.Printf("Building nodes\n")
|
fmt.Printf("Building nodes\n")
|
||||||
nodes := convertLinesToNodesParallel(lines)
|
if Config.Positions {
|
||||||
|
ast.TrackPositions = true
|
||||||
|
}
|
||||||
|
//NOTE: converting in parallel is slower on my system
|
||||||
|
//nodes := convertLinesToNodesParallel(lines)
|
||||||
|
nodes := convertLinesToNodes(lines)
|
||||||
|
|
||||||
// build tree
|
// build tree
|
||||||
fmt.Printf("Assembling tree\n")
|
fmt.Printf("Assembling tree\n")
|
||||||
|
@ -231,6 +238,18 @@ func Start() (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
if Profile {
|
||||||
|
f1, err := os.Create("cpuprofile.pprof")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("could not create CPU profile: ", err)
|
||||||
|
}
|
||||||
|
defer f1.Close()
|
||||||
|
if err := pprof.StartCPUProfile(f1); err != nil {
|
||||||
|
log.Fatal("could not start CPU profile: ", err)
|
||||||
|
}
|
||||||
|
defer pprof.StopCPUProfile()
|
||||||
|
}
|
||||||
|
|
||||||
confbytes, err := ioutil.ReadFile("nswrap.yaml")
|
confbytes, err := ioutil.ReadFile("nswrap.yaml")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Cannot open config file nswrap.yaml. %s\n",err)
|
fmt.Printf("Cannot open config file nswrap.yaml. %s\n",err)
|
||||||
|
@ -244,4 +263,15 @@ func main() {
|
||||||
fmt.Printf("Error: %v\n", err)
|
fmt.Printf("Error: %v\n", err)
|
||||||
os.Exit(-1)
|
os.Exit(-1)
|
||||||
}
|
}
|
||||||
|
if Profile {
|
||||||
|
f2, err := os.Create("memprofile.pprof")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("could not create memory profile: ", err)
|
||||||
|
}
|
||||||
|
defer f2.Close()
|
||||||
|
runtime.GC() // get up-to-date statistics
|
||||||
|
if err := pprof.WriteHeapProfile(f2); err != nil {
|
||||||
|
log.Fatal("could not write memory profile: ", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ func app() {
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
//Run our app in an autorelease pool just for fun
|
//Run our app in an autorelease pool just for fun
|
||||||
go ns.Autorelease(app)
|
go ns.Autoreleasepool(app)
|
||||||
select { }
|
select { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,12 @@ func updateState(c *ns.CBCentralManager) {
|
||||||
func discoverPeripheral(c *ns.CBCentralManager, p *ns.CBPeripheral, d *ns.NSDictionary, rssi *ns.NSNumber) {
|
func discoverPeripheral(c *ns.CBCentralManager, p *ns.CBPeripheral, d *ns.NSDictionary, rssi *ns.NSNumber) {
|
||||||
fmt.Printf("Did discover peripheral\n")
|
fmt.Printf("Did discover peripheral\n")
|
||||||
c.StopScan()
|
c.StopScan()
|
||||||
|
if peripheral != nil {
|
||||||
|
peripheral.Release()
|
||||||
|
}
|
||||||
peripheral = p
|
peripheral = p
|
||||||
peripheral.Retain()
|
peripheral.Retain()
|
||||||
c.ConnectPeripheral(p,nil)
|
c.ConnectPeripheral(peripheral,nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func connectPeripheral(c *ns.CBCentralManager, p *ns.CBPeripheral) {
|
func connectPeripheral(c *ns.CBCentralManager, p *ns.CBPeripheral) {
|
||||||
|
@ -106,6 +109,7 @@ func main() {
|
||||||
queue := ns.DispatchQueueCreate(ns.CharWithGoString("st.wow.gitlab.ble"),nil)
|
queue := ns.DispatchQueueCreate(ns.CharWithGoString("st.wow.gitlab.ble"),nil)
|
||||||
|
|
||||||
cd = ns.BleDelegateAlloc()
|
cd = ns.BleDelegateAlloc()
|
||||||
|
|
||||||
cd.CentralManagerDidUpdateStateCallback(updateState)
|
cd.CentralManagerDidUpdateStateCallback(updateState)
|
||||||
cd.CentralManagerDidDiscoverPeripheralCallback(discoverPeripheral)
|
cd.CentralManagerDidDiscoverPeripheralCallback(discoverPeripheral)
|
||||||
cd.CentralManagerDidConnectPeripheralCallback(connectPeripheral)
|
cd.CentralManagerDidConnectPeripheralCallback(connectPeripheral)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
//"fmt"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,26 +16,12 @@ func init() {
|
||||||
reservedwords = regexp.MustCompile("^(void|char|short|int|long|float|double|signed|unsigned|_Bool|_Complex|const|restrict|volatile|struct|union|enum)$")
|
reservedwords = regexp.MustCompile("^(void|char|short|int|long|float|double|signed|unsigned|_Bool|_Complex|const|restrict|volatile|struct|union|enum)$")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Parser is a function that takes the string to be parsed plus an input Node
|
||||||
|
//and returns a new Node and the unparsed remainder string. If the parser fails
|
||||||
|
//to parse anything in the input, it should return a nil Node.
|
||||||
type Parser func(string, *Node) (string, *Node)
|
type Parser func(string, *Node) (string, *Node)
|
||||||
|
|
||||||
// Adders
|
// Adders -- add elements to the Node tree
|
||||||
|
|
||||||
//Child takes a parser and adds its output node (if non-nil) to the tree.
|
|
||||||
//FIXME -- broken?
|
|
||||||
func Child(p Parser) Parser {
|
|
||||||
return func(s string, n *Node) (string, *Node) {
|
|
||||||
dbg("Child(%s %p)\n",n.Kind,n)
|
|
||||||
s2,n2 := p(s,n)
|
|
||||||
if n2 == nil {
|
|
||||||
return s,nil
|
|
||||||
}
|
|
||||||
if n2 != n {
|
|
||||||
dbg("Child(%p): AddChild()\n",p)
|
|
||||||
n.AddChild(n2)
|
|
||||||
}
|
|
||||||
return s2,n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//ChildOf takes a node and adds results of a parser to it as a child
|
//ChildOf takes a node and adds results of a parser to it as a child
|
||||||
func ChildOf(ret *Node, p Parser) Parser {
|
func ChildOf(ret *Node, p Parser) Parser {
|
||||||
|
@ -100,9 +85,10 @@ func NodeNamed(k string, p Parser) Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Combinators
|
// Combinators -- combine one or more Parsers into a new Parser.
|
||||||
|
|
||||||
//Opt optionally runs a Parser, returning the input node if it fails
|
//Opt optionally runs a Parser, returning the input Node (instead of nil)
|
||||||
|
//if it fails
|
||||||
func Opt(p Parser) Parser {
|
func Opt(p Parser) Parser {
|
||||||
return func(s string, n *Node) (string, *Node) {
|
return func(s string, n *Node) (string, *Node) {
|
||||||
s2,n2 := p(s,n)
|
s2,n2 := p(s,n)
|
||||||
|
@ -127,29 +113,6 @@ func OneOf(ps ...Parser) Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Doesn't work? May have side effects that do not get unwound.
|
|
||||||
func Longest(ps ...Parser) Parser {
|
|
||||||
dbg("Longest(%p)\n",ps)
|
|
||||||
return func(s string, n *Node) (string, *Node) {
|
|
||||||
ss := make([]string,len(ps))
|
|
||||||
ns := make([]*Node,len(ps))
|
|
||||||
//An arbitrarily large number so I don't have to import "math"
|
|
||||||
minrem := 10000
|
|
||||||
mini := 0
|
|
||||||
for i,p := range ps {
|
|
||||||
ss[i],ns[i] = p(s,n)
|
|
||||||
if ns[i] != nil && len(ss[i]) < minrem {
|
|
||||||
minrem = len(ss[i])
|
|
||||||
mini = i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if minrem < 10000 {
|
|
||||||
return ss[mini],ns[mini]
|
|
||||||
}
|
|
||||||
return s,nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Seq applies parsers in sequence, adding results as children to the input
|
//Seq applies parsers in sequence, adding results as children to the input
|
||||||
//node. Returns nil and the input string unless the entire sequence succeeds
|
//node. Returns nil and the input string unless the entire sequence succeeds
|
||||||
func Seq(ps ...Parser) Parser {
|
func Seq(ps ...Parser) Parser {
|
||||||
|
@ -172,7 +135,8 @@ func Seq(ps ...Parser) Parser {
|
||||||
return Children(p)
|
return Children(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Like Seq but subsequent children are nested inside their earlier siblings.
|
//Nest is like Seq but subsequent children are nested inside their earlier
|
||||||
|
//siblings.
|
||||||
func Nest(ps ...Parser) Parser {
|
func Nest(ps ...Parser) Parser {
|
||||||
dbg("Nest(%p)\n",ps)
|
dbg("Nest(%p)\n",ps)
|
||||||
p := func(s string, n *Node) (string, *Node) {
|
p := func(s string, n *Node) (string, *Node) {
|
||||||
|
@ -212,32 +176,41 @@ func ZeroOrMore(p Parser) Parser {
|
||||||
return Children(ret)
|
return Children(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//OneOrMore is ZeroOrMore, but fails (returns nil) if the input parser does
|
||||||
|
//not match any elements.
|
||||||
func OneOrMore(p Parser) Parser {
|
func OneOrMore(p Parser) Parser {
|
||||||
return Seq(p,ZeroOrMore(p))
|
return Seq(p,ZeroOrMore(p))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Parenthesized matches the input parser surrounded by literal parenthesis.
|
||||||
func Parenthesized(p Parser) Parser {
|
func Parenthesized(p Parser) Parser {
|
||||||
return Children(Seq(Lit("("),p,Lit(")")))
|
return Children(Seq(Lit("("),p,Lit(")")))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Bracketed matches the input parser surrounded by literal square brackets.
|
||||||
func Bracketed(p Parser) Parser {
|
func Bracketed(p Parser) Parser {
|
||||||
return Seq(Lit("["),p,Lit("]"))
|
return Seq(Lit("["),p,Lit("]"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//AngBracketed matches the input parser surrounded by literal angled brackets.
|
||||||
func AngBracketed(p Parser) Parser {
|
func AngBracketed(p Parser) Parser {
|
||||||
return Children(Seq(Lit("<"),p,Lit(">")))
|
return Children(Seq(Lit("<"),p,Lit(">")))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//CurlyBracketed matches the input parser surrounded by literal curly brackets.
|
||||||
func CurlyBracketed(p Parser) Parser {
|
func CurlyBracketed(p Parser) Parser {
|
||||||
return Children(Seq(Lit("{"),p,Lit("}")))
|
return Children(Seq(Lit("{"),p,Lit("}")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recognizers
|
// Recognizers -- these functions return parsers that match tokens in the input
|
||||||
|
// stream. There is no separate tokenizer.
|
||||||
|
|
||||||
|
//Word matches an element with a word boundary after its end
|
||||||
func Word(f string) Parser {
|
func Word(f string) Parser {
|
||||||
return Lit(f,true)
|
return Lit(f,true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Lit matches a literal string
|
||||||
func Lit(f string, ws ...bool) Parser {
|
func Lit(f string, ws ...bool) Parser {
|
||||||
word := false
|
word := false
|
||||||
if len(ws) > 0 {
|
if len(ws) > 0 {
|
||||||
|
@ -261,6 +234,7 @@ func Lit(f string, ws ...bool) Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Regexp matches a regular expression at the beginning of the input string
|
||||||
func Regexp(f string) Parser {
|
func Regexp(f string) Parser {
|
||||||
f = "^" + f
|
f = "^" + f
|
||||||
r := regexp.MustCompile(f)
|
r := regexp.MustCompile(f)
|
||||||
|
|
|
@ -33,7 +33,6 @@ var TypeParameters map[string]map[string]string
|
||||||
var typedefs map[string]*Type
|
var typedefs map[string]*Type
|
||||||
|
|
||||||
func (t *Type) Typedef() *Type {
|
func (t *Type) Typedef() *Type {
|
||||||
//return typedefs[t.BaseType().CType()]
|
|
||||||
return typedefs[t.CType()]
|
return typedefs[t.CType()]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +77,6 @@ func AddTypedef(n,t string) {
|
||||||
type Type struct {
|
type Type struct {
|
||||||
Node *Node
|
Node *Node
|
||||||
Class string
|
Class string
|
||||||
ctype string
|
|
||||||
Variadic bool
|
Variadic bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +94,7 @@ func clean(n *Node,c string) (*Node,bool) {
|
||||||
}
|
}
|
||||||
ret := NewNode(n.Kind,n.Content)
|
ret := NewNode(n.Kind,n.Content)
|
||||||
ret.Children = n.Children
|
ret.Children = n.Children
|
||||||
//fmt.Printf("clean(%s,%s)\n",n.Ctype(),c)
|
//fmt.Printf("clean(%s,%s)\n",n.CType(),c)
|
||||||
recur := false
|
recur := false
|
||||||
if TypeParameters[c] != nil {
|
if TypeParameters[c] != nil {
|
||||||
for k,v := range TypeParameters[c] {
|
for k,v := range TypeParameters[c] {
|
||||||
|
@ -127,7 +125,7 @@ func NewTypeFromString(t,c string) *Type {
|
||||||
}
|
}
|
||||||
if n2,ok := clean(n, c); ok {
|
if n2,ok := clean(n, c); ok {
|
||||||
//found type parameters, re-parse
|
//found type parameters, re-parse
|
||||||
return NewTypeFromString(n2.Ctype(),c)
|
return NewTypeFromString(n2.CType(),c)
|
||||||
}
|
}
|
||||||
return &Type{
|
return &Type{
|
||||||
Node: n,
|
Node: n,
|
||||||
|
@ -216,24 +214,16 @@ func (t *Type) _CType(attrib bool) string {
|
||||||
//fmt.Println("nil sent to _CType()")
|
//fmt.Println("nil sent to _CType()")
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
//if !attrib && t.ctype != "" { // cache
|
|
||||||
// return t.ctype
|
|
||||||
//}
|
|
||||||
var ct string
|
var ct string
|
||||||
if attrib {
|
if attrib {
|
||||||
ignore := map[string]bool { "GenericList": true }
|
ignore := map[string]bool { "GenericList": true }
|
||||||
ct = t.Node._Ctype(ignore)
|
ct = t.Node._CType(ignore)
|
||||||
} else {
|
} else {
|
||||||
ct = t.Node.CtypeSimplified()
|
ct = t.Node.CTypeSimplified()
|
||||||
}
|
}
|
||||||
ct = r_id.ReplaceAllString(ct,"NSObject*")
|
ct = r_id.ReplaceAllString(ct,"NSObject*")
|
||||||
ct = r_instancename.ReplaceAllString(ct,t.Class)
|
ct = r_instancename.ReplaceAllString(ct,t.Class)
|
||||||
ct = r_instancetype.ReplaceAllString(ct,t.Class + "*")
|
ct = r_instancetype.ReplaceAllString(ct,t.Class + "*")
|
||||||
if attrib {
|
|
||||||
t._CType(false)
|
|
||||||
} else {
|
|
||||||
t.ctype = ct
|
|
||||||
}
|
|
||||||
return ct
|
return ct
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +285,7 @@ func (t *Type) IsFunctionPtr() bool {
|
||||||
if td := t.Typedef(); td != nil {
|
if td := t.Typedef(); td != nil {
|
||||||
return td.IsFunctionPtr()
|
return td.IsFunctionPtr()
|
||||||
}
|
}
|
||||||
for pt := t.PointsTo(); pt != nil; pt = pt.PointsTo() {
|
if pt := t.PointsTo(); pt != nil {
|
||||||
return pt.IsFunction()
|
return pt.IsFunction()
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
@ -326,7 +316,8 @@ func (t *Type) IsPointer() bool {
|
||||||
return t.Node.IsPointer()
|
return t.Node.IsPointer()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Type) CToGo(cval string) string { // cast C value to CGo
|
// cast C value to CGo
|
||||||
|
func (t *Type) CToGo(cval string) string {
|
||||||
if t.IsPointer() {
|
if t.IsPointer() {
|
||||||
cval = "unsafe.Pointer(" + cval + ")"
|
cval = "unsafe.Pointer(" + cval + ")"
|
||||||
}
|
}
|
||||||
|
@ -334,7 +325,7 @@ func (t *Type) CToGo(cval string) string { // cast C value to CGo
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call a C function from Go with a given return type and parameter types
|
// Call a C function from Go with a given return type and parameter types
|
||||||
func GoToC(name string, pnames []string, rtype *Type, ptypes []*Type) string {
|
func GoToC(name string, pnames []string, rtype *Type, ptypes []*Type, fun bool) string {
|
||||||
if rtype == nil {
|
if rtype == nil {
|
||||||
fmt.Println("nil sent to GoToC")
|
fmt.Println("nil sent to GoToC")
|
||||||
return ""
|
return ""
|
||||||
|
@ -367,7 +358,7 @@ func GoToC(name string, pnames []string, rtype *Type, ptypes []*Type) string {
|
||||||
switch {
|
switch {
|
||||||
case pt.Variadic:
|
case pt.Variadic:
|
||||||
p = "unsafe.Pointer(&" + p + ")"
|
p = "unsafe.Pointer(&" + p + ")"
|
||||||
case pt.IsPointer():
|
case pt.IsPointer() && !fun:
|
||||||
p = "unsafe.Pointer(" + pn + ")"
|
p = "unsafe.Pointer(" + pn + ")"
|
||||||
default:
|
default:
|
||||||
p = "(" + pt.CGoType() + ")(" + pn + ")"
|
p = "(" + pt.CGoType() + ")(" + pn + ")"
|
||||||
|
|
|
@ -1,85 +1,6 @@
|
||||||
package types
|
package types
|
||||||
|
|
||||||
/* Parsers for recognizing type names in C/Objective-C
|
// A parser to recognize type names in C/Objective-C
|
||||||
|
|
||||||
type-name:
|
|
||||||
specifier-qualifier-list abstract-declarator<opt>
|
|
||||||
abstract-declarator:
|
|
||||||
pointer
|
|
||||||
pointer<opt> direct-abstract-declarator
|
|
||||||
direct-abstract-declarator:
|
|
||||||
( abstract-declarator )
|
|
||||||
direct-abstract-declarator<opt> [ type-qualifier-list<opt> assignment-expression<opt> ]
|
|
||||||
direct-abstract-declarator<opt> [ static type-qualifier-list<opt> assignment-expression ]
|
|
||||||
direct-abstract-declarator<opt> [ type-qualifier-list static assignment-expression ]
|
|
||||||
direct-abstract-declarator<opt> [ * ]
|
|
||||||
direct-abstract-declarator<opt> ( parameter-type-list<opt> )
|
|
||||||
pointer:
|
|
||||||
* type-qualifier-list<opt>
|
|
||||||
* type-qualifier-list<opt> pointer
|
|
||||||
parameter-type-list:
|
|
||||||
parameter-list
|
|
||||||
parameter-list , ...
|
|
||||||
parameter-list:
|
|
||||||
parameter-declaration
|
|
||||||
parameter-list , parameter-declaration
|
|
||||||
parameter-declaration:
|
|
||||||
declaration-specifiers declarator
|
|
||||||
declaration-specifiers abstract-declarator<opt>
|
|
||||||
type-qualifier-list:
|
|
||||||
type-qualifier
|
|
||||||
type-qualifier-list type-qualifier
|
|
||||||
specifier-qualifier-list:
|
|
||||||
type-specifier specifier-qualifier-list<opt>
|
|
||||||
type-qualifier specifier-qualifier-list<opt>
|
|
||||||
type-specifier:
|
|
||||||
void
|
|
||||||
char
|
|
||||||
short
|
|
||||||
int
|
|
||||||
long
|
|
||||||
float
|
|
||||||
double
|
|
||||||
signed
|
|
||||||
unsigned
|
|
||||||
_Bool
|
|
||||||
_Complex
|
|
||||||
struct-or-union-specifier
|
|
||||||
enum-specifier
|
|
||||||
typedef-name
|
|
||||||
type-qualifier:
|
|
||||||
const
|
|
||||||
restrict
|
|
||||||
volatile
|
|
||||||
struct-or-union-specifier:
|
|
||||||
// DON'T DO struct-or-union identifier<opt> { struct-declaration-list }
|
|
||||||
struct-or-union identifier
|
|
||||||
struct-or-union:
|
|
||||||
struct
|
|
||||||
union
|
|
||||||
struct-declaration-list:
|
|
||||||
struct-declaration
|
|
||||||
struct-declaration-list struct-declaration
|
|
||||||
struct-declaration:
|
|
||||||
specifier-qualifier-list struct-declarator-list ;
|
|
||||||
struct-declarator-list:
|
|
||||||
struct-declarator
|
|
||||||
struct-declarator-list , struct-declarator
|
|
||||||
struct-declarator:
|
|
||||||
declarator
|
|
||||||
declarator<opt>: constant-expression
|
|
||||||
identifier:
|
|
||||||
identifier-non-digit
|
|
||||||
identifier identifier-nondigit
|
|
||||||
identifier digit
|
|
||||||
identifier-nondigit:
|
|
||||||
nondigit
|
|
||||||
universal-character-name
|
|
||||||
nondigit:
|
|
||||||
_ [a-zA-Z]
|
|
||||||
digit:
|
|
||||||
[0-9]
|
|
||||||
*/
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"regexp"
|
"regexp"
|
||||||
|
@ -94,6 +15,7 @@ func init() {
|
||||||
return !instancetype.MatchString(s) && !instancename.MatchString(s)
|
return !instancetype.MatchString(s) && !instancename.MatchString(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//memoize the TypeName function for performance
|
||||||
cache := map[string]*Node{}
|
cache := map[string]*Node{}
|
||||||
TypeName = func(s string, n *Node) (string, *Node) {
|
TypeName = func(s string, n *Node) (string, *Node) {
|
||||||
if n2,ok := cache[s]; ok {
|
if n2,ok := cache[s]; ok {
|
||||||
|
@ -105,6 +27,8 @@ func init() {
|
||||||
}
|
}
|
||||||
return s2,n2
|
return s2,n2
|
||||||
}
|
}
|
||||||
|
//for debug purposes, the following line can be uncommented, which will
|
||||||
|
//memoization memoization
|
||||||
//TypeName = _TypeName
|
//TypeName = _TypeName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +44,6 @@ func AbstractDeclarator(s string, n *Node) (string, *Node) {
|
||||||
Opt(Pointer),
|
Opt(Pointer),
|
||||||
OneOrMore(DirectAbstractDeclarator)),
|
OneOrMore(DirectAbstractDeclarator)),
|
||||||
Pointer,
|
Pointer,
|
||||||
//Id,
|
|
||||||
Block,
|
Block,
|
||||||
)(s,n)
|
)(s,n)
|
||||||
}
|
}
|
||||||
|
@ -227,14 +150,6 @@ func NullableAnnotation(s string, n *Node) (string, *Node) {
|
||||||
))(s,n)
|
))(s,n)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Id(s string, n *Node) (string, *Node) {
|
|
||||||
return Seq(
|
|
||||||
NodeNamed("Id",Lit("id")),
|
|
||||||
Opt(TypeQualifierList),
|
|
||||||
Opt(NullableAnnotation),
|
|
||||||
)(s,n)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Pointer(s string, n *Node) (string, *Node) {
|
func Pointer(s string, n *Node) (string, *Node) {
|
||||||
return Seq(
|
return Seq(
|
||||||
NodeNamed("Pointer",Lit("*")),
|
NodeNamed("Pointer",Lit("*")),
|
||||||
|
@ -280,9 +195,7 @@ func TypeSpecifier(s string, n *Node) (string, *Node) {
|
||||||
Word("unsigned"),
|
Word("unsigned"),
|
||||||
Word("_Bool"),
|
Word("_Bool"),
|
||||||
Word("_Complex"),
|
Word("_Complex"),
|
||||||
//StructOrUnionSpecifier,
|
|
||||||
EnumSpecifier,
|
EnumSpecifier,
|
||||||
//TypedefName,
|
|
||||||
))(s,n)
|
))(s,n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,15 +36,15 @@ func Parse(s string) (*Node, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Evaluate a node to determine if it is a pointer or array
|
//Evaluate a node to determine if it is a pointer or array
|
||||||
func (n *Node) isAbstract(k string) bool {
|
func (n *Node) isIndirect(k string) bool {
|
||||||
if n.stripAbstract(k) == nil {
|
if n.stripIndirect(k) == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
//Strip one level of pointer or array indirection from a node
|
//Strip one level of pointer or array indirection from a node
|
||||||
func (n *Node) stripAbstract(k string) *Node {
|
func (n *Node) stripIndirect(k string) *Node {
|
||||||
if n == nil {
|
if n == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -55,14 +55,14 @@ func (n *Node) stripAbstract(k string) *Node {
|
||||||
ret := NewNode(n.Kind)
|
ret := NewNode(n.Kind)
|
||||||
cs := append([]*Node{},n.Children...)
|
cs := append([]*Node{},n.Children...)
|
||||||
|
|
||||||
dbg("stripAbstract(): i = %d\n",i)
|
dbg("stripIndirect(): i = %d\n",i)
|
||||||
//Scan backwords skipping TypeQualifier and NullableAnnotation tags
|
//Scan backwords skipping TypeQualifier and NullableAnnotation tags
|
||||||
for ;i > 0 &&
|
for ;i > 0 &&
|
||||||
(cs[i].Kind == "TypeQualifier" ||
|
(cs[i].Kind == "TypeQualifier" ||
|
||||||
cs[i].Kind == "NullableAnnotation") ; i-- { }
|
cs[i].Kind == "NullableAnnotation") ; i-- { }
|
||||||
|
|
||||||
if cs[i].Kind == k {
|
if cs[i].Kind == k {
|
||||||
dbg("stripAbstract(): last node is %s\n",k)
|
dbg("stripIndirect(): last node is %s\n",k)
|
||||||
ret.Children = cs[:i]
|
ret.Children = cs[:i]
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ func (n *Node) stripAbstract(k string) *Node {
|
||||||
//pointed to. Otherwise returns nil when called on non-pointer types.
|
//pointed to. Otherwise returns nil when called on non-pointer types.
|
||||||
func (n *Node) PointsTo() *Node {
|
func (n *Node) PointsTo() *Node {
|
||||||
dbg("PointsTo()\n")
|
dbg("PointsTo()\n")
|
||||||
return n.stripAbstract("Pointer")
|
return n.stripIndirect("Pointer")
|
||||||
}
|
}
|
||||||
|
|
||||||
//IsPointer returns true if the node is a pointer
|
//IsPointer returns true if the node is a pointer
|
||||||
|
@ -108,7 +108,7 @@ func (n *Node) IsPointer() bool {
|
||||||
//non-array types.
|
//non-array types.
|
||||||
func (n *Node) ArrayOf() *Node {
|
func (n *Node) ArrayOf() *Node {
|
||||||
dbg("ArrayOf()\n")
|
dbg("ArrayOf()\n")
|
||||||
return n.stripAbstract("Array")
|
return n.stripIndirect("Array")
|
||||||
}
|
}
|
||||||
|
|
||||||
//IsArray returns true if the node is an array
|
//IsArray returns true if the node is an array
|
||||||
|
|
|
@ -13,6 +13,8 @@ type Node struct {
|
||||||
Children []*Node
|
Children []*Node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewNode returns a new node of kind k with an optional content string as its
|
||||||
|
//second parameter.
|
||||||
func NewNode(k string,cs ...string) *Node {
|
func NewNode(k string,cs ...string) *Node {
|
||||||
c := ""
|
c := ""
|
||||||
if len(cs) > 0 {
|
if len(cs) > 0 {
|
||||||
|
@ -56,7 +58,6 @@ func (n *Node) AddChild(c *Node) *Node {
|
||||||
// Skip literals
|
// Skip literals
|
||||||
if c.Kind == "Lit" { return n }
|
if c.Kind == "Lit" { return n }
|
||||||
|
|
||||||
// Do we already have this child? (FIXME: Not needed?)
|
|
||||||
for _,d := range n.Children {
|
for _,d := range n.Children {
|
||||||
if c == d {
|
if c == d {
|
||||||
return n
|
return n
|
||||||
|
@ -85,21 +86,21 @@ func (n *Node) renameTypedefs(a,b string) (ret bool) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) CtypeSimplified() string {
|
func (n *Node) CTypeSimplified() string {
|
||||||
ignore := map[string]bool{
|
ignore := map[string]bool{
|
||||||
"NullableAnnotation": true,
|
"NullableAnnotation": true,
|
||||||
"KindQualifier": true,
|
"KindQualifier": true,
|
||||||
"TypeQualifier": true,
|
"TypeQualifier": true,
|
||||||
"GenericList": true,
|
"GenericList": true,
|
||||||
}
|
}
|
||||||
return n._Ctype(ignore)
|
return n._CType(ignore)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) Ctype() string {
|
func (n *Node) CType() string {
|
||||||
return n._Ctype(map[string]bool{})
|
return n._CType(map[string]bool{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) _Ctype(ignore map[string]bool) string {
|
func (n *Node) _CType(ignore map[string]bool) string {
|
||||||
if n == nil || ignore[n.Kind] {
|
if n == nil || ignore[n.Kind] {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -108,7 +109,7 @@ func (n *Node) _Ctype(ignore map[string]bool) string {
|
||||||
ret := []string{}
|
ret := []string{}
|
||||||
if n == nil { return ret }
|
if n == nil { return ret }
|
||||||
for _,c := range n.Children {
|
for _,c := range n.Children {
|
||||||
if x := c._Ctype(ignore); x != "" {
|
if x := c._CType(ignore); x != "" {
|
||||||
ret = append(ret, x)
|
ret = append(ret, x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
wrap/main.go
10
wrap/main.go
|
@ -659,7 +659,7 @@ func (o *NSAutoreleasePool) Init() *NSAutoreleasePool {
|
||||||
return (*NSAutoreleasePool)(unsafe.Pointer(C.NSAutoreleasePool_init(o.Ptr())))
|
return (*NSAutoreleasePool)(unsafe.Pointer(C.NSAutoreleasePool_init(o.Ptr())))
|
||||||
}
|
}
|
||||||
|
|
||||||
func Autorelease(f func()) {
|
func Autoreleasepool(f func()) {
|
||||||
pool := NSAutoreleasePoolAlloc().Init()
|
pool := NSAutoreleasePoolAlloc().Init()
|
||||||
f()
|
f()
|
||||||
pool.Drain()
|
pool.Drain()
|
||||||
|
@ -777,7 +777,7 @@ func %s%s(%s) %s {
|
||||||
`,vn,w.Vaargs,vn,vn))
|
`,vn,w.Vaargs,vn,vn))
|
||||||
}
|
}
|
||||||
w.goCode.WriteString(` ` +
|
w.goCode.WriteString(` ` +
|
||||||
types.GoToC(cname,ns,m.Type,tps) + "\n}\n")
|
types.GoToC(cname,ns,m.Type,tps,fun) + "\n}\n")
|
||||||
|
|
||||||
cret := ""
|
cret := ""
|
||||||
if !m.isVoid() {
|
if !m.isVoid() {
|
||||||
|
@ -936,7 +936,7 @@ func (w *Wrapper) ProcessDelegate(dname string, ps []string) {
|
||||||
} else {
|
} else {
|
||||||
pm := m.Parameters[0]
|
pm := m.Parameters[0]
|
||||||
w.processType(pm.Type)
|
w.processType(pm.Type)
|
||||||
parms = fmt.Sprintf(":(%s)%s",pm.Type.Node.Ctype(),pm.Vname)
|
parms = fmt.Sprintf(":(%s)%s",pm.Type.Node.CType(),pm.Vname)
|
||||||
vnames[i][1] = pm.Vname
|
vnames[i][1] = pm.Vname
|
||||||
gtypes[i][0] = pm.Type.GoType()
|
gtypes[i][0] = pm.Type.GoType()
|
||||||
if pm.Type.IsPointer() {
|
if pm.Type.IsPointer() {
|
||||||
|
@ -948,7 +948,7 @@ func (w *Wrapper) ProcessDelegate(dname string, ps []string) {
|
||||||
for j := 1; j < len(m.Parameters); j++ {
|
for j := 1; j < len(m.Parameters); j++ {
|
||||||
pm := m.Parameters[j]
|
pm := m.Parameters[j]
|
||||||
w.processType(pm.Type)
|
w.processType(pm.Type)
|
||||||
parms = parms + fmt.Sprintf(" %s:(%s)%s",pm.Pname,pm.Type.Node.Ctype(),pm.Vname)
|
parms = parms + fmt.Sprintf(" %s:(%s)%s",pm.Pname,pm.Type.Node.CType(),pm.Vname)
|
||||||
vnames[i][j+1] = pm.Vname
|
vnames[i][j+1] = pm.Vname
|
||||||
gtypes[i][j] = pm.Type.GoType()
|
gtypes[i][j] = pm.Type.GoType()
|
||||||
var getp string
|
var getp string
|
||||||
|
@ -960,7 +960,7 @@ func (w *Wrapper) ProcessDelegate(dname string, ps []string) {
|
||||||
getypes[i][j+1] = getp
|
getypes[i][j+1] = getp
|
||||||
}
|
}
|
||||||
methprotos[i] = fmt.Sprintf(
|
methprotos[i] = fmt.Sprintf(
|
||||||
`- (%s)%s%s;`,m.Type.Node.Ctype(),m.Name,parms)
|
`- (%s)%s%s;`,m.Type.Node.CType(),m.Name,parms)
|
||||||
if x := m.Type.GoType(); x == "Void" {
|
if x := m.Type.GoType(); x == "Void" {
|
||||||
grtypes[i] = ""
|
grtypes[i] = ""
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user