@@ -38,10 +38,22 @@ static kindDefinition PascalKinds [] = {
3838*/
3939
4040static void createPascalTag (
41- tagEntryInfo * const tag , const vString * const name , const int kind )
41+ tagEntryInfo * const tag , const vString * const name , const int kind ,
42+ const vString * arglist , const vString * vartype )
4243{
4344 if (PascalKinds [kind ].enabled && name != NULL && vStringLength (name ) > 0 )
45+ {
4446 initTagEntry (tag , vStringValue (name ), kind );
47+ if (arglist != NULL && !vStringIsEmpty (arglist ))
48+ {
49+ tag -> extensionFields .signature = vStringValue (arglist );
50+ }
51+ if (vartype && !vStringIsEmpty (vartype ))
52+ {
53+ tag -> extensionFields .typeRef [0 ] = "typename" ;
54+ tag -> extensionFields .typeRef [1 ] = vStringValue (vartype );
55+ }
56+ }
4557 else
4658 /* TODO: Passing NULL as name makes an assertion behind initTagEntry failure */
4759 initTagEntry (tag , NULL , KIND_GHOST_INDEX );
@@ -74,6 +86,64 @@ static bool tail (const char *cp)
7486 return result ;
7587}
7688
89+ static void parseArglist (const char * buf , vString * arglist , vString * vartype )
90+ {
91+ const char * start , * end ;
92+ int level ;
93+
94+ if (NULL == buf || arglist == NULL )
95+ return ;
96+
97+ /* parse argument list which can be missing like in "function ginit:integer;" */
98+ if (NULL != (start = strchr (buf , '(' )))
99+ {
100+ for (level = 1 , end = start + 1 ; level > 0 ; ++ end )
101+ {
102+ if ('\0' == * end )
103+ break ;
104+ else if ('(' == * end )
105+ ++ level ;
106+ else if (')' == * end )
107+ -- level ;
108+ }
109+ }
110+ else /* if no argument list was found, continue looking for a return value */
111+ {
112+ start = NULL ;
113+ end = buf ;
114+ }
115+
116+ /* parse return type if requested by passing a non-NULL vartype argument */
117+ if (NULL != vartype )
118+ {
119+ char * var , * var_start ;
120+
121+ if (NULL != (var = strchr (end , ':' )))
122+ {
123+ var ++ ; /* skip ':' */
124+ while (isspace ((int ) * var ))
125+ ++ var ;
126+
127+ if (starttoken (* var ))
128+ {
129+ var_start = var ;
130+ var ++ ;
131+ while (intoken (* var ))
132+ var ++ ;
133+ if (endtoken (* var ))
134+ {
135+ vStringNCatS (vartype , var_start , var - var_start );
136+ }
137+ }
138+ }
139+ }
140+
141+ if (NULL == start ) /* no argument list */
142+ vStringCatS (arglist , "()" );
143+ else
144+ vStringNCatS (arglist , start , end - start );
145+ }
146+
77147/* Algorithm adapted from from GNU etags.
78148 * Locates tags for procedures & functions. Doesn't do any type- or
79149 * var-definitions. It does look for the keyword "extern" or "forward"
@@ -83,6 +153,8 @@ static bool tail (const char *cp)
83153static void findPascalTags (void )
84154{
85155 vString * name = vStringNew ();
156+ vString * arglist = vStringNew ();
157+ vString * vartype = vStringNew ();
86158 tagEntryInfo tag ;
87159 pascalKind kind = K_FUNCTION ;
88160 /* each of these flags is true iff: */
@@ -205,7 +277,12 @@ static void findPascalTags (void)
205277 for (cp = dbp ; * cp != '\0' && !endtoken (* cp ) ; cp ++ )
206278 continue ;
207279 vStringNCopyS (name , (const char * ) dbp , cp - dbp );
208- createPascalTag (& tag , name , kind );
280+
281+ vStringClear (arglist );
282+ vStringClear (vartype );
283+ parseArglist ((const char * ) cp , arglist , (kind == K_FUNCTION ) ? vartype : NULL );
284+
285+ createPascalTag (& tag , name , kind , arglist , (kind == K_FUNCTION ) ? vartype : NULL );
209286 dbp = cp ; /* set dbp to e-o-token */
210287 get_tagname = false;
211288 found_tag = true;
@@ -246,6 +323,8 @@ static void findPascalTags (void)
246323 }
247324 } /* while not eof */
248325 }
326+ vStringDelete (arglist );
327+ vStringDelete (vartype );
249328 vStringDelete (name );
250329}
251330
0 commit comments