ctags.rb 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +2 -0
- data/Rakefile +23 -0
- data/ctags.rb.gemspec +23 -0
- data/ext/.gitignore +3 -0
- data/ext/extconf.rb +15 -0
- data/ext/vendor/exuberant-ctags/.gitignore +6 -0
- data/ext/vendor/exuberant-ctags/.indent.pro +31 -0
- data/ext/vendor/exuberant-ctags/COPYING +340 -0
- data/ext/vendor/exuberant-ctags/EXTENDING.html +386 -0
- data/ext/vendor/exuberant-ctags/FAQ +371 -0
- data/ext/vendor/exuberant-ctags/INSTALL +215 -0
- data/ext/vendor/exuberant-ctags/INSTALL.oth +73 -0
- data/ext/vendor/exuberant-ctags/MAINTAINERS +88 -0
- data/ext/vendor/exuberant-ctags/Makefile.in +222 -0
- data/ext/vendor/exuberant-ctags/NEWS +871 -0
- data/ext/vendor/exuberant-ctags/README +73 -0
- data/ext/vendor/exuberant-ctags/ant.c +42 -0
- data/ext/vendor/exuberant-ctags/argproc.c +505 -0
- data/ext/vendor/exuberant-ctags/args.c +274 -0
- data/ext/vendor/exuberant-ctags/args.h +63 -0
- data/ext/vendor/exuberant-ctags/asm.c +387 -0
- data/ext/vendor/exuberant-ctags/asp.c +328 -0
- data/ext/vendor/exuberant-ctags/awk.c +81 -0
- data/ext/vendor/exuberant-ctags/basic.c +203 -0
- data/ext/vendor/exuberant-ctags/beta.c +321 -0
- data/ext/vendor/exuberant-ctags/c.c +2932 -0
- data/ext/vendor/exuberant-ctags/cobol.c +50 -0
- data/ext/vendor/exuberant-ctags/config.h.in +277 -0
- data/ext/vendor/exuberant-ctags/configure +7704 -0
- data/ext/vendor/exuberant-ctags/configure.ac +532 -0
- data/ext/vendor/exuberant-ctags/ctags.1 +1186 -0
- data/ext/vendor/exuberant-ctags/ctags.h +28 -0
- data/ext/vendor/exuberant-ctags/ctags.html +2087 -0
- data/ext/vendor/exuberant-ctags/ctags.spec +40 -0
- data/ext/vendor/exuberant-ctags/debug.c +113 -0
- data/ext/vendor/exuberant-ctags/debug.h +70 -0
- data/ext/vendor/exuberant-ctags/descrip.mms +68 -0
- data/ext/vendor/exuberant-ctags/dosbatch.c +42 -0
- data/ext/vendor/exuberant-ctags/e_amiga.h +24 -0
- data/ext/vendor/exuberant-ctags/e_djgpp.h +47 -0
- data/ext/vendor/exuberant-ctags/e_mac.h +143 -0
- data/ext/vendor/exuberant-ctags/e_msoft.h +76 -0
- data/ext/vendor/exuberant-ctags/e_os2.h +37 -0
- data/ext/vendor/exuberant-ctags/e_qdos.h +34 -0
- data/ext/vendor/exuberant-ctags/e_riscos.h +58 -0
- data/ext/vendor/exuberant-ctags/e_vms.h +31 -0
- data/ext/vendor/exuberant-ctags/eiffel.c +1352 -0
- data/ext/vendor/exuberant-ctags/entry.c +847 -0
- data/ext/vendor/exuberant-ctags/entry.h +103 -0
- data/ext/vendor/exuberant-ctags/erlang.c +189 -0
- data/ext/vendor/exuberant-ctags/flex.c +2243 -0
- data/ext/vendor/exuberant-ctags/fortran.c +2197 -0
- data/ext/vendor/exuberant-ctags/general.h +127 -0
- data/ext/vendor/exuberant-ctags/get.c +669 -0
- data/ext/vendor/exuberant-ctags/get.h +50 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/all-wcprops +47 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/entries +112 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/README.txt.svn-base +5 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regcomp.c.svn-base +3818 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex.c.svn-base +74 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex.h.svn-base +575 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex_internal.c.svn-base +1713 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex_internal.h.svn-base +773 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regexec.c.svn-base +4338 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/README.txt +5 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/regcomp.c +3818 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/regex.c +74 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/regex.h +575 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/regex_internal.c +1713 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/regex_internal.h +773 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/regexec.c +4338 -0
- data/ext/vendor/exuberant-ctags/html.c +49 -0
- data/ext/vendor/exuberant-ctags/jscript.c +1572 -0
- data/ext/vendor/exuberant-ctags/keyword.c +258 -0
- data/ext/vendor/exuberant-ctags/keyword.h +34 -0
- data/ext/vendor/exuberant-ctags/lisp.c +139 -0
- data/ext/vendor/exuberant-ctags/lregex.c +704 -0
- data/ext/vendor/exuberant-ctags/lua.c +133 -0
- data/ext/vendor/exuberant-ctags/mac.c +273 -0
- data/ext/vendor/exuberant-ctags/magic.diff +21 -0
- data/ext/vendor/exuberant-ctags/main.c +584 -0
- data/ext/vendor/exuberant-ctags/main.h +32 -0
- data/ext/vendor/exuberant-ctags/maintainer.mak +476 -0
- data/ext/vendor/exuberant-ctags/make.c +217 -0
- data/ext/vendor/exuberant-ctags/matlab.c +44 -0
- data/ext/vendor/exuberant-ctags/mk_bc3.mak +46 -0
- data/ext/vendor/exuberant-ctags/mk_bc5.mak +49 -0
- data/ext/vendor/exuberant-ctags/mk_djg.mak +18 -0
- data/ext/vendor/exuberant-ctags/mk_manx.mak +65 -0
- data/ext/vendor/exuberant-ctags/mk_mingw.mak +31 -0
- data/ext/vendor/exuberant-ctags/mk_mpw.mak +130 -0
- data/ext/vendor/exuberant-ctags/mk_mvc.mak +40 -0
- data/ext/vendor/exuberant-ctags/mk_os2.mak +104 -0
- data/ext/vendor/exuberant-ctags/mk_qdos.mak +100 -0
- data/ext/vendor/exuberant-ctags/mk_sas.mak +63 -0
- data/ext/vendor/exuberant-ctags/mkinstalldirs +40 -0
- data/ext/vendor/exuberant-ctags/ocaml.c +1842 -0
- data/ext/vendor/exuberant-ctags/options.c +1842 -0
- data/ext/vendor/exuberant-ctags/options.h +155 -0
- data/ext/vendor/exuberant-ctags/parse.c +677 -0
- data/ext/vendor/exuberant-ctags/parse.h +129 -0
- data/ext/vendor/exuberant-ctags/parsers.h +63 -0
- data/ext/vendor/exuberant-ctags/pascal.c +267 -0
- data/ext/vendor/exuberant-ctags/perl.c +382 -0
- data/ext/vendor/exuberant-ctags/php.c +237 -0
- data/ext/vendor/exuberant-ctags/python.c +771 -0
- data/ext/vendor/exuberant-ctags/qdos.c +106 -0
- data/ext/vendor/exuberant-ctags/read.c +569 -0
- data/ext/vendor/exuberant-ctags/read.h +116 -0
- data/ext/vendor/exuberant-ctags/readtags.c +959 -0
- data/ext/vendor/exuberant-ctags/readtags.h +252 -0
- data/ext/vendor/exuberant-ctags/rexx.c +39 -0
- data/ext/vendor/exuberant-ctags/routines.c +891 -0
- data/ext/vendor/exuberant-ctags/routines.h +134 -0
- data/ext/vendor/exuberant-ctags/ruby.c +408 -0
- data/ext/vendor/exuberant-ctags/scheme.c +111 -0
- data/ext/vendor/exuberant-ctags/sh.c +115 -0
- data/ext/vendor/exuberant-ctags/slang.c +41 -0
- data/ext/vendor/exuberant-ctags/sml.c +212 -0
- data/ext/vendor/exuberant-ctags/sort.c +230 -0
- data/ext/vendor/exuberant-ctags/sort.h +32 -0
- data/ext/vendor/exuberant-ctags/source.mak +122 -0
- data/ext/vendor/exuberant-ctags/sql.c +2112 -0
- data/ext/vendor/exuberant-ctags/strlist.c +281 -0
- data/ext/vendor/exuberant-ctags/strlist.h +54 -0
- data/ext/vendor/exuberant-ctags/tcl.c +116 -0
- data/ext/vendor/exuberant-ctags/tex.c +524 -0
- data/ext/vendor/exuberant-ctags/verilog.c +340 -0
- data/ext/vendor/exuberant-ctags/vhdl.c +835 -0
- data/ext/vendor/exuberant-ctags/vim.c +636 -0
- data/ext/vendor/exuberant-ctags/vstring.c +232 -0
- data/ext/vendor/exuberant-ctags/vstring.h +85 -0
- data/ext/vendor/exuberant-ctags/yacc.c +40 -0
- data/lib/ctags/exuberant.rb +45 -0
- data/lib/ctags/version.rb +3 -0
- data/lib/ctags.rb +6 -0
- data/test/test_ctags.rb +24 -0
- metadata +233 -0
@@ -0,0 +1,382 @@
|
|
1
|
+
/*
|
2
|
+
* $Id: perl.c 601 2007-08-02 04:45:16Z perlguy0 $
|
3
|
+
*
|
4
|
+
* Copyright (c) 2000-2003, Darren Hiebert
|
5
|
+
*
|
6
|
+
* This source code is released for free distribution under the terms of the
|
7
|
+
* GNU General Public License.
|
8
|
+
*
|
9
|
+
* This module contains functions for generating tags for PERL language
|
10
|
+
* files.
|
11
|
+
*/
|
12
|
+
|
13
|
+
/*
|
14
|
+
* INCLUDE FILES
|
15
|
+
*/
|
16
|
+
#include "general.h" /* must always come first */
|
17
|
+
|
18
|
+
#include <string.h>
|
19
|
+
|
20
|
+
#include "entry.h"
|
21
|
+
#include "options.h"
|
22
|
+
#include "read.h"
|
23
|
+
#include "routines.h"
|
24
|
+
#include "vstring.h"
|
25
|
+
|
26
|
+
#define TRACE_PERL_C 0
|
27
|
+
#define TRACE if (TRACE_PERL_C) printf("perl.c:%d: ", __LINE__), printf
|
28
|
+
|
29
|
+
/*
|
30
|
+
* DATA DEFINITIONS
|
31
|
+
*/
|
32
|
+
typedef enum {
|
33
|
+
K_NONE = -1,
|
34
|
+
K_CONSTANT,
|
35
|
+
K_FORMAT,
|
36
|
+
K_LABEL,
|
37
|
+
K_PACKAGE,
|
38
|
+
K_SUBROUTINE,
|
39
|
+
K_SUBROUTINE_DECLARATION
|
40
|
+
} perlKind;
|
41
|
+
|
42
|
+
static kindOption PerlKinds [] = {
|
43
|
+
{ TRUE, 'c', "constant", "constants" },
|
44
|
+
{ TRUE, 'f', "format", "formats" },
|
45
|
+
{ TRUE, 'l', "label", "labels" },
|
46
|
+
{ TRUE, 'p', "package", "packages" },
|
47
|
+
{ TRUE, 's', "subroutine", "subroutines" },
|
48
|
+
{ FALSE, 'd', "subroutine declaration", "subroutine declarations" },
|
49
|
+
};
|
50
|
+
|
51
|
+
/*
|
52
|
+
* FUNCTION DEFINITIONS
|
53
|
+
*/
|
54
|
+
|
55
|
+
static boolean isIdentifier1 (int c)
|
56
|
+
{
|
57
|
+
return (boolean) (isalpha (c) || c == '_');
|
58
|
+
}
|
59
|
+
|
60
|
+
static boolean isIdentifier (int c)
|
61
|
+
{
|
62
|
+
return (boolean) (isalnum (c) || c == '_');
|
63
|
+
}
|
64
|
+
|
65
|
+
static boolean isPodWord (const char *word)
|
66
|
+
{
|
67
|
+
boolean result = FALSE;
|
68
|
+
if (isalpha (*word))
|
69
|
+
{
|
70
|
+
const char *const pods [] = {
|
71
|
+
"head1", "head2", "head3", "head4", "over", "item", "back",
|
72
|
+
"pod", "begin", "end", "for"
|
73
|
+
};
|
74
|
+
const size_t count = sizeof (pods) / sizeof (pods [0]);
|
75
|
+
const char *white = strpbrk (word, " \t");
|
76
|
+
const size_t len = (white!=NULL) ? (size_t)(white-word) : strlen (word);
|
77
|
+
char *const id = (char*) eMalloc (len + 1);
|
78
|
+
size_t i;
|
79
|
+
strncpy (id, word, len);
|
80
|
+
id [len] = '\0';
|
81
|
+
for (i = 0 ; i < count && ! result ; ++i)
|
82
|
+
{
|
83
|
+
if (strcmp (id, pods [i]) == 0)
|
84
|
+
result = TRUE;
|
85
|
+
}
|
86
|
+
eFree (id);
|
87
|
+
}
|
88
|
+
return result;
|
89
|
+
}
|
90
|
+
|
91
|
+
/*
|
92
|
+
* Perl subroutine declaration may look like one of the following:
|
93
|
+
*
|
94
|
+
* sub abc;
|
95
|
+
* sub abc :attr;
|
96
|
+
* sub abc (proto);
|
97
|
+
* sub abc (proto) :attr;
|
98
|
+
*
|
99
|
+
* Note that there may be more than one attribute. Attributes may
|
100
|
+
* have things in parentheses (they look like arguments). Anything
|
101
|
+
* inside of those parentheses goes. Prototypes may contain semi-colons.
|
102
|
+
* The matching end when we encounter (outside of any parentheses) either
|
103
|
+
* a semi-colon (that'd be a declaration) or an left curly brace
|
104
|
+
* (definition).
|
105
|
+
*
|
106
|
+
* This is pretty complicated parsing (plus we all know that only perl can
|
107
|
+
* parse Perl), so we are only promising best effort here.
|
108
|
+
*
|
109
|
+
* If we can't determine what this is (due to a file ending, for example),
|
110
|
+
* we will return FALSE.
|
111
|
+
*/
|
112
|
+
static boolean isSubroutineDeclaration (const unsigned char *cp)
|
113
|
+
{
|
114
|
+
boolean attr = FALSE;
|
115
|
+
int nparens = 0;
|
116
|
+
|
117
|
+
do {
|
118
|
+
for ( ; *cp; ++cp) {
|
119
|
+
SUB_DECL_SWITCH:
|
120
|
+
switch (*cp) {
|
121
|
+
case ':':
|
122
|
+
if (nparens)
|
123
|
+
break;
|
124
|
+
else if (TRUE == attr)
|
125
|
+
return FALSE; /* Invalid attribute name */
|
126
|
+
else
|
127
|
+
attr = TRUE;
|
128
|
+
break;
|
129
|
+
case '(':
|
130
|
+
++nparens;
|
131
|
+
break;
|
132
|
+
case ')':
|
133
|
+
--nparens;
|
134
|
+
break;
|
135
|
+
case ' ':
|
136
|
+
case '\t':
|
137
|
+
break;
|
138
|
+
case ';':
|
139
|
+
if (!nparens)
|
140
|
+
return TRUE;
|
141
|
+
case '{':
|
142
|
+
if (!nparens)
|
143
|
+
return FALSE;
|
144
|
+
default:
|
145
|
+
if (attr) {
|
146
|
+
if (isIdentifier1(*cp)) {
|
147
|
+
cp++;
|
148
|
+
while (isIdentifier (*cp))
|
149
|
+
cp++;
|
150
|
+
attr = FALSE;
|
151
|
+
goto SUB_DECL_SWITCH; /* Instead of --cp; */
|
152
|
+
} else {
|
153
|
+
return FALSE;
|
154
|
+
}
|
155
|
+
} else if (nparens) {
|
156
|
+
break;
|
157
|
+
} else {
|
158
|
+
return FALSE;
|
159
|
+
}
|
160
|
+
}
|
161
|
+
}
|
162
|
+
} while (NULL != (cp = fileReadLine ()));
|
163
|
+
|
164
|
+
return FALSE;
|
165
|
+
}
|
166
|
+
|
167
|
+
/* Algorithm adapted from from GNU etags.
|
168
|
+
* Perl support by Bart Robinson <lomew@cs.utah.edu>
|
169
|
+
* Perl sub names: look for /^ [ \t\n]sub [ \t\n]+ [^ \t\n{ (]+/
|
170
|
+
*/
|
171
|
+
static void findPerlTags (void)
|
172
|
+
{
|
173
|
+
vString *name = vStringNew ();
|
174
|
+
vString *package = NULL;
|
175
|
+
boolean skipPodDoc = FALSE;
|
176
|
+
const unsigned char *line;
|
177
|
+
|
178
|
+
while ((line = fileReadLine ()) != NULL)
|
179
|
+
{
|
180
|
+
boolean spaceRequired = FALSE;
|
181
|
+
boolean qualified = FALSE;
|
182
|
+
const unsigned char *cp = line;
|
183
|
+
perlKind kind = K_NONE;
|
184
|
+
tagEntryInfo e;
|
185
|
+
|
186
|
+
if (skipPodDoc)
|
187
|
+
{
|
188
|
+
if (strncmp ((const char*) line, "=cut", (size_t) 4) == 0)
|
189
|
+
skipPodDoc = FALSE;
|
190
|
+
continue;
|
191
|
+
}
|
192
|
+
else if (line [0] == '=')
|
193
|
+
{
|
194
|
+
skipPodDoc = isPodWord ((const char*)line + 1);
|
195
|
+
continue;
|
196
|
+
}
|
197
|
+
else if (strcmp ((const char*) line, "__DATA__") == 0)
|
198
|
+
break;
|
199
|
+
else if (strcmp ((const char*) line, "__END__") == 0)
|
200
|
+
break;
|
201
|
+
else if (line [0] == '#')
|
202
|
+
continue;
|
203
|
+
|
204
|
+
while (isspace (*cp))
|
205
|
+
cp++;
|
206
|
+
|
207
|
+
if (strncmp((const char*) cp, "sub", (size_t) 3) == 0)
|
208
|
+
{
|
209
|
+
TRACE("this looks like a sub\n");
|
210
|
+
cp += 3;
|
211
|
+
kind = K_SUBROUTINE;
|
212
|
+
spaceRequired = TRUE;
|
213
|
+
qualified = TRUE;
|
214
|
+
}
|
215
|
+
else if (strncmp((const char*) cp, "use", (size_t) 3) == 0)
|
216
|
+
{
|
217
|
+
cp += 3;
|
218
|
+
if (!isspace(*cp))
|
219
|
+
continue;
|
220
|
+
while (*cp && isspace (*cp))
|
221
|
+
++cp;
|
222
|
+
if (strncmp((const char*) cp, "constant", (size_t) 8) != 0)
|
223
|
+
continue;
|
224
|
+
cp += 8;
|
225
|
+
kind = K_CONSTANT;
|
226
|
+
spaceRequired = TRUE;
|
227
|
+
qualified = TRUE;
|
228
|
+
}
|
229
|
+
else if (strncmp((const char*) cp, "package", (size_t) 7) == 0)
|
230
|
+
{
|
231
|
+
/* This will point to space after 'package' so that a tag
|
232
|
+
can be made */
|
233
|
+
const unsigned char *space = cp += 7;
|
234
|
+
|
235
|
+
if (package == NULL)
|
236
|
+
package = vStringNew ();
|
237
|
+
else
|
238
|
+
vStringClear (package);
|
239
|
+
while (isspace (*cp))
|
240
|
+
cp++;
|
241
|
+
while ((int) *cp != ';' && !isspace ((int) *cp))
|
242
|
+
{
|
243
|
+
vStringPut (package, (int) *cp);
|
244
|
+
cp++;
|
245
|
+
}
|
246
|
+
vStringCatS (package, "::");
|
247
|
+
|
248
|
+
cp = space; /* Rewind */
|
249
|
+
kind = K_PACKAGE;
|
250
|
+
spaceRequired = TRUE;
|
251
|
+
qualified = TRUE;
|
252
|
+
}
|
253
|
+
else if (strncmp((const char*) cp, "format", (size_t) 6) == 0)
|
254
|
+
{
|
255
|
+
cp += 6;
|
256
|
+
kind = K_FORMAT;
|
257
|
+
spaceRequired = TRUE;
|
258
|
+
qualified = TRUE;
|
259
|
+
}
|
260
|
+
else
|
261
|
+
{
|
262
|
+
if (isIdentifier1 (*cp))
|
263
|
+
{
|
264
|
+
const unsigned char *p = cp;
|
265
|
+
while (isIdentifier (*p))
|
266
|
+
++p;
|
267
|
+
while (isspace (*p))
|
268
|
+
++p;
|
269
|
+
if ((int) *p == ':' && (int) *(p + 1) != ':')
|
270
|
+
kind = K_LABEL;
|
271
|
+
}
|
272
|
+
}
|
273
|
+
if (kind != K_NONE)
|
274
|
+
{
|
275
|
+
TRACE("cp0: %s\n", (const char *) cp);
|
276
|
+
if (spaceRequired && *cp && !isspace (*cp))
|
277
|
+
continue;
|
278
|
+
|
279
|
+
TRACE("cp1: %s\n", (const char *) cp);
|
280
|
+
while (isspace (*cp))
|
281
|
+
cp++;
|
282
|
+
|
283
|
+
while (!*cp || '#' == *cp) { /* Gobble up empty lines
|
284
|
+
and comments */
|
285
|
+
cp = fileReadLine ();
|
286
|
+
if (!cp)
|
287
|
+
goto END_MAIN_WHILE;
|
288
|
+
while (isspace (*cp))
|
289
|
+
cp++;
|
290
|
+
}
|
291
|
+
|
292
|
+
while (isIdentifier (*cp) || (K_PACKAGE == kind && ':' == *cp))
|
293
|
+
{
|
294
|
+
vStringPut (name, (int) *cp);
|
295
|
+
cp++;
|
296
|
+
}
|
297
|
+
|
298
|
+
if (K_FORMAT == kind &&
|
299
|
+
vStringLength (name) == 0 && /* cp did not advance */
|
300
|
+
'=' == *cp)
|
301
|
+
{
|
302
|
+
/* format's name is optional. If it's omitted, 'STDOUT'
|
303
|
+
is assumed. */
|
304
|
+
vStringCatS (name, "STDOUT");
|
305
|
+
}
|
306
|
+
|
307
|
+
vStringTerminate (name);
|
308
|
+
TRACE("name: %s\n", name->buffer);
|
309
|
+
|
310
|
+
if (0 == vStringLength(name)) {
|
311
|
+
vStringClear(name);
|
312
|
+
continue;
|
313
|
+
}
|
314
|
+
|
315
|
+
if (K_SUBROUTINE == kind)
|
316
|
+
{
|
317
|
+
/*
|
318
|
+
* isSubroutineDeclaration() may consume several lines. So
|
319
|
+
* we record line positions.
|
320
|
+
*/
|
321
|
+
initTagEntry(&e, vStringValue(name));
|
322
|
+
|
323
|
+
if (TRUE == isSubroutineDeclaration(cp)) {
|
324
|
+
if (TRUE == PerlKinds[K_SUBROUTINE_DECLARATION].enabled) {
|
325
|
+
kind = K_SUBROUTINE_DECLARATION;
|
326
|
+
} else {
|
327
|
+
vStringClear (name);
|
328
|
+
continue;
|
329
|
+
}
|
330
|
+
}
|
331
|
+
|
332
|
+
e.kind = PerlKinds[kind].letter;
|
333
|
+
e.kindName = PerlKinds[kind].name;
|
334
|
+
|
335
|
+
makeTagEntry(&e);
|
336
|
+
|
337
|
+
if (Option.include.qualifiedTags && qualified &&
|
338
|
+
package != NULL && vStringLength (package) > 0)
|
339
|
+
{
|
340
|
+
vString *const qualifiedName = vStringNew ();
|
341
|
+
vStringCopy (qualifiedName, package);
|
342
|
+
vStringCat (qualifiedName, name);
|
343
|
+
e.name = vStringValue(qualifiedName);
|
344
|
+
makeTagEntry(&e);
|
345
|
+
vStringDelete (qualifiedName);
|
346
|
+
}
|
347
|
+
} else if (vStringLength (name) > 0)
|
348
|
+
{
|
349
|
+
makeSimpleTag (name, PerlKinds, kind);
|
350
|
+
if (Option.include.qualifiedTags && qualified &&
|
351
|
+
K_PACKAGE != kind &&
|
352
|
+
package != NULL && vStringLength (package) > 0)
|
353
|
+
{
|
354
|
+
vString *const qualifiedName = vStringNew ();
|
355
|
+
vStringCopy (qualifiedName, package);
|
356
|
+
vStringCat (qualifiedName, name);
|
357
|
+
makeSimpleTag (qualifiedName, PerlKinds, kind);
|
358
|
+
vStringDelete (qualifiedName);
|
359
|
+
}
|
360
|
+
}
|
361
|
+
vStringClear (name);
|
362
|
+
}
|
363
|
+
}
|
364
|
+
|
365
|
+
END_MAIN_WHILE:
|
366
|
+
vStringDelete (name);
|
367
|
+
if (package != NULL)
|
368
|
+
vStringDelete (package);
|
369
|
+
}
|
370
|
+
|
371
|
+
extern parserDefinition* PerlParser (void)
|
372
|
+
{
|
373
|
+
static const char *const extensions [] = { "pl", "pm", "plx", "perl", NULL };
|
374
|
+
parserDefinition* def = parserNew ("Perl");
|
375
|
+
def->kinds = PerlKinds;
|
376
|
+
def->kindCount = KIND_COUNT (PerlKinds);
|
377
|
+
def->extensions = extensions;
|
378
|
+
def->parser = findPerlTags;
|
379
|
+
return def;
|
380
|
+
}
|
381
|
+
|
382
|
+
/* vi:set tabstop=4 shiftwidth=4 noexpandtab: */
|
@@ -0,0 +1,237 @@
|
|
1
|
+
/*
|
2
|
+
* $Id: php.c 624 2007-09-15 22:53:31Z jafl $
|
3
|
+
*
|
4
|
+
* Copyright (c) 2000, Jesus Castagnetto <jmcastagnetto@zkey.com>
|
5
|
+
*
|
6
|
+
* This source code is released for free distribution under the terms of the
|
7
|
+
* GNU General Public License.
|
8
|
+
*
|
9
|
+
* This module contains functions for generating tags for the PHP web page
|
10
|
+
* scripting language. Only recognizes functions and classes, not methods or
|
11
|
+
* variables.
|
12
|
+
*
|
13
|
+
* Parsing PHP defines by Pavel Hlousek <pavel.hlousek@seznam.cz>, Apr 2003.
|
14
|
+
*/
|
15
|
+
|
16
|
+
/*
|
17
|
+
* INCLUDE FILES
|
18
|
+
*/
|
19
|
+
#include "general.h" /* must always come first */
|
20
|
+
|
21
|
+
#include <string.h>
|
22
|
+
|
23
|
+
#include "parse.h"
|
24
|
+
#include "read.h"
|
25
|
+
#include "vstring.h"
|
26
|
+
|
27
|
+
/*
|
28
|
+
* DATA DEFINITIONS
|
29
|
+
*/
|
30
|
+
typedef enum {
|
31
|
+
K_CLASS, K_DEFINE, K_FUNCTION, K_VARIABLE
|
32
|
+
} phpKind;
|
33
|
+
|
34
|
+
#if 0
|
35
|
+
static kindOption PhpKinds [] = {
|
36
|
+
{ TRUE, 'c', "class", "classes" },
|
37
|
+
{ TRUE, 'd', "define", "constant definitions" },
|
38
|
+
{ TRUE, 'f', "function", "functions" },
|
39
|
+
{ TRUE, 'v', "variable", "variables" }
|
40
|
+
};
|
41
|
+
#endif
|
42
|
+
|
43
|
+
/*
|
44
|
+
* FUNCTION DEFINITIONS
|
45
|
+
*/
|
46
|
+
|
47
|
+
/* JavaScript patterns are duplicated in jscript.c */
|
48
|
+
|
49
|
+
/*
|
50
|
+
* Cygwin doesn't support non-ASCII characters in character classes.
|
51
|
+
* This isn't a good solution to the underlying problem, because we're still
|
52
|
+
* making assumptions about the character encoding.
|
53
|
+
* Really, these regular expressions need to concentrate on what marks the
|
54
|
+
* end of an identifier, and we need something like iconv to take into
|
55
|
+
* account the user's locale (or an override on the command-line.)
|
56
|
+
*/
|
57
|
+
#ifdef __CYGWIN__
|
58
|
+
#define ALPHA "[:alpha:]"
|
59
|
+
#define ALNUM "[:alnum:]"
|
60
|
+
#else
|
61
|
+
#define ALPHA "A-Za-z\x7f-\xff"
|
62
|
+
#define ALNUM "0-9A-Za-z\x7f-\xff"
|
63
|
+
#endif
|
64
|
+
|
65
|
+
static void installPHPRegex (const langType language)
|
66
|
+
{
|
67
|
+
addTagRegex(language, "(^|[ \t])class[ \t]+([" ALPHA "_][" ALNUM "_]*)",
|
68
|
+
"\\2", "c,class,classes", NULL);
|
69
|
+
addTagRegex(language, "(^|[ \t])interface[ \t]+([" ALPHA "_][" ALNUM "_]*)",
|
70
|
+
"\\2", "i,interface,interfaces", NULL);
|
71
|
+
addTagRegex(language, "(^|[ \t])define[ \t]*\\([ \t]*['\"]?([" ALPHA "_][" ALNUM "_]*)",
|
72
|
+
"\\2", "d,define,constant definitions", NULL);
|
73
|
+
addTagRegex(language, "(^|[ \t])function[ \t]+&?[ \t]*([" ALPHA "_][" ALNUM "_]*)",
|
74
|
+
"\\2", "f,function,functions", NULL);
|
75
|
+
addTagRegex(language, "(^|[ \t])(\\$|::\\$|\\$this->)([" ALPHA "_][" ALNUM "_]*)[ \t]*=",
|
76
|
+
"\\3", "v,variable,variables", NULL);
|
77
|
+
addTagRegex(language, "(^|[ \t])(var|public|protected|private|static)[ \t]+\\$([" ALPHA "_][" ALNUM "_]*)[ \t]*[=;]",
|
78
|
+
"\\3", "v,variable,variables", NULL);
|
79
|
+
|
80
|
+
/* function regex is covered by PHP regex */
|
81
|
+
addTagRegex (language, "(^|[ \t])([A-Za-z0-9_]+)[ \t]*[=:][ \t]*function[ \t]*\\(",
|
82
|
+
"\\2", "j,jsfunction,javascript functions", NULL);
|
83
|
+
addTagRegex (language, "(^|[ \t])([A-Za-z0-9_.]+)\\.([A-Za-z0-9_]+)[ \t]*=[ \t]*function[ \t]*\\(",
|
84
|
+
"\\2.\\3", "j,jsfunction,javascript functions", NULL);
|
85
|
+
addTagRegex (language, "(^|[ \t])([A-Za-z0-9_.]+)\\.([A-Za-z0-9_]+)[ \t]*=[ \t]*function[ \t]*\\(",
|
86
|
+
"\\3", "j,jsfunction,javascript functions", NULL);
|
87
|
+
}
|
88
|
+
|
89
|
+
/* Create parser definition structure */
|
90
|
+
extern parserDefinition* PhpParser (void)
|
91
|
+
{
|
92
|
+
static const char *const extensions [] = { "php", "php3", "phtml", NULL };
|
93
|
+
parserDefinition* def = parserNew ("PHP");
|
94
|
+
def->extensions = extensions;
|
95
|
+
def->initialize = installPHPRegex;
|
96
|
+
def->regex = TRUE;
|
97
|
+
return def;
|
98
|
+
}
|
99
|
+
|
100
|
+
#if 0
|
101
|
+
|
102
|
+
static boolean isLetter(const int c)
|
103
|
+
{
|
104
|
+
return (boolean)(isalpha(c) || (c >= 127 && c <= 255));
|
105
|
+
}
|
106
|
+
|
107
|
+
static boolean isVarChar1(const int c)
|
108
|
+
{
|
109
|
+
return (boolean)(isLetter (c) || c == '_');
|
110
|
+
}
|
111
|
+
|
112
|
+
static boolean isVarChar(const int c)
|
113
|
+
{
|
114
|
+
return (boolean)(isVarChar1 (c) || isdigit (c));
|
115
|
+
}
|
116
|
+
|
117
|
+
static void findPhpTags (void)
|
118
|
+
{
|
119
|
+
vString *name = vStringNew ();
|
120
|
+
const unsigned char *line;
|
121
|
+
|
122
|
+
while ((line = fileReadLine ()) != NULL)
|
123
|
+
{
|
124
|
+
const unsigned char *cp = line;
|
125
|
+
const char* f;
|
126
|
+
|
127
|
+
while (isspace (*cp))
|
128
|
+
cp++;
|
129
|
+
|
130
|
+
if (*(const char*)cp == '$' && isVarChar1 (*(const char*)(cp+1)))
|
131
|
+
{
|
132
|
+
cp += 1;
|
133
|
+
vStringClear (name);
|
134
|
+
while (isVarChar ((int) *cp))
|
135
|
+
{
|
136
|
+
vStringPut (name, (int) *cp);
|
137
|
+
++cp;
|
138
|
+
}
|
139
|
+
while (isspace ((int) *cp))
|
140
|
+
++cp;
|
141
|
+
if (*(const char*) cp == '=')
|
142
|
+
{
|
143
|
+
vStringTerminate (name);
|
144
|
+
makeSimpleTag (name, PhpKinds, K_VARIABLE);
|
145
|
+
vStringClear (name);
|
146
|
+
}
|
147
|
+
}
|
148
|
+
else if ((f = strstr ((const char*) cp, "function")) != NULL &&
|
149
|
+
(f == (const char*) cp || isspace ((int) f [-1])) &&
|
150
|
+
isspace ((int) f [8]))
|
151
|
+
{
|
152
|
+
cp = ((const unsigned char *) f) + 8;
|
153
|
+
|
154
|
+
while (isspace ((int) *cp))
|
155
|
+
++cp;
|
156
|
+
|
157
|
+
if (*cp == '&') /* skip reference character and following whitespace */
|
158
|
+
{
|
159
|
+
cp++;
|
160
|
+
|
161
|
+
while (isspace ((int) *cp))
|
162
|
+
++cp;
|
163
|
+
}
|
164
|
+
|
165
|
+
vStringClear (name);
|
166
|
+
while (isalnum ((int) *cp) || *cp == '_')
|
167
|
+
{
|
168
|
+
vStringPut (name, (int) *cp);
|
169
|
+
++cp;
|
170
|
+
}
|
171
|
+
vStringTerminate (name);
|
172
|
+
makeSimpleTag (name, PhpKinds, K_FUNCTION);
|
173
|
+
vStringClear (name);
|
174
|
+
}
|
175
|
+
else if (strncmp ((const char*) cp, "class", (size_t) 5) == 0 &&
|
176
|
+
isspace ((int) cp [5]))
|
177
|
+
{
|
178
|
+
cp += 5;
|
179
|
+
|
180
|
+
while (isspace ((int) *cp))
|
181
|
+
++cp;
|
182
|
+
vStringClear (name);
|
183
|
+
while (isalnum ((int) *cp) || *cp == '_')
|
184
|
+
{
|
185
|
+
vStringPut (name, (int) *cp);
|
186
|
+
++cp;
|
187
|
+
}
|
188
|
+
vStringTerminate (name);
|
189
|
+
makeSimpleTag (name, PhpKinds, K_CLASS);
|
190
|
+
vStringClear (name);
|
191
|
+
}
|
192
|
+
else if (strncmp ((const char*) cp, "define", (size_t) 6) == 0 &&
|
193
|
+
! isalnum ((int) cp [6]))
|
194
|
+
{
|
195
|
+
cp += 6;
|
196
|
+
|
197
|
+
while (isspace ((int) *cp))
|
198
|
+
++cp;
|
199
|
+
if (*cp != '(')
|
200
|
+
continue;
|
201
|
+
++cp;
|
202
|
+
|
203
|
+
while (isspace ((int) *cp))
|
204
|
+
++cp;
|
205
|
+
if ((*cp == '\'') || (*cp == '"'))
|
206
|
+
++cp;
|
207
|
+
else if (! ((*cp == '_') || isalnum ((int) *cp)))
|
208
|
+
continue;
|
209
|
+
|
210
|
+
vStringClear (name);
|
211
|
+
while (isalnum ((int) *cp) || *cp == '_')
|
212
|
+
{
|
213
|
+
vStringPut (name, (int) *cp);
|
214
|
+
++cp;
|
215
|
+
}
|
216
|
+
vStringTerminate (name);
|
217
|
+
makeSimpleTag (name, PhpKinds, K_DEFINE);
|
218
|
+
vStringClear (name);
|
219
|
+
}
|
220
|
+
}
|
221
|
+
vStringDelete (name);
|
222
|
+
}
|
223
|
+
|
224
|
+
extern parserDefinition* PhpParser (void)
|
225
|
+
{
|
226
|
+
static const char *const extensions [] = { "php", "php3", "phtml", NULL };
|
227
|
+
parserDefinition* def = parserNew ("PHP");
|
228
|
+
def->kinds = PhpKinds;
|
229
|
+
def->kindCount = KIND_COUNT (PhpKinds);
|
230
|
+
def->extensions = extensions;
|
231
|
+
def->parser = findPhpTags;
|
232
|
+
return def;
|
233
|
+
}
|
234
|
+
|
235
|
+
#endif
|
236
|
+
|
237
|
+
/* vi:set tabstop=4 shiftwidth=4: */
|