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,636 @@
1
+ /*
2
+ * $Id: vim.c 485 2006-10-24 12:06:19Z dfishburn $
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
+ * Thanks are due to Jay Glanville for significant improvements.
10
+ *
11
+ * This module contains functions for generating tags for user-defined
12
+ * functions for the Vim editor.
13
+ */
14
+
15
+ /*
16
+ * INCLUDE FILES
17
+ */
18
+ #include "general.h" /* must always come first */
19
+
20
+ #include <string.h>
21
+ #include <setjmp.h>
22
+ #ifdef DEBUG
23
+ #include <stdio.h>
24
+ #endif
25
+
26
+
27
+ #include "parse.h"
28
+ #include "read.h"
29
+ #include "vstring.h"
30
+
31
+ #if 0
32
+ typedef struct sLineInfo {
33
+ tokenType type;
34
+ keywordId keyword;
35
+ vString * string;
36
+ vString * scope;
37
+ unsigned long lineNumber;
38
+ fpos_t filePosition;
39
+ } lineInfo;
40
+ #endif
41
+
42
+ /*
43
+ * DATA DEFINITIONS
44
+ */
45
+ typedef enum {
46
+ K_AUGROUP,
47
+ K_COMMAND,
48
+ K_FUNCTION,
49
+ K_MAP,
50
+ K_VARIABLE
51
+ } vimKind;
52
+
53
+ static kindOption VimKinds [] = {
54
+ { TRUE, 'a', "augroup", "autocommand groups" },
55
+ { TRUE, 'c', "command", "user-defined commands" },
56
+ { TRUE, 'f', "function", "function definitions" },
57
+ { TRUE, 'm', "map", "maps" },
58
+ { TRUE, 'v', "variable", "variable definitions" },
59
+ };
60
+
61
+ /*
62
+ * DATA DECLARATIONS
63
+ */
64
+
65
+ #if 0
66
+ typedef enum eException {
67
+ ExceptionNone, ExceptionEOF
68
+ } exception_t;
69
+ #endif
70
+
71
+ /*
72
+ * DATA DEFINITIONS
73
+ */
74
+
75
+ #if 0
76
+ static jmp_buf Exception;
77
+ #endif
78
+
79
+ /*
80
+ * FUNCTION DEFINITIONS
81
+ */
82
+
83
+ /* This function takes a char pointer, tries to find a scope separator in the
84
+ * string, and if it does, returns a pointer to the character after the colon,
85
+ * and the character defining the scope.
86
+ * If a colon is not found, it returns the original pointer.
87
+ */
88
+ static const unsigned char* skipPrefix (const unsigned char* name, int *scope)
89
+ {
90
+ const unsigned char* result = name;
91
+ int counter;
92
+ size_t length;
93
+ length = strlen((const char*)name);
94
+ if (scope != NULL)
95
+ *scope = '\0';
96
+ if (length > 3 && name[1] == ':')
97
+ {
98
+ if (scope != NULL)
99
+ *scope = *name;
100
+ result = name + 2;
101
+ }
102
+ else if (length > 5 && strncasecmp ((const char*) name, "<SID>", (size_t) 5) == 0)
103
+ {
104
+ if (scope != NULL)
105
+ *scope = *name;
106
+ result = name + 5;
107
+ }
108
+ else
109
+ {
110
+ /*
111
+ * Vim7 check for dictionaries or autoload function names
112
+ */
113
+ counter = 0;
114
+ do
115
+ {
116
+ switch ( name[counter] )
117
+ {
118
+ case '.':
119
+ /* Set the scope to d - Dictionary */
120
+ *scope = 'd';
121
+ break;
122
+ case '#':
123
+ /* Set the scope to a - autoload */
124
+ *scope = 'a';
125
+ break;
126
+ }
127
+ ++counter;
128
+ } while (isalnum ((int) name[counter]) ||
129
+ name[counter] == '_' ||
130
+ name[counter] == '.' ||
131
+ name[counter] == '#'
132
+ );
133
+ }
134
+ return result;
135
+ }
136
+
137
+ static boolean isMap (const unsigned char* line)
138
+ {
139
+ /*
140
+ * There are many different short cuts for specifying a map.
141
+ * This routine should capture all the permutations.
142
+ */
143
+ if (
144
+ strncmp ((const char*) line, "map", (size_t) 3) == 0 ||
145
+ strncmp ((const char*) line, "nm", (size_t) 2) == 0 ||
146
+ strncmp ((const char*) line, "nma", (size_t) 3) == 0 ||
147
+ strncmp ((const char*) line, "nmap", (size_t) 4) == 0 ||
148
+ strncmp ((const char*) line, "vm", (size_t) 2) == 0 ||
149
+ strncmp ((const char*) line, "vma", (size_t) 3) == 0 ||
150
+ strncmp ((const char*) line, "vmap", (size_t) 4) == 0 ||
151
+ strncmp ((const char*) line, "om", (size_t) 2) == 0 ||
152
+ strncmp ((const char*) line, "oma", (size_t) 3) == 0 ||
153
+ strncmp ((const char*) line, "omap", (size_t) 4) == 0 ||
154
+ strncmp ((const char*) line, "im", (size_t) 2) == 0 ||
155
+ strncmp ((const char*) line, "ima", (size_t) 3) == 0 ||
156
+ strncmp ((const char*) line, "imap", (size_t) 4) == 0 ||
157
+ strncmp ((const char*) line, "lm", (size_t) 2) == 0 ||
158
+ strncmp ((const char*) line, "lma", (size_t) 3) == 0 ||
159
+ strncmp ((const char*) line, "lmap", (size_t) 4) == 0 ||
160
+ strncmp ((const char*) line, "cm", (size_t) 2) == 0 ||
161
+ strncmp ((const char*) line, "cma", (size_t) 3) == 0 ||
162
+ strncmp ((const char*) line, "cmap", (size_t) 4) == 0 ||
163
+ strncmp ((const char*) line, "no", (size_t) 2) == 0 ||
164
+ strncmp ((const char*) line, "nor", (size_t) 3) == 0 ||
165
+ strncmp ((const char*) line, "nore", (size_t) 4) == 0 ||
166
+ strncmp ((const char*) line, "norem", (size_t) 5) == 0 ||
167
+ strncmp ((const char*) line, "norema", (size_t) 6) == 0 ||
168
+ strncmp ((const char*) line, "noremap", (size_t) 7) == 0 ||
169
+ strncmp ((const char*) line, "nno", (size_t) 3) == 0 ||
170
+ strncmp ((const char*) line, "nnor", (size_t) 4) == 0 ||
171
+ strncmp ((const char*) line, "nnore", (size_t) 5) == 0 ||
172
+ strncmp ((const char*) line, "nnorem", (size_t) 6) == 0 ||
173
+ strncmp ((const char*) line, "nnorema", (size_t) 7) == 0 ||
174
+ strncmp ((const char*) line, "nnoremap", (size_t) 8) == 0 ||
175
+ strncmp ((const char*) line, "vno", (size_t) 3) == 0 ||
176
+ strncmp ((const char*) line, "vnor", (size_t) 4) == 0 ||
177
+ strncmp ((const char*) line, "vnore", (size_t) 5) == 0 ||
178
+ strncmp ((const char*) line, "vnorem", (size_t) 6) == 0 ||
179
+ strncmp ((const char*) line, "vnorema", (size_t) 7) == 0 ||
180
+ strncmp ((const char*) line, "vnoremap", (size_t) 8) == 0 ||
181
+ strncmp ((const char*) line, "ono", (size_t) 3) == 0 ||
182
+ strncmp ((const char*) line, "onor", (size_t) 4) == 0 ||
183
+ strncmp ((const char*) line, "onore", (size_t) 5) == 0 ||
184
+ strncmp ((const char*) line, "onorem", (size_t) 6) == 0 ||
185
+ strncmp ((const char*) line, "onorema", (size_t) 7) == 0 ||
186
+ strncmp ((const char*) line, "onoremap", (size_t) 8) == 0 ||
187
+ strncmp ((const char*) line, "ino", (size_t) 3) == 0 ||
188
+ strncmp ((const char*) line, "inor", (size_t) 4) == 0 ||
189
+ strncmp ((const char*) line, "inore", (size_t) 5) == 0 ||
190
+ strncmp ((const char*) line, "inorem", (size_t) 6) == 0 ||
191
+ strncmp ((const char*) line, "inorema", (size_t) 7) == 0 ||
192
+ strncmp ((const char*) line, "inoremap", (size_t) 8) == 0 ||
193
+ strncmp ((const char*) line, "lno", (size_t) 3) == 0 ||
194
+ strncmp ((const char*) line, "lnor", (size_t) 4) == 0 ||
195
+ strncmp ((const char*) line, "lnore", (size_t) 5) == 0 ||
196
+ strncmp ((const char*) line, "lnorem", (size_t) 6) == 0 ||
197
+ strncmp ((const char*) line, "lnorema", (size_t) 7) == 0 ||
198
+ strncmp ((const char*) line, "lnoremap", (size_t) 8) == 0 ||
199
+ strncmp ((const char*) line, "cno", (size_t) 3) == 0 ||
200
+ strncmp ((const char*) line, "cnor", (size_t) 4) == 0 ||
201
+ strncmp ((const char*) line, "cnore", (size_t) 5) == 0 ||
202
+ strncmp ((const char*) line, "cnorem", (size_t) 6) == 0 ||
203
+ strncmp ((const char*) line, "cnorema", (size_t) 7) == 0 ||
204
+ strncmp ((const char*) line, "cnoremap", (size_t) 8) == 0
205
+ )
206
+ return TRUE;
207
+
208
+ return FALSE;
209
+ }
210
+
211
+ static const unsigned char * readVimLine (void)
212
+ {
213
+ const unsigned char *line;
214
+
215
+ while ((line = fileReadLine ()) != NULL)
216
+ {
217
+ while (isspace ((int) *line))
218
+ ++line;
219
+
220
+ if ((int) *line == '"')
221
+ continue; /* skip comment */
222
+
223
+ break;
224
+ }
225
+
226
+ return line;
227
+ }
228
+
229
+ static void parseFunction (const unsigned char *line)
230
+ {
231
+ vString *name = vStringNew ();
232
+ /* boolean inFunction = FALSE; */
233
+ int scope;
234
+
235
+ const unsigned char *cp = line + 1;
236
+
237
+ if ((int) *++cp == 'n' && (int) *++cp == 'c' &&
238
+ (int) *++cp == 't' && (int) *++cp == 'i' &&
239
+ (int) *++cp == 'o' && (int) *++cp == 'n')
240
+ ++cp;
241
+ if ((int) *cp == '!')
242
+ ++cp;
243
+ if (isspace ((int) *cp))
244
+ {
245
+ while (*cp && isspace ((int) *cp))
246
+ ++cp;
247
+
248
+ if (*cp)
249
+ {
250
+ cp = skipPrefix (cp, &scope);
251
+ if (isupper ((int) *cp) ||
252
+ scope == 's' || /* script scope */
253
+ scope == '<' || /* script scope */
254
+ scope == 'd' || /* dictionary */
255
+ scope == 'a') /* autoload */
256
+ {
257
+ do
258
+ {
259
+ vStringPut (name, (int) *cp);
260
+ ++cp;
261
+ } while (isalnum ((int) *cp) || *cp == '_' || *cp == '.' || *cp == '#');
262
+ vStringTerminate (name);
263
+ makeSimpleTag (name, VimKinds, K_FUNCTION);
264
+ vStringClear (name);
265
+ }
266
+ }
267
+ }
268
+
269
+ /* TODO - update struct to indicate inside function */
270
+ while ((line = readVimLine ()) != NULL)
271
+ {
272
+ /*
273
+ * Vim7 added the for/endfo[r] construct, so we must first
274
+ * check for an "endfo", before a "endf"
275
+ */
276
+ if ( (!strncmp ((const char*) line, "endfo", (size_t) 5) == 0) &&
277
+ (strncmp ((const char*) line, "endf", (size_t) 4) == 0) )
278
+ break;
279
+ /* TODO - call parseVimLine */
280
+ }
281
+ vStringDelete (name);
282
+ }
283
+
284
+ static void parseAutogroup (const unsigned char *line)
285
+ {
286
+ vString *name = vStringNew ();
287
+
288
+ /* Found Autocommand Group (augroup) */
289
+ const unsigned char *cp = line + 2;
290
+ if ((int) *++cp == 'r' && (int) *++cp == 'o' &&
291
+ (int) *++cp == 'u' && (int) *++cp == 'p')
292
+ ++cp;
293
+ if (isspace ((int) *cp))
294
+ {
295
+ while (*cp && isspace ((int) *cp))
296
+ ++cp;
297
+
298
+ if (*cp)
299
+ {
300
+ if (strncasecmp ((const char*) cp, "end", (size_t) 3) != 0)
301
+ {
302
+ do
303
+ {
304
+ vStringPut (name, (int) *cp);
305
+ ++cp;
306
+ } while (isalnum ((int) *cp) || *cp == '_');
307
+ vStringTerminate (name);
308
+ makeSimpleTag (name, VimKinds, K_AUGROUP);
309
+ vStringClear (name);
310
+ }
311
+ }
312
+ }
313
+ vStringDelete (name);
314
+ }
315
+
316
+ static boolean parseCommand (const unsigned char *line)
317
+ {
318
+ vString *name = vStringNew ();
319
+ boolean cmdProcessed = TRUE;
320
+
321
+ /*
322
+ * Found a user-defined command
323
+ *
324
+ * They can have many options preceeded by a dash
325
+ * command! -nargs=+ -complete Select :call s:DB_execSql("select " . <q-args>)
326
+ * The name of the command should be the first word not preceeded by a dash
327
+ *
328
+ */
329
+ const unsigned char *cp = line;
330
+
331
+ if ( (int) *cp == '\\' )
332
+ {
333
+ /*
334
+ * We are recursively calling this function is the command
335
+ * has been continued on to the next line
336
+ *
337
+ * Vim statements can be continued onto a newline using a \
338
+ * to indicate the previous line is continuing.
339
+ *
340
+ * com -nargs=1 -bang -complete=customlist,EditFileComplete
341
+ * \ EditFile edit<bang> <args>
342
+ *
343
+ * If the following lines do not have a line continuation
344
+ * the command must not be spanning multiple lines and should
345
+ * be synatically incorrect.
346
+ */
347
+ if ((int) *cp == '\\')
348
+ ++cp;
349
+
350
+ while (*cp && isspace ((int) *cp))
351
+ ++cp;
352
+ }
353
+ else if ( (!strncmp ((const char*) line, "comp", (size_t) 4) == 0) &&
354
+ (!strncmp ((const char*) line, "comc", (size_t) 4) == 0) &&
355
+ (strncmp ((const char*) line, "com", (size_t) 3) == 0) )
356
+ {
357
+ cp += 2;
358
+ if ((int) *++cp == 'm' && (int) *++cp == 'a' &&
359
+ (int) *++cp == 'n' && (int) *++cp == 'd')
360
+ ++cp;
361
+
362
+ if ((int) *cp == '!')
363
+ ++cp;
364
+
365
+ while (*cp && isspace ((int) *cp))
366
+ ++cp;
367
+ }
368
+ else
369
+ {
370
+ /*
371
+ * We are recursively calling this function. If it does not start
372
+ * with "com" or a line continuation character, we have moved off
373
+ * the command line and should let the other routines parse this file.
374
+ */
375
+ cmdProcessed = FALSE;
376
+ goto cleanUp;
377
+ }
378
+
379
+ /*
380
+ * Strip off any spaces and options which are part of the command.
381
+ * These should preceed the command name.
382
+ */
383
+ do
384
+ {
385
+ if (isspace ((int) *cp))
386
+ {
387
+ ++cp;
388
+ }
389
+ else if (*cp == '-')
390
+ {
391
+ /*
392
+ * Read until the next space which sparates options or the name
393
+ */
394
+ while (*cp && !isspace ((int) *cp))
395
+ ++cp;
396
+ }
397
+ } while ( *cp && !isalnum ((int) *cp) );
398
+
399
+ if ( ! *cp )
400
+ {
401
+ /*
402
+ * We have reached the end of the line without finding the command name.
403
+ * Read the next line and continue processing it as a command.
404
+ */
405
+ line = readVimLine();
406
+ parseCommand(line);
407
+ goto cleanUp;
408
+ }
409
+
410
+ do
411
+ {
412
+ vStringPut (name, (int) *cp);
413
+ ++cp;
414
+ } while (isalnum ((int) *cp) || *cp == '_');
415
+
416
+ vStringTerminate (name);
417
+ makeSimpleTag (name, VimKinds, K_COMMAND);
418
+ vStringClear (name);
419
+
420
+ cleanUp:
421
+ vStringDelete (name);
422
+
423
+ return cmdProcessed;
424
+ }
425
+
426
+ static void parseLet (const unsigned char *line)
427
+ {
428
+ vString *name = vStringNew ();
429
+
430
+ /* we've found a variable declared outside of a function!! */
431
+ const unsigned char *cp = line + 3;
432
+ const unsigned char *np = line;
433
+ /* get the name */
434
+ if (isspace ((int) *cp))
435
+ {
436
+ while (*cp && isspace ((int) *cp))
437
+ ++cp;
438
+
439
+ /*
440
+ * Ignore lets which set:
441
+ * & - local buffer vim settings
442
+ * @ - registers
443
+ * [ - Lists or Dictionaries
444
+ */
445
+ if (!*cp || *cp == '&' || *cp == '@' || *cp == '[' )
446
+ goto cleanUp;
447
+
448
+ /*
449
+ * Ignore vim variables which are read only
450
+ * v: - Vim variables.
451
+ */
452
+ np = cp;
453
+ ++np;
454
+ if ((int) *cp == 'v' && (int) *np == ':' )
455
+ goto cleanUp;
456
+
457
+ /* deal with spaces, $, @ and & */
458
+ while (*cp && *cp != '$' && !isalnum ((int) *cp))
459
+ ++cp;
460
+
461
+ if (!*cp)
462
+ goto cleanUp;
463
+
464
+ /* cp = skipPrefix (cp, &scope); */
465
+ do
466
+ {
467
+ if (!*cp)
468
+ break;
469
+
470
+ vStringPut (name, (int) *cp);
471
+ ++cp;
472
+ } while (isalnum ((int) *cp) || *cp == '_' || *cp == '#' || *cp == ':' || *cp == '$');
473
+ vStringTerminate (name);
474
+ makeSimpleTag (name, VimKinds, K_VARIABLE);
475
+ vStringClear (name);
476
+ }
477
+
478
+ cleanUp:
479
+ vStringDelete (name);
480
+ }
481
+
482
+ static boolean parseMap (const unsigned char *line)
483
+ {
484
+ vString *name = vStringNew ();
485
+
486
+ const unsigned char *cp = line;
487
+
488
+ /* Remove map */
489
+ while (*cp && isalnum ((int) *cp))
490
+ ++cp;
491
+
492
+ if ((int) *cp == '!')
493
+ ++cp;
494
+
495
+ /*
496
+ * Maps follow this basic format
497
+ * map
498
+ * nnoremap <silent> <F8> :Tlist<CR>
499
+ * map <unique> <Leader>scdt <Plug>GetColumnDataType
500
+ * inoremap ,,, <esc>diwi<<esc>pa><cr></<esc>pa><esc>kA
501
+ * inoremap <buffer> ( <C-R>=PreviewFunctionSignature()<LF>
502
+ *
503
+ * The Vim help shows the various special arguments available to a map:
504
+ * 1.2 SPECIAL ARGUMENTS *:map-arguments*
505
+ * <buffer>
506
+ * <silent>
507
+ * <script>
508
+ * <unique>
509
+ * <special>
510
+ * <expr>
511
+ *
512
+ * Strip the special arguments from the map command, this should leave
513
+ * the map name which we will use as the "name".
514
+ */
515
+
516
+ do
517
+ {
518
+ while (*cp && isspace ((int) *cp))
519
+ ++cp;
520
+
521
+ if (strncmp ((const char*) cp, "<Leader>", (size_t) 8) == 0)
522
+ break;
523
+
524
+ if (
525
+ strncmp ((const char*) cp, "<buffer>", (size_t) 8) == 0 ||
526
+ strncmp ((const char*) cp, "<silent>", (size_t) 8) == 0 ||
527
+ strncmp ((const char*) cp, "<script>", (size_t) 8) == 0 ||
528
+ strncmp ((const char*) cp, "<unique>", (size_t) 8) == 0
529
+ )
530
+ {
531
+ cp += 8;
532
+ continue;
533
+ }
534
+
535
+ if (strncmp ((const char*) cp, "<expr>", (size_t) 6) == 0)
536
+ {
537
+ cp += 6;
538
+ continue;
539
+ }
540
+
541
+ if (strncmp ((const char*) cp, "<special>", (size_t) 9) == 0)
542
+ {
543
+ cp += 9;
544
+ continue;
545
+ }
546
+
547
+ break;
548
+ } while (*cp);
549
+
550
+ do
551
+ {
552
+ vStringPut (name, (int) *cp);
553
+ ++cp;
554
+ } while (*cp && *cp != ' ');
555
+
556
+ vStringTerminate (name);
557
+ makeSimpleTag (name, VimKinds, K_MAP);
558
+ vStringClear (name);
559
+
560
+ vStringDelete (name);
561
+
562
+ return TRUE;
563
+ }
564
+
565
+ static boolean parseVimLine (const unsigned char *line)
566
+ {
567
+ boolean readNextLine = TRUE;
568
+
569
+ if ( (!strncmp ((const char*) line, "comp", (size_t) 4) == 0) &&
570
+ (!strncmp ((const char*) line, "comc", (size_t) 4) == 0) &&
571
+ (strncmp ((const char*) line, "com", (size_t) 3) == 0) )
572
+ {
573
+ readNextLine = parseCommand(line);
574
+ /* TODO - Handle parseCommand returning FALSE */
575
+ }
576
+
577
+ if (isMap(line))
578
+ {
579
+ parseMap(line);
580
+ }
581
+
582
+ if (strncmp ((const char*) line, "fu", (size_t) 2) == 0)
583
+ {
584
+ parseFunction(line);
585
+ }
586
+
587
+ if (strncmp ((const char*) line, "aug", (size_t) 3) == 0)
588
+ {
589
+ parseAutogroup(line);
590
+ }
591
+
592
+ if ( strncmp ((const char*) line, "let", (size_t) 3) == 0 )
593
+ {
594
+ parseLet(line);
595
+ }
596
+
597
+ return readNextLine;
598
+ }
599
+
600
+ static void parseVimFile (const unsigned char *line)
601
+ {
602
+ boolean readNextLine = TRUE;
603
+ line = readVimLine();
604
+
605
+ while (line != NULL)
606
+ {
607
+ readNextLine = parseVimLine(line);
608
+
609
+ if ( readNextLine )
610
+ line = readVimLine();
611
+
612
+ }
613
+ }
614
+
615
+ static void findVimTags (void)
616
+ {
617
+ const unsigned char *line;
618
+ /* TODO - change this into a structure */
619
+
620
+ line = '\0';
621
+
622
+ parseVimFile (line);
623
+ }
624
+
625
+ extern parserDefinition* VimParser (void)
626
+ {
627
+ static const char *const extensions [] = { "vim", NULL };
628
+ parserDefinition* def = parserNew ("Vim");
629
+ def->kinds = VimKinds;
630
+ def->kindCount = KIND_COUNT (VimKinds);
631
+ def->extensions = extensions;
632
+ def->parser = findVimTags;
633
+ return def;
634
+ }
635
+
636
+ /* vi:set tabstop=4 shiftwidth=4 noexpandtab: */