ctags.rb 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. data/Gemfile +2 -0
  2. data/Rakefile +23 -0
  3. data/ctags.rb.gemspec +23 -0
  4. data/ext/.gitignore +3 -0
  5. data/ext/extconf.rb +15 -0
  6. data/ext/vendor/exuberant-ctags/.gitignore +6 -0
  7. data/ext/vendor/exuberant-ctags/.indent.pro +31 -0
  8. data/ext/vendor/exuberant-ctags/COPYING +340 -0
  9. data/ext/vendor/exuberant-ctags/EXTENDING.html +386 -0
  10. data/ext/vendor/exuberant-ctags/FAQ +371 -0
  11. data/ext/vendor/exuberant-ctags/INSTALL +215 -0
  12. data/ext/vendor/exuberant-ctags/INSTALL.oth +73 -0
  13. data/ext/vendor/exuberant-ctags/MAINTAINERS +88 -0
  14. data/ext/vendor/exuberant-ctags/Makefile.in +222 -0
  15. data/ext/vendor/exuberant-ctags/NEWS +871 -0
  16. data/ext/vendor/exuberant-ctags/README +73 -0
  17. data/ext/vendor/exuberant-ctags/ant.c +42 -0
  18. data/ext/vendor/exuberant-ctags/argproc.c +505 -0
  19. data/ext/vendor/exuberant-ctags/args.c +274 -0
  20. data/ext/vendor/exuberant-ctags/args.h +63 -0
  21. data/ext/vendor/exuberant-ctags/asm.c +387 -0
  22. data/ext/vendor/exuberant-ctags/asp.c +328 -0
  23. data/ext/vendor/exuberant-ctags/awk.c +81 -0
  24. data/ext/vendor/exuberant-ctags/basic.c +203 -0
  25. data/ext/vendor/exuberant-ctags/beta.c +321 -0
  26. data/ext/vendor/exuberant-ctags/c.c +2932 -0
  27. data/ext/vendor/exuberant-ctags/cobol.c +50 -0
  28. data/ext/vendor/exuberant-ctags/config.h.in +277 -0
  29. data/ext/vendor/exuberant-ctags/configure +7704 -0
  30. data/ext/vendor/exuberant-ctags/configure.ac +532 -0
  31. data/ext/vendor/exuberant-ctags/ctags.1 +1186 -0
  32. data/ext/vendor/exuberant-ctags/ctags.h +28 -0
  33. data/ext/vendor/exuberant-ctags/ctags.html +2087 -0
  34. data/ext/vendor/exuberant-ctags/ctags.spec +40 -0
  35. data/ext/vendor/exuberant-ctags/debug.c +113 -0
  36. data/ext/vendor/exuberant-ctags/debug.h +70 -0
  37. data/ext/vendor/exuberant-ctags/descrip.mms +68 -0
  38. data/ext/vendor/exuberant-ctags/dosbatch.c +42 -0
  39. data/ext/vendor/exuberant-ctags/e_amiga.h +24 -0
  40. data/ext/vendor/exuberant-ctags/e_djgpp.h +47 -0
  41. data/ext/vendor/exuberant-ctags/e_mac.h +143 -0
  42. data/ext/vendor/exuberant-ctags/e_msoft.h +76 -0
  43. data/ext/vendor/exuberant-ctags/e_os2.h +37 -0
  44. data/ext/vendor/exuberant-ctags/e_qdos.h +34 -0
  45. data/ext/vendor/exuberant-ctags/e_riscos.h +58 -0
  46. data/ext/vendor/exuberant-ctags/e_vms.h +31 -0
  47. data/ext/vendor/exuberant-ctags/eiffel.c +1352 -0
  48. data/ext/vendor/exuberant-ctags/entry.c +847 -0
  49. data/ext/vendor/exuberant-ctags/entry.h +103 -0
  50. data/ext/vendor/exuberant-ctags/erlang.c +189 -0
  51. data/ext/vendor/exuberant-ctags/flex.c +2243 -0
  52. data/ext/vendor/exuberant-ctags/fortran.c +2197 -0
  53. data/ext/vendor/exuberant-ctags/general.h +127 -0
  54. data/ext/vendor/exuberant-ctags/get.c +669 -0
  55. data/ext/vendor/exuberant-ctags/get.h +50 -0
  56. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/all-wcprops +47 -0
  57. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/entries +112 -0
  58. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/README.txt.svn-base +5 -0
  59. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regcomp.c.svn-base +3818 -0
  60. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex.c.svn-base +74 -0
  61. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex.h.svn-base +575 -0
  62. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex_internal.c.svn-base +1713 -0
  63. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex_internal.h.svn-base +773 -0
  64. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regexec.c.svn-base +4338 -0
  65. data/ext/vendor/exuberant-ctags/gnu_regex/README.txt +5 -0
  66. data/ext/vendor/exuberant-ctags/gnu_regex/regcomp.c +3818 -0
  67. data/ext/vendor/exuberant-ctags/gnu_regex/regex.c +74 -0
  68. data/ext/vendor/exuberant-ctags/gnu_regex/regex.h +575 -0
  69. data/ext/vendor/exuberant-ctags/gnu_regex/regex_internal.c +1713 -0
  70. data/ext/vendor/exuberant-ctags/gnu_regex/regex_internal.h +773 -0
  71. data/ext/vendor/exuberant-ctags/gnu_regex/regexec.c +4338 -0
  72. data/ext/vendor/exuberant-ctags/html.c +49 -0
  73. data/ext/vendor/exuberant-ctags/jscript.c +1572 -0
  74. data/ext/vendor/exuberant-ctags/keyword.c +258 -0
  75. data/ext/vendor/exuberant-ctags/keyword.h +34 -0
  76. data/ext/vendor/exuberant-ctags/lisp.c +139 -0
  77. data/ext/vendor/exuberant-ctags/lregex.c +704 -0
  78. data/ext/vendor/exuberant-ctags/lua.c +133 -0
  79. data/ext/vendor/exuberant-ctags/mac.c +273 -0
  80. data/ext/vendor/exuberant-ctags/magic.diff +21 -0
  81. data/ext/vendor/exuberant-ctags/main.c +584 -0
  82. data/ext/vendor/exuberant-ctags/main.h +32 -0
  83. data/ext/vendor/exuberant-ctags/maintainer.mak +476 -0
  84. data/ext/vendor/exuberant-ctags/make.c +217 -0
  85. data/ext/vendor/exuberant-ctags/matlab.c +44 -0
  86. data/ext/vendor/exuberant-ctags/mk_bc3.mak +46 -0
  87. data/ext/vendor/exuberant-ctags/mk_bc5.mak +49 -0
  88. data/ext/vendor/exuberant-ctags/mk_djg.mak +18 -0
  89. data/ext/vendor/exuberant-ctags/mk_manx.mak +65 -0
  90. data/ext/vendor/exuberant-ctags/mk_mingw.mak +31 -0
  91. data/ext/vendor/exuberant-ctags/mk_mpw.mak +130 -0
  92. data/ext/vendor/exuberant-ctags/mk_mvc.mak +40 -0
  93. data/ext/vendor/exuberant-ctags/mk_os2.mak +104 -0
  94. data/ext/vendor/exuberant-ctags/mk_qdos.mak +100 -0
  95. data/ext/vendor/exuberant-ctags/mk_sas.mak +63 -0
  96. data/ext/vendor/exuberant-ctags/mkinstalldirs +40 -0
  97. data/ext/vendor/exuberant-ctags/ocaml.c +1842 -0
  98. data/ext/vendor/exuberant-ctags/options.c +1842 -0
  99. data/ext/vendor/exuberant-ctags/options.h +155 -0
  100. data/ext/vendor/exuberant-ctags/parse.c +677 -0
  101. data/ext/vendor/exuberant-ctags/parse.h +129 -0
  102. data/ext/vendor/exuberant-ctags/parsers.h +63 -0
  103. data/ext/vendor/exuberant-ctags/pascal.c +267 -0
  104. data/ext/vendor/exuberant-ctags/perl.c +382 -0
  105. data/ext/vendor/exuberant-ctags/php.c +237 -0
  106. data/ext/vendor/exuberant-ctags/python.c +771 -0
  107. data/ext/vendor/exuberant-ctags/qdos.c +106 -0
  108. data/ext/vendor/exuberant-ctags/read.c +569 -0
  109. data/ext/vendor/exuberant-ctags/read.h +116 -0
  110. data/ext/vendor/exuberant-ctags/readtags.c +959 -0
  111. data/ext/vendor/exuberant-ctags/readtags.h +252 -0
  112. data/ext/vendor/exuberant-ctags/rexx.c +39 -0
  113. data/ext/vendor/exuberant-ctags/routines.c +891 -0
  114. data/ext/vendor/exuberant-ctags/routines.h +134 -0
  115. data/ext/vendor/exuberant-ctags/ruby.c +408 -0
  116. data/ext/vendor/exuberant-ctags/scheme.c +111 -0
  117. data/ext/vendor/exuberant-ctags/sh.c +115 -0
  118. data/ext/vendor/exuberant-ctags/slang.c +41 -0
  119. data/ext/vendor/exuberant-ctags/sml.c +212 -0
  120. data/ext/vendor/exuberant-ctags/sort.c +230 -0
  121. data/ext/vendor/exuberant-ctags/sort.h +32 -0
  122. data/ext/vendor/exuberant-ctags/source.mak +122 -0
  123. data/ext/vendor/exuberant-ctags/sql.c +2112 -0
  124. data/ext/vendor/exuberant-ctags/strlist.c +281 -0
  125. data/ext/vendor/exuberant-ctags/strlist.h +54 -0
  126. data/ext/vendor/exuberant-ctags/tcl.c +116 -0
  127. data/ext/vendor/exuberant-ctags/tex.c +524 -0
  128. data/ext/vendor/exuberant-ctags/verilog.c +340 -0
  129. data/ext/vendor/exuberant-ctags/vhdl.c +835 -0
  130. data/ext/vendor/exuberant-ctags/vim.c +636 -0
  131. data/ext/vendor/exuberant-ctags/vstring.c +232 -0
  132. data/ext/vendor/exuberant-ctags/vstring.h +85 -0
  133. data/ext/vendor/exuberant-ctags/yacc.c +40 -0
  134. data/lib/ctags/exuberant.rb +45 -0
  135. data/lib/ctags/version.rb +3 -0
  136. data/lib/ctags.rb +6 -0
  137. data/test/test_ctags.rb +24 -0
  138. 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: */