2 * Copyright (c) 2000-2001, Max Ischenko <mfi@ukr.net>.
4 * This source code is released for free distribution under the terms of the
5 * GNU General Public License version 2 or (at your option) any later version.
7 * This module contains functions for generating tags for Lua language.
13 #include "general.h" /* must always come first */
33 LUA_UNKNOWN_REFERENCED
,
36 static roleDefinition LuaUnknownRoles
[] = {
37 { false, "referenced", "referenced somehow" },
40 static kindDefinition LuaKinds
[] = {
41 { true, 'f', "function", "functions" },
43 /* `unknown' is a kind just for making FQ tag for functions. */
44 { false, 'Y', "unknown", "unknown language object",
45 .referenceOnly
= true, ATTACH_ROLES(LuaUnknownRoles
) },
49 * FUNCTION DEFINITIONS
54 * Returns 1 if line looks like a line of Lua code.
56 * TODO: Recognize UNIX bang notation.
57 * (Lua treat first line as a comment if it starts with #!)
60 static bool is_a_code_line (const unsigned char *line
)
63 const unsigned char *p
= line
;
68 else if (p
[0] == '-' && p
[1] == '-')
75 static bool isLuaIdentifier (char c
)
77 return (bool) !(isspace((unsigned char) c
) || c
== '(' || c
== ')'
78 || c
== '=' || c
== '.' || c
== ':' || c
== '{'
82 static void set_scope (int child
, int parent
)
84 if (parent
== CORK_NIL
|| child
== CORK_NIL
)
87 tagEntryInfo
*e
= getEntryInCorkQueue (child
);
91 e
->extensionFields
.scopeIndex
= parent
;
94 static void extract_next_token (const char *begin
, const char *end_sentinel
, vString
*name
)
96 if (begin
== NULL
|| end_sentinel
== NULL
)
99 Assert (begin
<= end_sentinel
);
102 if (begin
== end_sentinel
)
105 /* Trim prefixed white spaces */
106 while (isspace ((unsigned char) *begin
))
110 if (begin
== end_sentinel
)
113 const char *end
= end_sentinel
- 1;
115 /* Trim suffixed white spaces */
116 while (isspace ((unsigned char) *end
))
119 Assert (begin
<= end
);
121 int lastCorkIndx
= CORK_NIL
;
122 for (const char *c
= begin
; c
<= end
; ++c
)
124 if (*c
== '.' || *c
== ':')
126 int r
= makeSimpleRefTag(name
,
127 K_UNKNOWN
, LUA_UNKNOWN_REFERENCED
);
128 set_scope(r
, lastCorkIndx
);
131 /* Do not include module names in function name */
134 else if (isLuaIdentifier (*c
))
135 vStringPut (name
, *c
);
138 /* An unexpected character is found
139 * between "function" and "(" */
145 int d
= makeSimpleTag (name
, K_FUNCTION
);
146 set_scope(d
, lastCorkIndx
);
150 static void extract_prev_token (const char *end
, const char *begin_sentinel
, vString
*name
)
154 if (end
== NULL
|| begin_sentinel
== NULL
)
157 if (! (begin_sentinel
<= end
))
160 while (isspace ((unsigned char) *end
))
163 if (! (begin_sentinel
<= end
))
168 while (begin_sentinel
<= begin
&& isLuaIdentifier (*begin
))
171 int targetCorkIndex
= CORK_NIL
;
174 vStringNCatS (name
, begin
+ 1, end
- begin
);
175 targetCorkIndex
= makeSimpleTag (name
, K_FUNCTION
);
179 if (targetCorkIndex
== CORK_NIL
|| begin_sentinel
== begin
)
182 /* Fill the scope field of the function. */
184 while (begin_sentinel
<= (begin
+ 1))
186 bool on_boundary
= false;
187 if (begin
< begin_sentinel
|| !isLuaIdentifier (*begin
))
191 vStringNCatS (name
, begin
+ 1, end
- begin
);
192 int r
= makeSimpleRefTag (name
,
193 K_UNKNOWN
, LUA_UNKNOWN_REFERENCED
);
194 set_scope (targetCorkIndex
, r
);
198 if (begin_sentinel
<= begin
&& ! (*begin
== ':' || *begin
== '.'))
209 static void findLuaTags (void)
211 vString
*name
= vStringNew ();
212 const unsigned char *line
;
214 while ((line
= readLineFromInputFile ()) != NULL
)
218 if (! is_a_code_line (line
))
221 p
= (const char*) strstr ((const char*) line
, "function");
225 q
= strchr ((const char*) line
, '=');
228 p
= p
+ 8; /* skip the `function' word */
230 /* We expect [ \t(] */
231 if (! (*p
== '(' || isspace ((unsigned char) *p
)))
233 q
= strchr ((const char*) p
, '(');
235 extract_next_token (p
, q
, name
);
237 (*(q
+1) != '=') /* ignore `if type(v) == "function" then ...' */
238 && (q
< p
) /* ignore "function" ~= */
240 p
= (const char*) &line
[0];
242 extract_prev_token (q
- 1, p
, name
);
245 vStringDelete (name
);
248 extern parserDefinition
* LuaParser (void)
250 static const char* const extensions
[] = { "lua", NULL
};
251 parserDefinition
* def
= parserNew ("Lua");
252 def
->kindTable
= LuaKinds
;
253 def
->kindCount
= ARRAY_SIZE (LuaKinds
);
254 def
->extensions
= extensions
;
255 def
->parser
= findLuaTags
;
256 def
->useCork
= CORK_QUEUE
;
257 def
->requestAutomaticFQTag
= true;