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.
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: */