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,524 @@
1
+ /*
2
+ * $Id: tex.c 666 2008-05-15 17:47:31Z dfishburn $
3
+ *
4
+ * Copyright (c) 2008, David Fishburn
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 TeX language files.
10
+ *
11
+ * Tex language reference:
12
+ * http://en.wikibooks.org/wiki/TeX#The_Structure_of_TeX
13
+ */
14
+
15
+ /*
16
+ * INCLUDE FILES
17
+ */
18
+ #include "general.h" /* must always come first */
19
+ #include <ctype.h> /* to define isalpha () */
20
+ #include <setjmp.h>
21
+ #ifdef DEBUG
22
+ #include <stdio.h>
23
+ #endif
24
+
25
+ #include "debug.h"
26
+ #include "entry.h"
27
+ #include "keyword.h"
28
+ #include "parse.h"
29
+ #include "read.h"
30
+ #include "routines.h"
31
+ #include "vstring.h"
32
+
33
+ /*
34
+ * MACROS
35
+ */
36
+ #define isType(token,t) (boolean) ((token)->type == (t))
37
+ #define isKeyword(token,k) (boolean) ((token)->keyword == (k))
38
+
39
+ /*
40
+ * DATA DECLARATIONS
41
+ */
42
+
43
+ typedef enum eException { ExceptionNone, ExceptionEOF } exception_t;
44
+
45
+ /*
46
+ * Used to specify type of keyword.
47
+ */
48
+ typedef enum eKeywordId {
49
+ KEYWORD_NONE = -1,
50
+ KEYWORD_chapter,
51
+ KEYWORD_section,
52
+ KEYWORD_subsection,
53
+ KEYWORD_subsubsection,
54
+ KEYWORD_part,
55
+ KEYWORD_paragraph,
56
+ KEYWORD_subparagraph
57
+ } keywordId;
58
+
59
+ /* Used to determine whether keyword is valid for the token language and
60
+ * what its ID is.
61
+ */
62
+ typedef struct sKeywordDesc {
63
+ const char *name;
64
+ keywordId id;
65
+ } keywordDesc;
66
+
67
+ typedef enum eTokenType {
68
+ TOKEN_UNDEFINED,
69
+ TOKEN_CHARACTER,
70
+ TOKEN_CLOSE_PAREN,
71
+ TOKEN_SEMICOLON,
72
+ TOKEN_COLON,
73
+ TOKEN_COMMA,
74
+ TOKEN_KEYWORD,
75
+ TOKEN_OPEN_PAREN,
76
+ TOKEN_OPERATOR,
77
+ TOKEN_IDENTIFIER,
78
+ TOKEN_STRING,
79
+ TOKEN_PERIOD,
80
+ TOKEN_OPEN_CURLY,
81
+ TOKEN_CLOSE_CURLY,
82
+ TOKEN_EQUAL_SIGN,
83
+ TOKEN_EXCLAMATION,
84
+ TOKEN_FORWARD_SLASH,
85
+ TOKEN_OPEN_SQUARE,
86
+ TOKEN_CLOSE_SQUARE,
87
+ TOKEN_OPEN_MXML,
88
+ TOKEN_CLOSE_MXML,
89
+ TOKEN_CLOSE_SGML,
90
+ TOKEN_LESS_THAN,
91
+ TOKEN_GREATER_THAN,
92
+ TOKEN_QUESTION_MARK,
93
+ TOKEN_STAR
94
+ } tokenType;
95
+
96
+ typedef struct sTokenInfo {
97
+ tokenType type;
98
+ keywordId keyword;
99
+ vString * string;
100
+ vString * scope;
101
+ unsigned long lineNumber;
102
+ fpos_t filePosition;
103
+ } tokenInfo;
104
+
105
+ /*
106
+ * DATA DEFINITIONS
107
+ */
108
+
109
+ static langType Lang_js;
110
+
111
+ static jmp_buf Exception;
112
+
113
+ typedef enum {
114
+ TEXTAG_CHAPTER,
115
+ TEXTAG_SECTION,
116
+ TEXTAG_SUBSECTION,
117
+ TEXTAG_SUBSUBSECTION,
118
+ TEXTAG_PART,
119
+ TEXTAG_PARAGRAPH,
120
+ TEXTAG_SUBPARAGRAPH,
121
+ TEXTAG_COUNT
122
+ } texKind;
123
+
124
+ static kindOption TexKinds [] = {
125
+ { TRUE, 'c', "chapter", "chapters" },
126
+ { TRUE, 's', "section", "sections" },
127
+ { TRUE, 'u', "subsection", "subsections" },
128
+ { TRUE, 'b', "subsubsection", "subsubsections" },
129
+ { TRUE, 'p', "part", "parts" },
130
+ { TRUE, 'P', "paragraph", "paragraphs" },
131
+ { TRUE, 'G', "subparagraph", "subparagraphs" }
132
+ };
133
+
134
+ static const keywordDesc TexKeywordTable [] = {
135
+ /* keyword keyword ID */
136
+ { "chapter", KEYWORD_chapter },
137
+ { "section", KEYWORD_section },
138
+ { "subsection", KEYWORD_subsection },
139
+ { "subsubsection", KEYWORD_subsubsection },
140
+ { "part", KEYWORD_part },
141
+ { "paragraph", KEYWORD_paragraph },
142
+ { "subparagraph", KEYWORD_subparagraph }
143
+ };
144
+
145
+ /*
146
+ * FUNCTION DEFINITIONS
147
+ */
148
+
149
+ static boolean isIdentChar (const int c)
150
+ {
151
+ return (boolean)
152
+ (isalpha (c) || isdigit (c) || c == '$' ||
153
+ c == '_' || c == '#');
154
+ }
155
+
156
+ static void buildTexKeywordHash (void)
157
+ {
158
+ const size_t count = sizeof (TexKeywordTable) /
159
+ sizeof (TexKeywordTable [0]);
160
+ size_t i;
161
+ for (i = 0 ; i < count ; ++i)
162
+ {
163
+ const keywordDesc* const p = &TexKeywordTable [i];
164
+ addKeyword (p->name, Lang_js, (int) p->id);
165
+ }
166
+ }
167
+
168
+ static tokenInfo *newToken (void)
169
+ {
170
+ tokenInfo *const token = xMalloc (1, tokenInfo);
171
+
172
+ token->type = TOKEN_UNDEFINED;
173
+ token->keyword = KEYWORD_NONE;
174
+ token->string = vStringNew ();
175
+ token->scope = vStringNew ();
176
+ token->lineNumber = getSourceLineNumber ();
177
+ token->filePosition = getInputFilePosition ();
178
+
179
+ return token;
180
+ }
181
+
182
+ static void deleteToken (tokenInfo *const token)
183
+ {
184
+ vStringDelete (token->string);
185
+ vStringDelete (token->scope);
186
+ eFree (token);
187
+ }
188
+
189
+ /*
190
+ * Tag generation functions
191
+ */
192
+
193
+ static void makeConstTag (tokenInfo *const token, const texKind kind)
194
+ {
195
+ if (TexKinds [kind].enabled )
196
+ {
197
+ const char *const name = vStringValue (token->string);
198
+ tagEntryInfo e;
199
+ initTagEntry (&e, name);
200
+
201
+ e.lineNumber = token->lineNumber;
202
+ e.filePosition = token->filePosition;
203
+ e.kindName = TexKinds [kind].name;
204
+ e.kind = TexKinds [kind].letter;
205
+
206
+ makeTagEntry (&e);
207
+ }
208
+ }
209
+
210
+ static void makeTexTag (tokenInfo *const token, texKind kind)
211
+ {
212
+ vString * fulltag;
213
+
214
+ if (TexKinds [kind].enabled)
215
+ {
216
+ /*
217
+ * If a scope has been added to the token, change the token
218
+ * string to include the scope when making the tag.
219
+ */
220
+ if ( vStringLength (token->scope) > 0 )
221
+ {
222
+ fulltag = vStringNew ();
223
+ vStringCopy (fulltag, token->scope);
224
+ vStringCatS (fulltag, ".");
225
+ vStringCatS (fulltag, vStringValue (token->string));
226
+ vStringTerminate (fulltag);
227
+ vStringCopy (token->string, fulltag);
228
+ vStringDelete (fulltag);
229
+ }
230
+ makeConstTag (token, kind);
231
+ }
232
+ }
233
+
234
+ /*
235
+ * Parsing functions
236
+ */
237
+
238
+ static void parseString (vString *const string, const int delimiter)
239
+ {
240
+ boolean end = FALSE;
241
+ while (! end)
242
+ {
243
+ int c = fileGetc ();
244
+ if (c == EOF)
245
+ end = TRUE;
246
+ else if (c == '\\')
247
+ {
248
+ c = fileGetc(); /* This maybe a ' or ". */
249
+ vStringPut (string, c);
250
+ }
251
+ else if (c == delimiter)
252
+ end = TRUE;
253
+ else
254
+ vStringPut (string, c);
255
+ }
256
+ vStringTerminate (string);
257
+ }
258
+
259
+ /*
260
+ * Read a C identifier beginning with "firstChar" and places it into
261
+ * "name".
262
+ */
263
+ static void parseIdentifier (vString *const string, const int firstChar)
264
+ {
265
+ int c = firstChar;
266
+ Assert (isIdentChar (c));
267
+ do
268
+ {
269
+ vStringPut (string, c);
270
+ c = fileGetc ();
271
+ } while (isIdentChar (c));
272
+
273
+ vStringTerminate (string);
274
+ if (!isspace (c))
275
+ fileUngetc (c); /* unget non-identifier character */
276
+ }
277
+
278
+ static void readToken (tokenInfo *const token)
279
+ {
280
+ int c;
281
+
282
+ token->type = TOKEN_UNDEFINED;
283
+ token->keyword = KEYWORD_NONE;
284
+ vStringClear (token->string);
285
+
286
+ getNextChar:
287
+ do
288
+ {
289
+ c = fileGetc ();
290
+ token->lineNumber = getSourceLineNumber ();
291
+ token->filePosition = getInputFilePosition ();
292
+ }
293
+ while (c == '\t' || c == ' ' || c == '\n');
294
+
295
+ switch (c)
296
+ {
297
+ case EOF: longjmp (Exception, (int)ExceptionEOF); break;
298
+ case '(': token->type = TOKEN_OPEN_PAREN; break;
299
+ case ')': token->type = TOKEN_CLOSE_PAREN; break;
300
+ case ';': token->type = TOKEN_SEMICOLON; break;
301
+ case ',': token->type = TOKEN_COMMA; break;
302
+ case '.': token->type = TOKEN_PERIOD; break;
303
+ case ':': token->type = TOKEN_COLON; break;
304
+ case '{': token->type = TOKEN_OPEN_CURLY; break;
305
+ case '}': token->type = TOKEN_CLOSE_CURLY; break;
306
+ case '=': token->type = TOKEN_EQUAL_SIGN; break;
307
+ case '[': token->type = TOKEN_OPEN_SQUARE; break;
308
+ case ']': token->type = TOKEN_CLOSE_SQUARE; break;
309
+ case '?': token->type = TOKEN_QUESTION_MARK; break;
310
+ case '*': token->type = TOKEN_STAR; break;
311
+
312
+ case '\'':
313
+ case '"':
314
+ token->type = TOKEN_STRING;
315
+ parseString (token->string, c);
316
+ token->lineNumber = getSourceLineNumber ();
317
+ token->filePosition = getInputFilePosition ();
318
+ break;
319
+
320
+ case '\\':
321
+ /*
322
+ * All Tex tags start with a backslash.
323
+ * Check if the next character is an alpha character
324
+ * else it is not a potential tex tag.
325
+ */
326
+ c = fileGetc ();
327
+ if (! isalpha (c))
328
+ fileUngetc (c);
329
+ else
330
+ {
331
+ parseIdentifier (token->string, c);
332
+ token->lineNumber = getSourceLineNumber ();
333
+ token->filePosition = getInputFilePosition ();
334
+ token->keyword = analyzeToken (token->string, Lang_js);
335
+ if (isKeyword (token, KEYWORD_NONE))
336
+ token->type = TOKEN_IDENTIFIER;
337
+ else
338
+ token->type = TOKEN_KEYWORD;
339
+ }
340
+ break;
341
+
342
+ case '%':
343
+ fileSkipToCharacter ('\n'); /* % are single line comments */
344
+ goto getNextChar;
345
+ break;
346
+
347
+ default:
348
+ if (! isIdentChar (c))
349
+ token->type = TOKEN_UNDEFINED;
350
+ else
351
+ {
352
+ parseIdentifier (token->string, c);
353
+ token->lineNumber = getSourceLineNumber ();
354
+ token->filePosition = getInputFilePosition ();
355
+ token->type = TOKEN_IDENTIFIER;
356
+ }
357
+ break;
358
+ }
359
+ }
360
+
361
+ static void copyToken (tokenInfo *const dest, tokenInfo *const src)
362
+ {
363
+ dest->lineNumber = src->lineNumber;
364
+ dest->filePosition = src->filePosition;
365
+ dest->type = src->type;
366
+ dest->keyword = src->keyword;
367
+ vStringCopy (dest->string, src->string);
368
+ vStringCopy (dest->scope, src->scope);
369
+ }
370
+
371
+ /*
372
+ * Scanning functions
373
+ */
374
+
375
+ static boolean parseTag (tokenInfo *const token, texKind kind)
376
+ {
377
+ tokenInfo *const name = newToken ();
378
+ vString * fullname;
379
+ boolean useLongName = TRUE;
380
+
381
+ fullname = vStringNew ();
382
+ vStringClear (fullname);
383
+
384
+ /*
385
+ * Tex tags are of these formats:
386
+ * \keyword{any number of words}
387
+ * \keyword[short desc]{any number of words}
388
+ * \keyword*[short desc]{any number of words}
389
+ *
390
+ * When a keyword is found, loop through all words within
391
+ * the curly braces for the tag name.
392
+ */
393
+
394
+ if (isType (token, TOKEN_KEYWORD))
395
+ {
396
+ copyToken (name, token);
397
+ readToken (token);
398
+ }
399
+
400
+ if (isType (token, TOKEN_OPEN_SQUARE))
401
+ {
402
+ useLongName = FALSE;
403
+
404
+ readToken (token);
405
+ while (! isType (token, TOKEN_CLOSE_SQUARE) )
406
+ {
407
+ if (isType (token, TOKEN_IDENTIFIER))
408
+ {
409
+ if (fullname->length > 0)
410
+ vStringCatS (fullname, " ");
411
+ vStringCatS (fullname, vStringValue (token->string));
412
+ }
413
+ readToken (token);
414
+ }
415
+ vStringTerminate (fullname);
416
+ vStringCopy (name->string, fullname);
417
+ makeTexTag (name, kind);
418
+ }
419
+
420
+ if (isType (token, TOKEN_STAR))
421
+ {
422
+ readToken (token);
423
+ }
424
+
425
+ if (isType (token, TOKEN_OPEN_CURLY))
426
+ {
427
+ readToken (token);
428
+ while (! isType (token, TOKEN_CLOSE_CURLY) )
429
+ {
430
+ if (isType (token, TOKEN_IDENTIFIER) && useLongName)
431
+ {
432
+ if (fullname->length > 0)
433
+ vStringCatS (fullname, " ");
434
+ vStringCatS (fullname, vStringValue (token->string));
435
+ }
436
+ readToken (token);
437
+ }
438
+ if (useLongName)
439
+ {
440
+ vStringTerminate (fullname);
441
+ vStringCopy (name->string, fullname);
442
+ makeTexTag (name, kind);
443
+ }
444
+ }
445
+
446
+ deleteToken (name);
447
+ vStringDelete (fullname);
448
+ return TRUE;
449
+ }
450
+
451
+ static void parseTexFile (tokenInfo *const token)
452
+ {
453
+ do
454
+ {
455
+ readToken (token);
456
+
457
+ if (isType (token, TOKEN_KEYWORD))
458
+ {
459
+ switch (token->keyword)
460
+ {
461
+ case KEYWORD_chapter:
462
+ parseTag (token, TEXTAG_CHAPTER);
463
+ break;
464
+ case KEYWORD_section:
465
+ parseTag (token, TEXTAG_SECTION);
466
+ break;
467
+ case KEYWORD_subsection:
468
+ parseTag (token, TEXTAG_SUBSUBSECTION);
469
+ break;
470
+ case KEYWORD_subsubsection:
471
+ parseTag (token, TEXTAG_SUBSUBSECTION);
472
+ break;
473
+ case KEYWORD_part:
474
+ parseTag (token, TEXTAG_PART);
475
+ break;
476
+ case KEYWORD_paragraph:
477
+ parseTag (token, TEXTAG_PARAGRAPH);
478
+ break;
479
+ case KEYWORD_subparagraph:
480
+ parseTag (token, TEXTAG_SUBPARAGRAPH);
481
+ break;
482
+ default:
483
+ break;
484
+ }
485
+ }
486
+ } while (TRUE);
487
+ }
488
+
489
+ static void initialize (const langType language)
490
+ {
491
+ Assert (sizeof (TexKinds) / sizeof (TexKinds [0]) == TEXTAG_COUNT);
492
+ Lang_js = language;
493
+ buildTexKeywordHash ();
494
+ }
495
+
496
+ static void findTexTags (void)
497
+ {
498
+ tokenInfo *const token = newToken ();
499
+ exception_t exception;
500
+
501
+ exception = (exception_t) (setjmp (Exception));
502
+ while (exception == ExceptionNone)
503
+ parseTexFile (token);
504
+
505
+ deleteToken (token);
506
+ }
507
+
508
+ /* Create parser definition stucture */
509
+ extern parserDefinition* TexParser (void)
510
+ {
511
+ static const char *const extensions [] = { "tex", NULL };
512
+ parserDefinition *const def = parserNew ("Tex");
513
+ def->extensions = extensions;
514
+ /*
515
+ * New definitions for parsing instead of regex
516
+ */
517
+ def->kinds = TexKinds;
518
+ def->kindCount = KIND_COUNT (TexKinds);
519
+ def->parser = findTexTags;
520
+ def->initialize = initialize;
521
+
522
+ return def;
523
+ }
524
+ /* vi:set tabstop=4 shiftwidth=4 noexpandtab: */