@@ -39,44 +39,52 @@ import (
3939 "strings"
4040)
4141
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-
5442const KIND_PROTOTYPE = "prototype"
5543const KIND_FUNCTION = "function"
56- const KIND_PROTOTYPE_MODIFIERS = "prototype_modifiers"
44+
45+ //const KIND_PROTOTYPE_MODIFIERS = "prototype_modifiers"
5746
5847const TEMPLATE = "template"
5948const STATIC = "static"
60- const TRUE = "true"
6149
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+ }
6554
6655type CTagsParser struct {}
6756
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+
6876func (s * CTagsParser ) Run (context map [string ]interface {}) error {
6977 rows := strings .Split (context [constants .CTX_CTAGS_OUTPUT ].(string ), "\n " )
7078
7179 rows = removeEmpty (rows )
7280
73- var tags []map [ string ] string
81+ var tags []* CTag
7482 for _ , row := range rows {
7583 tags = append (tags , parseTag (row ))
7684 }
7785
7886 skipTagsWhere (tags , tagIsUnknown , context )
79- skipTagsWithField (tags , FIELDS_MARKING_UNHANDLED_TAGS , context )
87+ skipTagsWhere (tags , tagIsUnhandled , context )
8088 skipTagsWhere (tags , signatureContainsDefaultArg , context )
8189 addPrototypes (tags )
8290 removeDefinedProtypes (tags , context )
@@ -88,90 +96,90 @@ func (s *CTagsParser) Run(context map[string]interface{}) error {
8896 return nil
8997}
9098
91- func addPrototypes (tags []map [ string ] string ) {
99+ func addPrototypes (tags []* CTag ) {
92100 for _ , tag := range tags {
93- if tag [ FIELD_SKIP ] != TRUE {
94- addPrototype ( tag )
101+ if ! tag . SkipMe {
102+ tag . AddPrototype ( )
95103 }
96104 }
97105}
98106
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
102110 if strings .Contains (code , "{" ) {
103111 code = code [:strings .Index (code , "{" )]
104112 } else {
105113 code = code [:strings .LastIndex (code , ")" )+ 1 ]
106114 }
107- tag [ KIND_PROTOTYPE ] = code + ";"
115+ tag . Prototype = code + ";"
108116 return
109117 }
110118
111- tag [ KIND_PROTOTYPE ] = tag [ FIELD_RETURNTYPE ] + " " + tag [ FIELD_FUNCTION_NAME ] + tag [ FIELD_SIGNATURE ] + ";"
119+ tag . Prototype = tag . Returntype + " " + tag . FunctionName + tag . Signature + ";"
112120
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
116124 }
117- tag [ KIND_PROTOTYPE_MODIFIERS ] = strings .TrimSpace (tag [ KIND_PROTOTYPE_MODIFIERS ] )
125+ tag . PrototypeModifiers = strings .TrimSpace (tag . PrototypeModifiers )
118126}
119127
120- func removeDefinedProtypes (tags []map [ string ] string , context map [string ]interface {}) {
128+ func removeDefinedProtypes (tags []* CTag , context map [string ]interface {}) {
121129 definedPrototypes := make (map [string ]bool )
122130 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
125133 }
126134 }
127135
128136 for _ , tag := range tags {
129- if definedPrototypes [tag [ KIND_PROTOTYPE ] ] {
137+ if definedPrototypes [tag . Prototype ] {
130138 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 )
132140 }
133- tag [ FIELD_SKIP ] = TRUE
141+ tag . SkipMe = true
134142 }
135143 }
136144}
137145
138- func removeDuplicate (tags []map [ string ] string ) {
146+ func removeDuplicate (tags []* CTag ) {
139147 definedPrototypes := make (map [string ]bool )
140148
141149 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
144152 } else {
145- tag [ FIELD_SKIP ] = TRUE
153+ tag . SkipMe = true
146154 }
147155 }
148156}
149157
150- type skipFuncType func (tag map [ string ] string ) bool
158+ type skipFuncType func (tag * CTag ) bool
151159
152- func skipTagsWhere (tags []map [ string ] string , skipFunc skipFuncType , context map [string ]interface {}) {
160+ func skipTagsWhere (tags []* CTag , skipFunc skipFuncType , context map [string ]interface {}) {
153161 for _ , tag := range tags {
154- if tag [ FIELD_SKIP ] != TRUE {
162+ if ! tag . SkipMe {
155163 skip := skipFunc (tag )
156164 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 ())
158166 }
159- tag [ FIELD_SKIP ] = strconv . FormatBool ( skip )
167+ tag . SkipMe = skip
160168 }
161169 }
162170}
163171
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 , "=" )
166174}
167175
168- func prototypeAndCodeDontMatch (tag map [ string ] string ) bool {
169- if tag [ FIELD_SKIP ] == TRUE {
176+ func prototypeAndCodeDontMatch (tag * CTag ) bool {
177+ if tag . SkipMe {
170178 return true
171179 }
172180
173- code := removeSpacesAndTabs (tag [ FIELD_CODE ] )
174- prototype := removeSpacesAndTabs (tag [ KIND_PROTOTYPE ] )
181+ code := removeSpacesAndTabs (tag . Code )
182+ prototype := removeSpacesAndTabs (tag . Prototype )
175183 prototype = removeTralingSemicolon (prototype )
176184
177185 return strings .Index (code , prototype ) == - 1
@@ -187,41 +195,66 @@ func removeSpacesAndTabs(s string) string {
187195 return s
188196}
189197
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
198211 }
212+ return true
199213}
200214
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 ]
203217}
204218
205- func parseTag (row string ) map [ string ] string {
206- tag := make ( map [ string ] string )
219+ func parseTag (row string ) * CTag {
220+ tag := & CTag {}
207221 parts := strings .Split (row , "\t " )
208222
209- tag [ FIELD_FUNCTION_NAME ] = parts [0 ]
210- tag [ FIELD_FILENAME ] = parts [1 ]
223+ tag . FunctionName = parts [0 ]
224+ tag . Filename = parts [1 ]
211225
212226 parts = parts [2 :]
213227
214228 for _ , part := range parts {
215229 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
219252 }
220253 }
221254 }
222255
223256 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 , "$/;" )]
225258 }
226259
227260 return tag
0 commit comments