@@ -8,16 +8,20 @@ import (
88 "os/exec"
99 "regexp"
1010 "strings"
11+ "sync"
1112)
1213
1314func removeComments (line string ) string {
1415 for {
1516 start := strings .Index (line , "/*" )
16- end := strings .Index (line , "*/" )
17- if start == - 1 || end == - 1 || end < start {
17+ if start == - 1 {
1818 break
1919 }
20- line = line [:start ] + line [end + 2 :]
20+ end := strings .Index (line [start + 2 :], "*/" )
21+ if end == - 1 {
22+ break
23+ }
24+ line = line [:start ] + line [start + end + 4 :]
2125 }
2226 trailingCommentIndex := strings .Index (line , "//" )
2327 if trailingCommentIndex != - 1 {
@@ -38,8 +42,8 @@ func ParseCEnum(r io.Reader, name string, min int) (map[int]string, error) {
3842 nLine := 0
3943 for scanner .Scan () {
4044 nLine ++
41- line := removeComments ( scanner .Text () )
42- if startRegex .MatchString (line ) {
45+ line := scanner .Text ()
46+ if strings . Contains ( line , "enum" ) && startRegex .MatchString (removeComments ( line ) ) {
4347 for scanner .Scan () {
4448 nLine ++
4549 line := removeComments (scanner .Text ())
@@ -81,29 +85,55 @@ func ParseCEnum(r io.Reader, name string, min int) (map[int]string, error) {
8185 return enumMap , nil
8286}
8387
88+ // Cache keyed by: version:file:enum
89+ var enumCache = make (map [string ]map [int ]string )
90+ var lock = sync.RWMutex {}
91+
8492// Read an enum from a header file after prepreprocessing
8593func FetchEnumWithMin (srcDir , ovlName , enumName string , min int ) (map [int ]string , error ) {
86- header := fmt .Sprintf ("%s/%s.h" , srcDir , ovlName )
87- cpp , err := exec .LookPath ("cpp" )
88- cmd := exec .Command (cpp ,
89- fmt .Sprintf ("-DVERSION=%s" ),
90- "-lang-c" ,
91- "-Iinclude" ,
92- "-Iinclude/psxsdk" ,
93- "-fno-builtin" ,
94- "-undef" ,
95- "-P" ,
96- header )
97- o , err := cmd .Output ()
94+ version := GetVersion ()
95+ header := fmt .Sprintf ("%s/%s.h" , srcDir , ovlName )
96+ cacheKey := fmt .Sprintf ("%s:%s:%s" , version , header , enumName )
97+
98+ lock .RLock ()
99+ parsed , ok := enumCache [cacheKey ]
100+ lock .RUnlock ()
101+ if ok {
102+ return parsed , nil
103+ }
104+
105+ cpp , err := exec .LookPath ("cpp" )
106+ if err != nil {
107+ return nil , fmt .Errorf ("failed to find `cpp': %w" , err )
108+ }
109+
110+ cmd := exec .Command (cpp ,
111+ fmt .Sprintf ("-DVERSION=%s" , GetVersion ()),
112+ "-lang-c" ,
113+ "-Iinclude" ,
114+ "-Iinclude/psxsdk" ,
115+ "-fno-builtin" ,
116+ "-undef" ,
117+ "-P" ,
118+ header )
119+ o , err := cmd .Output ()
98120
99121 if err != nil {
100122 return nil , fmt .Errorf ("failed preprocess header: %s %s: %w" , cmd .Path , cmd .Args , err )
101123 }
102- r := strings .NewReader (string (o ))
103- return ParseCEnum (r , enumName , min )
104- }
105124
125+ r := strings .NewReader (string (o ))
126+ parsed , err = ParseCEnum (r , enumName , min )
127+
128+ if err == nil {
129+ lock .Lock ()
130+ enumCache [cacheKey ] = parsed
131+ lock .Unlock ()
132+ }
133+
134+ return parsed , err
135+ }
106136
107137func FetchEnum (srcDir , ovlName , enumName string ) (map [int ]string , error ) {
108- return FetchEnumWithMin (srcDir , ovlName , enumName , 0 )
138+ return FetchEnumWithMin (srcDir , ovlName , enumName , 0 )
109139}
0 commit comments