@@ -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 {
6977rows := strings .Split (context [constants .CTX_CTAGS_OUTPUT ].(string ),"\n " )
7078
7179rows = removeEmpty (rows )
7280
73- var tags []map [ string ] string
81+ var tags []* CTag
7482for _ ,row := range rows {
7583tags = append (tags ,parseTag (row ))
7684}
7785
7886skipTagsWhere (tags ,tagIsUnknown ,context )
79- skipTagsWithField (tags ,FIELDS_MARKING_UNHANDLED_TAGS ,context )
87+ skipTagsWhere (tags ,tagIsUnhandled ,context )
8088skipTagsWhere (tags ,signatureContainsDefaultArg ,context )
8189addPrototypes (tags )
8290removeDefinedProtypes (tags ,context )
@@ -88,90 +96,90 @@ func (s *CTagsParser) Run(context map[string]interface{}) error {
8896return nil
8997}
9098
91- func addPrototypes (tags []map [ string ] string ) {
99+ func addPrototypes (tags []* CTag ) {
92100for _ ,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
102110if strings .Contains (code ,"{" ) {
103111code = code [:strings .Index (code ,"{" )]
104112}else {
105113code = code [:strings .LastIndex (code ,")" )+ 1 ]
106114}
107- tag [ KIND_PROTOTYPE ] = code + ";"
115+ tag . Prototype = code + ";"
108116return
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 {}) {
121129definedPrototypes := make (map [string ]bool )
122130for _ ,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
128136for _ ,tag := range tags {
129- if definedPrototypes [tag [ KIND_PROTOTYPE ] ] {
137+ if definedPrototypes [tag . Prototype ] {
130138if 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 ) {
139147definedPrototypes := make (map [string ]bool )
140148
141149for _ ,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 {}) {
153161for _ ,tag := range tags {
154- if tag [ FIELD_SKIP ] != TRUE {
162+ if ! tag . SkipMe {
155163skip := skipFunc (tag )
156164if 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 {
170178return 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 )
175183prototype = removeTralingSemicolon (prototype )
176184
177185return strings .Index (code ,prototype )== - 1
@@ -187,41 +195,66 @@ func removeSpacesAndTabs(s string) string {
187195return 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 {}
207221parts := 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
212226parts = parts [2 :]
213227
214228for _ ,part := range parts {
215229if 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
223256if 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
227260return tag