Some AST tweaks and add astfile: config option to read AST from a file

instead of running Clang. Attempt to port to MacOS Mojave.
This commit is contained in:
Greg 2019-06-01 15:10:51 -04:00
parent a7df3a4e71
commit 4f0cdf4d1a
5 changed files with 54 additions and 32 deletions

View File

@ -3,7 +3,7 @@ package ast
import ( import (
"strings" "strings"
"git.wow.st/gmp/nswrap/util" //"git.wow.st/gmp/nswrap/util"
) )
// AllocSizeAttr is a type of attribute that is optionally attached to a variable // AllocSizeAttr is a type of attribute that is optionally attached to a variable
@ -12,8 +12,8 @@ type AllocSizeAttr struct {
Addr Address Addr Address
Pos Position Pos Position
Inherited bool Inherited bool
A int A string
B int B string
ChildNodes []Node ChildNodes []Node
} }
@ -27,8 +27,8 @@ func parseAllocSizeAttr(line string) *AllocSizeAttr {
Addr: ParseAddress(groups["address"]), Addr: ParseAddress(groups["address"]),
Pos: NewPositionFromString(groups["position"]), Pos: NewPositionFromString(groups["position"]),
Inherited: len(groups["inherited"]) > 0, Inherited: len(groups["inherited"]) > 0,
A: util.Atoi(strings.TrimSpace(groups["a"])), A: strings.TrimSpace(groups["a"]),
B: util.Atoi(strings.TrimSpace(groups["b"])), B: strings.TrimSpace(groups["b"]),
ChildNodes: []Node{}, ChildNodes: []Node{},
} }
} }

View File

@ -18,7 +18,8 @@ func parseImplicitCastExpr(line string) *ImplicitCastExpr {
`<(?P<position>.*)> `<(?P<position>.*)>
'(?P<type>.*?)' '(?P<type>.*?)'
(:'(?P<type2>.*?)')? (:'(?P<type2>.*?)')?
<(?P<kind>.*)>`, <(?P<kind>.*)>
( part_of_explicit_cast)?`,
line, line,
) )

View File

@ -19,7 +19,8 @@ func parseUnaryOperator(line string) *UnaryOperator {
(?P<lvalue> lvalue)? (?P<lvalue> lvalue)?
(?P<prefix> prefix)? (?P<prefix> prefix)?
(?P<postfix> postfix)? (?P<postfix> postfix)?
'(?P<operator>.*?)'`, '(?P<operator>.*?)'
( .*)?`,
line, line,
) )

View File

@ -15,6 +15,7 @@ type VarDecl struct {
Type2 string Type2 string
IsExtern bool IsExtern bool
IsUsed bool IsUsed bool
IsRange bool
IsCInit bool IsCInit bool
IsReferenced bool IsReferenced bool
IsStatic bool IsStatic bool
@ -28,6 +29,7 @@ func parseVarDecl(line string) *VarDecl {
(?:parent (?P<parent>0x[0-9a-f]+) )? (?:parent (?P<parent>0x[0-9a-f]+) )?
<(?P<position>.*)>(?P<position2> .+:\d+)? <(?P<position>.*)>(?P<position2> .+:\d+)?
(?P<used> used)? (?P<used> used)?
(?P<range> range)?
(?P<referenced> referenced)? (?P<referenced> referenced)?
(?P<name> \w+)? (?P<name> \w+)?
'(?P<type>.+?)' '(?P<type>.+?)'
@ -36,6 +38,7 @@ func parseVarDecl(line string) *VarDecl {
(?P<static> static)? (?P<static> static)?
(?P<cinit> cinit)? (?P<cinit> cinit)?
(?P<register> register)? (?P<register> register)?
(.*)
`, `,
line, line,
) )
@ -55,6 +58,7 @@ func parseVarDecl(line string) *VarDecl {
Type2: type2, Type2: type2,
IsExtern: len(groups["extern"]) > 0, IsExtern: len(groups["extern"]) > 0,
IsUsed: len(groups["used"]) > 0, IsUsed: len(groups["used"]) > 0,
IsRange: len(groups["range"]) > 0,
IsCInit: len(groups["cinit"]) > 0, IsCInit: len(groups["cinit"]) > 0,
IsReferenced: len(groups["referenced"]) > 0, IsReferenced: len(groups["referenced"]) > 0,
IsStatic: len(groups["static"]) > 0, IsStatic: len(groups["static"]) > 0,

66
main.go
View File

@ -23,6 +23,7 @@ type conf struct {
Positions bool Positions bool
Package string Package string
Inputfiles []string Inputfiles []string
Astfile string
Classes []string Classes []string
Functions []string Functions []string
Enums []string Enums []string
@ -157,35 +158,48 @@ func matches(x string, rs []string) bool {
// Start begins transpiling an input file. // Start begins transpiling an input file.
func Start() (err error) { func Start() (err error) {
for _, in := range Config.Inputfiles { astPP := []byte{}
_, err := os.Stat(in) if Config.Astfile != "" {
fmt.Printf("Reading ast file %s\n",Config.Astfile)
_, err = os.Stat(Config.Astfile)
if err != nil { if err != nil {
return fmt.Errorf("Input file %s is not found", in) return fmt.Errorf("Input AST file %s not found",Config.Astfile)
}
astPP, err = ioutil.ReadFile(Config.Astfile)
if err != nil {
return err
}
} else {
for _, in := range Config.Inputfiles {
_, err = os.Stat(in)
if err != nil {
return fmt.Errorf("Input file %s is not found", in)
}
} }
}
// Generate AST // 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"}
if Config.Arc { if Config.Arc {
cargs = append(cargs,"-fobjc-arc") cargs = append(cargs,"-fobjc-arc")
} }
cargs = append(cargs,Config.Inputfiles...) cargs = append(cargs,Config.Inputfiles...)
fmt.Printf("Generating AST\n") fmt.Printf("Generating AST\n")
astPP, err := exec.Command("clang",cargs...).Output() astPP, err = exec.Command("clang",cargs...).Output()
if err != nil { if err != nil {
// If clang fails it still prints out the AST, so we have to run it // If clang fails it still prints out the AST, so we have to run it
// again to get the real error. // again to get the real error.
//errBody, _ := exec.Command("clang", cargs...).CombinedOutput() //errBody, _ := exec.Command("clang", cargs...).CombinedOutput()
var txt string var txt string
switch x := err.(type) { switch x := err.(type) {
case *exec.ExitError: case *exec.ExitError:
txt = string(x.Stderr) txt = string(x.Stderr)
default: default:
txt = err.Error() txt = err.Error()
}
fmt.Printf("clang failed:\n%s\n", txt)
os.Exit(-1)
} }
fmt.Printf("clang failed:\n%s\n", txt)
os.Exit(-1)
} }
lines := readAST(astPP) lines := readAST(astPP)
@ -271,6 +285,8 @@ func main() {
fmt.Printf("Cannot decode config file nswrap.yaml. %s\n",err) fmt.Printf("Cannot decode config file nswrap.yaml. %s\n",err)
os.Exit(-1) os.Exit(-1)
} }
fmt.Printf("Package = %s\n",Config.Package)
fmt.Printf("Astfile = %s\n",Config.Astfile)
if err := Start(); err != nil { if err := Start(); err != nil {
fmt.Printf("Error: %v\n", err) fmt.Printf("Error: %v\n", err)
os.Exit(-1) os.Exit(-1)