ctags.rb 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +2 -0
- data/Rakefile +23 -0
- data/ctags.rb.gemspec +23 -0
- data/ext/.gitignore +3 -0
- data/ext/extconf.rb +15 -0
- data/ext/vendor/exuberant-ctags/.gitignore +6 -0
- data/ext/vendor/exuberant-ctags/.indent.pro +31 -0
- data/ext/vendor/exuberant-ctags/COPYING +340 -0
- data/ext/vendor/exuberant-ctags/EXTENDING.html +386 -0
- data/ext/vendor/exuberant-ctags/FAQ +371 -0
- data/ext/vendor/exuberant-ctags/INSTALL +215 -0
- data/ext/vendor/exuberant-ctags/INSTALL.oth +73 -0
- data/ext/vendor/exuberant-ctags/MAINTAINERS +88 -0
- data/ext/vendor/exuberant-ctags/Makefile.in +222 -0
- data/ext/vendor/exuberant-ctags/NEWS +871 -0
- data/ext/vendor/exuberant-ctags/README +73 -0
- data/ext/vendor/exuberant-ctags/ant.c +42 -0
- data/ext/vendor/exuberant-ctags/argproc.c +505 -0
- data/ext/vendor/exuberant-ctags/args.c +274 -0
- data/ext/vendor/exuberant-ctags/args.h +63 -0
- data/ext/vendor/exuberant-ctags/asm.c +387 -0
- data/ext/vendor/exuberant-ctags/asp.c +328 -0
- data/ext/vendor/exuberant-ctags/awk.c +81 -0
- data/ext/vendor/exuberant-ctags/basic.c +203 -0
- data/ext/vendor/exuberant-ctags/beta.c +321 -0
- data/ext/vendor/exuberant-ctags/c.c +2932 -0
- data/ext/vendor/exuberant-ctags/cobol.c +50 -0
- data/ext/vendor/exuberant-ctags/config.h.in +277 -0
- data/ext/vendor/exuberant-ctags/configure +7704 -0
- data/ext/vendor/exuberant-ctags/configure.ac +532 -0
- data/ext/vendor/exuberant-ctags/ctags.1 +1186 -0
- data/ext/vendor/exuberant-ctags/ctags.h +28 -0
- data/ext/vendor/exuberant-ctags/ctags.html +2087 -0
- data/ext/vendor/exuberant-ctags/ctags.spec +40 -0
- data/ext/vendor/exuberant-ctags/debug.c +113 -0
- data/ext/vendor/exuberant-ctags/debug.h +70 -0
- data/ext/vendor/exuberant-ctags/descrip.mms +68 -0
- data/ext/vendor/exuberant-ctags/dosbatch.c +42 -0
- data/ext/vendor/exuberant-ctags/e_amiga.h +24 -0
- data/ext/vendor/exuberant-ctags/e_djgpp.h +47 -0
- data/ext/vendor/exuberant-ctags/e_mac.h +143 -0
- data/ext/vendor/exuberant-ctags/e_msoft.h +76 -0
- data/ext/vendor/exuberant-ctags/e_os2.h +37 -0
- data/ext/vendor/exuberant-ctags/e_qdos.h +34 -0
- data/ext/vendor/exuberant-ctags/e_riscos.h +58 -0
- data/ext/vendor/exuberant-ctags/e_vms.h +31 -0
- data/ext/vendor/exuberant-ctags/eiffel.c +1352 -0
- data/ext/vendor/exuberant-ctags/entry.c +847 -0
- data/ext/vendor/exuberant-ctags/entry.h +103 -0
- data/ext/vendor/exuberant-ctags/erlang.c +189 -0
- data/ext/vendor/exuberant-ctags/flex.c +2243 -0
- data/ext/vendor/exuberant-ctags/fortran.c +2197 -0
- data/ext/vendor/exuberant-ctags/general.h +127 -0
- data/ext/vendor/exuberant-ctags/get.c +669 -0
- data/ext/vendor/exuberant-ctags/get.h +50 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/all-wcprops +47 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/entries +112 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/README.txt.svn-base +5 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regcomp.c.svn-base +3818 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex.c.svn-base +74 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex.h.svn-base +575 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex_internal.c.svn-base +1713 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex_internal.h.svn-base +773 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regexec.c.svn-base +4338 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/README.txt +5 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/regcomp.c +3818 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/regex.c +74 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/regex.h +575 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/regex_internal.c +1713 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/regex_internal.h +773 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/regexec.c +4338 -0
- data/ext/vendor/exuberant-ctags/html.c +49 -0
- data/ext/vendor/exuberant-ctags/jscript.c +1572 -0
- data/ext/vendor/exuberant-ctags/keyword.c +258 -0
- data/ext/vendor/exuberant-ctags/keyword.h +34 -0
- data/ext/vendor/exuberant-ctags/lisp.c +139 -0
- data/ext/vendor/exuberant-ctags/lregex.c +704 -0
- data/ext/vendor/exuberant-ctags/lua.c +133 -0
- data/ext/vendor/exuberant-ctags/mac.c +273 -0
- data/ext/vendor/exuberant-ctags/magic.diff +21 -0
- data/ext/vendor/exuberant-ctags/main.c +584 -0
- data/ext/vendor/exuberant-ctags/main.h +32 -0
- data/ext/vendor/exuberant-ctags/maintainer.mak +476 -0
- data/ext/vendor/exuberant-ctags/make.c +217 -0
- data/ext/vendor/exuberant-ctags/matlab.c +44 -0
- data/ext/vendor/exuberant-ctags/mk_bc3.mak +46 -0
- data/ext/vendor/exuberant-ctags/mk_bc5.mak +49 -0
- data/ext/vendor/exuberant-ctags/mk_djg.mak +18 -0
- data/ext/vendor/exuberant-ctags/mk_manx.mak +65 -0
- data/ext/vendor/exuberant-ctags/mk_mingw.mak +31 -0
- data/ext/vendor/exuberant-ctags/mk_mpw.mak +130 -0
- data/ext/vendor/exuberant-ctags/mk_mvc.mak +40 -0
- data/ext/vendor/exuberant-ctags/mk_os2.mak +104 -0
- data/ext/vendor/exuberant-ctags/mk_qdos.mak +100 -0
- data/ext/vendor/exuberant-ctags/mk_sas.mak +63 -0
- data/ext/vendor/exuberant-ctags/mkinstalldirs +40 -0
- data/ext/vendor/exuberant-ctags/ocaml.c +1842 -0
- data/ext/vendor/exuberant-ctags/options.c +1842 -0
- data/ext/vendor/exuberant-ctags/options.h +155 -0
- data/ext/vendor/exuberant-ctags/parse.c +677 -0
- data/ext/vendor/exuberant-ctags/parse.h +129 -0
- data/ext/vendor/exuberant-ctags/parsers.h +63 -0
- data/ext/vendor/exuberant-ctags/pascal.c +267 -0
- data/ext/vendor/exuberant-ctags/perl.c +382 -0
- data/ext/vendor/exuberant-ctags/php.c +237 -0
- data/ext/vendor/exuberant-ctags/python.c +771 -0
- data/ext/vendor/exuberant-ctags/qdos.c +106 -0
- data/ext/vendor/exuberant-ctags/read.c +569 -0
- data/ext/vendor/exuberant-ctags/read.h +116 -0
- data/ext/vendor/exuberant-ctags/readtags.c +959 -0
- data/ext/vendor/exuberant-ctags/readtags.h +252 -0
- data/ext/vendor/exuberant-ctags/rexx.c +39 -0
- data/ext/vendor/exuberant-ctags/routines.c +891 -0
- data/ext/vendor/exuberant-ctags/routines.h +134 -0
- data/ext/vendor/exuberant-ctags/ruby.c +408 -0
- data/ext/vendor/exuberant-ctags/scheme.c +111 -0
- data/ext/vendor/exuberant-ctags/sh.c +115 -0
- data/ext/vendor/exuberant-ctags/slang.c +41 -0
- data/ext/vendor/exuberant-ctags/sml.c +212 -0
- data/ext/vendor/exuberant-ctags/sort.c +230 -0
- data/ext/vendor/exuberant-ctags/sort.h +32 -0
- data/ext/vendor/exuberant-ctags/source.mak +122 -0
- data/ext/vendor/exuberant-ctags/sql.c +2112 -0
- data/ext/vendor/exuberant-ctags/strlist.c +281 -0
- data/ext/vendor/exuberant-ctags/strlist.h +54 -0
- data/ext/vendor/exuberant-ctags/tcl.c +116 -0
- data/ext/vendor/exuberant-ctags/tex.c +524 -0
- data/ext/vendor/exuberant-ctags/verilog.c +340 -0
- data/ext/vendor/exuberant-ctags/vhdl.c +835 -0
- data/ext/vendor/exuberant-ctags/vim.c +636 -0
- data/ext/vendor/exuberant-ctags/vstring.c +232 -0
- data/ext/vendor/exuberant-ctags/vstring.h +85 -0
- data/ext/vendor/exuberant-ctags/yacc.c +40 -0
- data/lib/ctags/exuberant.rb +45 -0
- data/lib/ctags/version.rb +3 -0
- data/lib/ctags.rb +6 -0
- data/test/test_ctags.rb +24 -0
- metadata +233 -0
|
@@ -0,0 +1,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: */
|