@@ -39,44 +39,52 @@ import (
39
39
"strings"
40
40
)
41
41
42
- const FIELD_KIND = "kind"
43
- const FIELD_LINE = "line"
44
- const FIELD_SIGNATURE = "signature"
45
- const FIELD_RETURNTYPE = "returntype"
46
- const FIELD_CODE = "code"
47
- const FIELD_CLASS = "class"
48
- const FIELD_STRUCT = "struct"
49
- const FIELD_NAMESPACE = "namespace"
50
- const FIELD_FILENAME = "filename"
51
- const FIELD_SKIP = "skipMe"
52
- const FIELD_FUNCTION_NAME = "functionName"
53
-
54
42
const KIND_PROTOTYPE = "prototype"
55
43
const KIND_FUNCTION = "function"
56
- const KIND_PROTOTYPE_MODIFIERS = "prototype_modifiers"
44
+
45
+ //const KIND_PROTOTYPE_MODIFIERS = "prototype_modifiers"
57
46
58
47
const TEMPLATE = "template"
59
48
const STATIC = "static"
60
- const TRUE = "true"
61
49
62
- var FIELDS = map [string ]bool {"kind" : true , "line" : true , "typeref" : true , "signature" : true , "returntype" : true , "class" : true , "struct" : true , "namespace" : true }
63
- var KNOWN_TAG_KINDS = map [string ]bool {"prototype" : true , "function" : true }
64
- var FIELDS_MARKING_UNHANDLED_TAGS = []string {FIELD_CLASS , FIELD_STRUCT , FIELD_NAMESPACE }
50
+ var KNOWN_TAG_KINDS = map [string ]bool {
51
+ "prototype" : true ,
52
+ "function" : true ,
53
+ }
65
54
66
55
type CTagsParser struct {}
67
56
57
+ type CTag struct {
58
+ FunctionName string
59
+ Kind string
60
+ Line int
61
+ Signature string
62
+ Returntype string
63
+ Code string
64
+ Class string
65
+ Struct string
66
+ Namespace string
67
+ Filename string
68
+ Typeref string
69
+ SkipMe bool
70
+
71
+ Prototype string
72
+ Function string
73
+ PrototypeModifiers string
74
+ }
75
+
68
76
func (s * CTagsParser ) Run (context map [string ]interface {}) error {
69
77
rows := strings .Split (context [constants .CTX_CTAGS_OUTPUT ].(string ), "\n " )
70
78
71
79
rows = removeEmpty (rows )
72
80
73
- var tags []map [ string ] string
81
+ var tags []* CTag
74
82
for _ , row := range rows {
75
83
tags = append (tags , parseTag (row ))
76
84
}
77
85
78
86
skipTagsWhere (tags , tagIsUnknown , context )
79
- skipTagsWithField (tags , FIELDS_MARKING_UNHANDLED_TAGS , context )
87
+ skipTagsWhere (tags , tagIsUnhandled , context )
80
88
skipTagsWhere (tags , signatureContainsDefaultArg , context )
81
89
addPrototypes (tags )
82
90
removeDefinedProtypes (tags , context )
@@ -88,90 +96,90 @@ func (s *CTagsParser) Run(context map[string]interface{}) error {
88
96
return nil
89
97
}
90
98
91
- func addPrototypes (tags []map [ string ] string ) {
99
+ func addPrototypes (tags []* CTag ) {
92
100
for _ , tag := range tags {
93
- if tag [ FIELD_SKIP ] != TRUE {
94
- addPrototype ( tag )
101
+ if ! tag . SkipMe {
102
+ tag . AddPrototype ( )
95
103
}
96
104
}
97
105
}
98
106
99
- func addPrototype (tag map [ string ] string ) {
100
- if strings .Index (tag [ FIELD_RETURNTYPE ] , TEMPLATE ) == 0 || strings .Index (tag [ FIELD_CODE ] , TEMPLATE ) == 0 {
101
- code := tag [ FIELD_CODE ]
107
+ func (tag * CTag ) AddPrototype ( ) {
108
+ if strings .Index (tag . Returntype , TEMPLATE ) == 0 || strings .Index (tag . Code , TEMPLATE ) == 0 {
109
+ code := tag . Code
102
110
if strings .Contains (code , "{" ) {
103
111
code = code [:strings .Index (code , "{" )]
104
112
} else {
105
113
code = code [:strings .LastIndex (code , ")" )+ 1 ]
106
114
}
107
- tag [ KIND_PROTOTYPE ] = code + ";"
115
+ tag . Prototype = code + ";"
108
116
return
109
117
}
110
118
111
- tag [ KIND_PROTOTYPE ] = tag [ FIELD_RETURNTYPE ] + " " + tag [ FIELD_FUNCTION_NAME ] + tag [ FIELD_SIGNATURE ] + ";"
119
+ tag . Prototype = tag . Returntype + " " + tag . FunctionName + tag . Signature + ";"
112
120
113
- tag [ KIND_PROTOTYPE_MODIFIERS ] = ""
114
- if strings .Index (tag [ FIELD_CODE ] , STATIC + " " ) != - 1 {
115
- tag [ KIND_PROTOTYPE_MODIFIERS ] = tag [ KIND_PROTOTYPE_MODIFIERS ] + " " + STATIC
121
+ tag . PrototypeModifiers = ""
122
+ if strings .Index (tag . Code , STATIC + " " ) != - 1 {
123
+ tag . PrototypeModifiers = tag . PrototypeModifiers + " " + STATIC
116
124
}
117
- tag [ KIND_PROTOTYPE_MODIFIERS ] = strings .TrimSpace (tag [ KIND_PROTOTYPE_MODIFIERS ] )
125
+ tag . PrototypeModifiers = strings .TrimSpace (tag . PrototypeModifiers )
118
126
}
119
127
120
- func removeDefinedProtypes (tags []map [ string ] string , context map [string ]interface {}) {
128
+ func removeDefinedProtypes (tags []* CTag , context map [string ]interface {}) {
121
129
definedPrototypes := make (map [string ]bool )
122
130
for _ , tag := range tags {
123
- if tag [ FIELD_KIND ] == KIND_PROTOTYPE {
124
- definedPrototypes [tag [ KIND_PROTOTYPE ] ] = true
131
+ if tag . Kind == KIND_PROTOTYPE {
132
+ definedPrototypes [tag . Prototype ] = true
125
133
}
126
134
}
127
135
128
136
for _ , tag := range tags {
129
- if definedPrototypes [tag [ KIND_PROTOTYPE ] ] {
137
+ if definedPrototypes [tag . Prototype ] {
130
138
if utils .DebugLevel (context ) >= 10 {
131
- utils .Logger (context ).Fprintln (os .Stderr , constants .MSG_SKIPPING_TAG_ALREADY_DEFINED , tag [ FIELD_FUNCTION_NAME ] )
139
+ utils .Logger (context ).Fprintln (os .Stderr , constants .MSG_SKIPPING_TAG_ALREADY_DEFINED , tag . FunctionName )
132
140
}
133
- tag [ FIELD_SKIP ] = TRUE
141
+ tag . SkipMe = true
134
142
}
135
143
}
136
144
}
137
145
138
- func removeDuplicate (tags []map [ string ] string ) {
146
+ func removeDuplicate (tags []* CTag ) {
139
147
definedPrototypes := make (map [string ]bool )
140
148
141
149
for _ , tag := range tags {
142
- if ! definedPrototypes [tag [ KIND_PROTOTYPE ] ] {
143
- definedPrototypes [tag [ KIND_PROTOTYPE ] ] = true
150
+ if ! definedPrototypes [tag . Prototype ] {
151
+ definedPrototypes [tag . Prototype ] = true
144
152
} else {
145
- tag [ FIELD_SKIP ] = TRUE
153
+ tag . SkipMe = true
146
154
}
147
155
}
148
156
}
149
157
150
- type skipFuncType func (tag map [ string ] string ) bool
158
+ type skipFuncType func (tag * CTag ) bool
151
159
152
- func skipTagsWhere (tags []map [ string ] string , skipFunc skipFuncType , context map [string ]interface {}) {
160
+ func skipTagsWhere (tags []* CTag , skipFunc skipFuncType , context map [string ]interface {}) {
153
161
for _ , tag := range tags {
154
- if tag [ FIELD_SKIP ] != TRUE {
162
+ if ! tag . SkipMe {
155
163
skip := skipFunc (tag )
156
164
if skip && utils .DebugLevel (context ) >= 10 {
157
- utils .Logger (context ).Fprintln (os .Stderr , constants .MSG_SKIPPING_TAG_WITH_REASON , tag [ FIELD_FUNCTION_NAME ] , runtime .FuncForPC (reflect .ValueOf (skipFunc ).Pointer ()).Name ())
165
+ utils .Logger (context ).Fprintln (os .Stderr , constants .MSG_SKIPPING_TAG_WITH_REASON , tag . FunctionName , runtime .FuncForPC (reflect .ValueOf (skipFunc ).Pointer ()).Name ())
158
166
}
159
- tag [ FIELD_SKIP ] = strconv . FormatBool ( skip )
167
+ tag . SkipMe = skip
160
168
}
161
169
}
162
170
}
163
171
164
- func signatureContainsDefaultArg (tag map [ string ] string ) bool {
165
- return strings .Contains (tag [ FIELD_SIGNATURE ] , "=" )
172
+ func signatureContainsDefaultArg (tag * CTag ) bool {
173
+ return strings .Contains (tag . Signature , "=" )
166
174
}
167
175
168
- func prototypeAndCodeDontMatch (tag map [ string ] string ) bool {
169
- if tag [ FIELD_SKIP ] == TRUE {
176
+ func prototypeAndCodeDontMatch (tag * CTag ) bool {
177
+ if tag . SkipMe {
170
178
return true
171
179
}
172
180
173
- code := removeSpacesAndTabs (tag [ FIELD_CODE ] )
174
- prototype := removeSpacesAndTabs (tag [ KIND_PROTOTYPE ] )
181
+ code := removeSpacesAndTabs (tag . Code )
182
+ prototype := removeSpacesAndTabs (tag . Prototype )
175
183
prototype = removeTralingSemicolon (prototype )
176
184
177
185
return strings .Index (code , prototype ) == - 1
@@ -187,41 +195,66 @@ func removeSpacesAndTabs(s string) string {
187
195
return s
188
196
}
189
197
190
- func skipTagsWithField (tags []map [string ]string , fields []string , context map [string ]interface {}) {
191
- for _ , tag := range tags {
192
- if field , skip := utils .TagHasAtLeastOneField (tag , fields ); skip {
193
- if utils .DebugLevel (context ) >= 10 {
194
- utils .Logger (context ).Fprintln (os .Stderr , constants .MSG_SKIPPING_TAG_BECAUSE_HAS_FIELD , field )
195
- }
196
- tag [FIELD_SKIP ] = TRUE
197
- }
198
+ func tagIsUnhandled (tag * CTag ) bool {
199
+ return ! tag .IsHandled ()
200
+ }
201
+
202
+ func (tag * CTag ) IsHandled () bool {
203
+ if tag .Class != "" {
204
+ return false
205
+ }
206
+ if tag .Struct != "" {
207
+ return false
208
+ }
209
+ if tag .Namespace != "" {
210
+ return false
198
211
}
212
+ return true
199
213
}
200
214
201
- func tagIsUnknown (tag map [ string ] string ) bool {
202
- return ! KNOWN_TAG_KINDS [tag [ FIELD_KIND ] ]
215
+ func tagIsUnknown (tag * CTag ) bool {
216
+ return ! KNOWN_TAG_KINDS [tag . Kind ]
203
217
}
204
218
205
- func parseTag (row string ) map [ string ] string {
206
- tag := make ( map [ string ] string )
219
+ func parseTag (row string ) * CTag {
220
+ tag := & CTag {}
207
221
parts := strings .Split (row , "\t " )
208
222
209
- tag [ FIELD_FUNCTION_NAME ] = parts [0 ]
210
- tag [ FIELD_FILENAME ] = parts [1 ]
223
+ tag . FunctionName = parts [0 ]
224
+ tag . Filename = parts [1 ]
211
225
212
226
parts = parts [2 :]
213
227
214
228
for _ , part := range parts {
215
229
if strings .Contains (part , ":" ) {
216
- field := part [:strings .Index (part , ":" )]
217
- if FIELDS [field ] {
218
- tag [field ] = strings .TrimSpace (part [strings .Index (part , ":" )+ 1 :])
230
+ colon := strings .Index (part , ":" )
231
+ field := part [:colon ]
232
+ value := strings .TrimSpace (part [colon + 1 :])
233
+ switch field {
234
+ case "kind" :
235
+ tag .Kind = value
236
+ case "line" :
237
+ val , _ := strconv .Atoi (value )
238
+ // TODO: Check err from strconv.Atoi
239
+ tag .Line = val
240
+ case "typeref" :
241
+ tag .Typeref = value
242
+ case "signature" :
243
+ tag .Signature = value
244
+ case "returntype" :
245
+ tag .Returntype = value
246
+ case "class" :
247
+ tag .Class = value
248
+ case "struct" :
249
+ tag .Struct = value
250
+ case "namespace" :
251
+ tag .Namespace = value
219
252
}
220
253
}
221
254
}
222
255
223
256
if strings .Contains (row , "/^" ) && strings .Contains (row , "$/;" ) {
224
- tag [ FIELD_CODE ] = row [strings .Index (row , "/^" )+ 2 : strings .Index (row , "$/;" )]
257
+ tag . Code = row [strings .Index (row , "/^" )+ 2 : strings .Index (row , "$/;" )]
225
258
}
226
259
227
260
return tag
0 commit comments