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,669 @@
1
+ /*
2
+ * $Id: get.c 559 2007-06-17 03:30:09Z elliotth $
3
+ *
4
+ * Copyright (c) 1996-2002, 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 the high level source read functions (preprocessor
10
+ * directives are handled within this level).
11
+ */
12
+
13
+ /*
14
+ * INCLUDE FILES
15
+ */
16
+ #include "general.h" /* must always come first */
17
+
18
+ #include <string.h>
19
+
20
+ #include "debug.h"
21
+ #include "entry.h"
22
+ #include "get.h"
23
+ #include "options.h"
24
+ #include "read.h"
25
+ #include "vstring.h"
26
+
27
+ /*
28
+ * MACROS
29
+ */
30
+ #define stringMatch(s1,s2) (strcmp (s1,s2) == 0)
31
+ #define isspacetab(c) ((c) == SPACE || (c) == TAB)
32
+
33
+ /*
34
+ * DATA DECLARATIONS
35
+ */
36
+ typedef enum { COMMENT_NONE, COMMENT_C, COMMENT_CPLUS } Comment;
37
+
38
+ enum eCppLimits {
39
+ MaxCppNestingLevel = 20,
40
+ MaxDirectiveName = 10
41
+ };
42
+
43
+ /* Defines the one nesting level of a preprocessor conditional.
44
+ */
45
+ typedef struct sConditionalInfo {
46
+ boolean ignoreAllBranches; /* ignoring parent conditional branch */
47
+ boolean singleBranch; /* choose only one branch */
48
+ boolean branchChosen; /* branch already selected */
49
+ boolean ignoring; /* current ignore state */
50
+ } conditionalInfo;
51
+
52
+ enum eState {
53
+ DRCTV_NONE, /* no known directive - ignore to end of line */
54
+ DRCTV_DEFINE, /* "#define" encountered */
55
+ DRCTV_HASH, /* initial '#' read; determine directive */
56
+ DRCTV_IF, /* "#if" or "#ifdef" encountered */
57
+ DRCTV_PRAGMA, /* #pragma encountered */
58
+ DRCTV_UNDEF /* "#undef" encountered */
59
+ };
60
+
61
+ /* Defines the current state of the pre-processor.
62
+ */
63
+ typedef struct sCppState {
64
+ int ungetch, ungetch2; /* ungotten characters, if any */
65
+ boolean resolveRequired; /* must resolve if/else/elif/endif branch */
66
+ boolean hasAtLiteralStrings; /* supports @"c:\" strings */
67
+ struct sDirective {
68
+ enum eState state; /* current directive being processed */
69
+ boolean accept; /* is a directive syntactically permitted? */
70
+ vString * name; /* macro name */
71
+ unsigned int nestLevel; /* level 0 is not used */
72
+ conditionalInfo ifdef [MaxCppNestingLevel];
73
+ } directive;
74
+ } cppState;
75
+
76
+ /*
77
+ * DATA DEFINITIONS
78
+ */
79
+
80
+ /* Use brace formatting to detect end of block.
81
+ */
82
+ static boolean BraceFormat = FALSE;
83
+
84
+ static cppState Cpp = {
85
+ '\0', '\0', /* ungetch characters */
86
+ FALSE, /* resolveRequired */
87
+ FALSE, /* hasAtLiteralStrings */
88
+ {
89
+ DRCTV_NONE, /* state */
90
+ FALSE, /* accept */
91
+ NULL, /* tag name */
92
+ 0, /* nestLevel */
93
+ { {FALSE,FALSE,FALSE,FALSE} } /* ifdef array */
94
+ } /* directive */
95
+ };
96
+
97
+ /*
98
+ * FUNCTION DEFINITIONS
99
+ */
100
+
101
+ extern boolean isBraceFormat (void)
102
+ {
103
+ return BraceFormat;
104
+ }
105
+
106
+ extern unsigned int getDirectiveNestLevel (void)
107
+ {
108
+ return Cpp.directive.nestLevel;
109
+ }
110
+
111
+ extern void cppInit (const boolean state, const boolean hasAtLiteralStrings)
112
+ {
113
+ BraceFormat = state;
114
+
115
+ Cpp.ungetch = '\0';
116
+ Cpp.ungetch2 = '\0';
117
+ Cpp.resolveRequired = FALSE;
118
+ Cpp.hasAtLiteralStrings = hasAtLiteralStrings;
119
+
120
+ Cpp.directive.state = DRCTV_NONE;
121
+ Cpp.directive.accept = TRUE;
122
+ Cpp.directive.nestLevel = 0;
123
+
124
+ Cpp.directive.ifdef [0].ignoreAllBranches = FALSE;
125
+ Cpp.directive.ifdef [0].singleBranch = FALSE;
126
+ Cpp.directive.ifdef [0].branchChosen = FALSE;
127
+ Cpp.directive.ifdef [0].ignoring = FALSE;
128
+
129
+ if (Cpp.directive.name == NULL)
130
+ Cpp.directive.name = vStringNew ();
131
+ else
132
+ vStringClear (Cpp.directive.name);
133
+ }
134
+
135
+ extern void cppTerminate (void)
136
+ {
137
+ if (Cpp.directive.name != NULL)
138
+ {
139
+ vStringDelete (Cpp.directive.name);
140
+ Cpp.directive.name = NULL;
141
+ }
142
+ }
143
+
144
+ extern void cppBeginStatement (void)
145
+ {
146
+ Cpp.resolveRequired = TRUE;
147
+ }
148
+
149
+ extern void cppEndStatement (void)
150
+ {
151
+ Cpp.resolveRequired = FALSE;
152
+ }
153
+
154
+ /*
155
+ * Scanning functions
156
+ *
157
+ * This section handles preprocessor directives. It strips out all
158
+ * directives and may emit a tag for #define directives.
159
+ */
160
+
161
+ /* This puts a character back into the input queue for the source File.
162
+ * Up to two characters may be ungotten.
163
+ */
164
+ extern void cppUngetc (const int c)
165
+ {
166
+ Assert (Cpp.ungetch2 == '\0');
167
+ Cpp.ungetch2 = Cpp.ungetch;
168
+ Cpp.ungetch = c;
169
+ }
170
+
171
+ /* Reads a directive, whose first character is given by "c", into "name".
172
+ */
173
+ static boolean readDirective (int c, char *const name, unsigned int maxLength)
174
+ {
175
+ unsigned int i;
176
+
177
+ for (i = 0 ; i < maxLength - 1 ; ++i)
178
+ {
179
+ if (i > 0)
180
+ {
181
+ c = fileGetc ();
182
+ if (c == EOF || ! isalpha (c))
183
+ {
184
+ fileUngetc (c);
185
+ break;
186
+ }
187
+ }
188
+ name [i] = c;
189
+ }
190
+ name [i] = '\0'; /* null terminate */
191
+
192
+ return (boolean) isspacetab (c);
193
+ }
194
+
195
+ /* Reads an identifier, whose first character is given by "c", into "tag",
196
+ * together with the file location and corresponding line number.
197
+ */
198
+ static void readIdentifier (int c, vString *const name)
199
+ {
200
+ vStringClear (name);
201
+ do
202
+ {
203
+ vStringPut (name, c);
204
+ } while (c = fileGetc (), (c != EOF && isident (c)));
205
+ fileUngetc (c);
206
+ vStringTerminate (name);
207
+ }
208
+
209
+ static conditionalInfo *currentConditional (void)
210
+ {
211
+ return &Cpp.directive.ifdef [Cpp.directive.nestLevel];
212
+ }
213
+
214
+ static boolean isIgnore (void)
215
+ {
216
+ return Cpp.directive.ifdef [Cpp.directive.nestLevel].ignoring;
217
+ }
218
+
219
+ static boolean setIgnore (const boolean ignore)
220
+ {
221
+ return Cpp.directive.ifdef [Cpp.directive.nestLevel].ignoring = ignore;
222
+ }
223
+
224
+ static boolean isIgnoreBranch (void)
225
+ {
226
+ conditionalInfo *const ifdef = currentConditional ();
227
+
228
+ /* Force a single branch if an incomplete statement is discovered
229
+ * en route. This may have allowed earlier branches containing complete
230
+ * statements to be followed, but we must follow no further branches.
231
+ */
232
+ if (Cpp.resolveRequired && ! BraceFormat)
233
+ ifdef->singleBranch = TRUE;
234
+
235
+ /* We will ignore this branch in the following cases:
236
+ *
237
+ * 1. We are ignoring all branches (conditional was within an ignored
238
+ * branch of the parent conditional)
239
+ * 2. A branch has already been chosen and either of:
240
+ * a. A statement was incomplete upon entering the conditional
241
+ * b. A statement is incomplete upon encountering a branch
242
+ */
243
+ return (boolean) (ifdef->ignoreAllBranches ||
244
+ (ifdef->branchChosen && ifdef->singleBranch));
245
+ }
246
+
247
+ static void chooseBranch (void)
248
+ {
249
+ if (! BraceFormat)
250
+ {
251
+ conditionalInfo *const ifdef = currentConditional ();
252
+
253
+ ifdef->branchChosen = (boolean) (ifdef->singleBranch ||
254
+ Cpp.resolveRequired);
255
+ }
256
+ }
257
+
258
+ /* Pushes one nesting level for an #if directive, indicating whether or not
259
+ * the branch should be ignored and whether a branch has already been chosen.
260
+ */
261
+ static boolean pushConditional (const boolean firstBranchChosen)
262
+ {
263
+ const boolean ignoreAllBranches = isIgnore (); /* current ignore */
264
+ boolean ignoreBranch = FALSE;
265
+
266
+ if (Cpp.directive.nestLevel < (unsigned int) MaxCppNestingLevel - 1)
267
+ {
268
+ conditionalInfo *ifdef;
269
+
270
+ ++Cpp.directive.nestLevel;
271
+ ifdef = currentConditional ();
272
+
273
+ /* We take a snapshot of whether there is an incomplete statement in
274
+ * progress upon encountering the preprocessor conditional. If so,
275
+ * then we will flag that only a single branch of the conditional
276
+ * should be followed.
277
+ */
278
+ ifdef->ignoreAllBranches = ignoreAllBranches;
279
+ ifdef->singleBranch = Cpp.resolveRequired;
280
+ ifdef->branchChosen = firstBranchChosen;
281
+ ifdef->ignoring = (boolean) (ignoreAllBranches || (
282
+ ! firstBranchChosen && ! BraceFormat &&
283
+ (ifdef->singleBranch || !Option.if0)));
284
+ ignoreBranch = ifdef->ignoring;
285
+ }
286
+ return ignoreBranch;
287
+ }
288
+
289
+ /* Pops one nesting level for an #endif directive.
290
+ */
291
+ static boolean popConditional (void)
292
+ {
293
+ if (Cpp.directive.nestLevel > 0)
294
+ --Cpp.directive.nestLevel;
295
+
296
+ return isIgnore ();
297
+ }
298
+
299
+ static void makeDefineTag (const char *const name)
300
+ {
301
+ const boolean isFileScope = (boolean) (! isHeaderFile ());
302
+
303
+ if (includingDefineTags () &&
304
+ (! isFileScope || Option.include.fileScope))
305
+ {
306
+ tagEntryInfo e;
307
+ initTagEntry (&e, name);
308
+ e.lineNumberEntry = (boolean) (Option.locate != EX_PATTERN);
309
+ e.isFileScope = isFileScope;
310
+ e.truncateLine = TRUE;
311
+ e.kindName = "macro";
312
+ e.kind = 'd';
313
+ makeTagEntry (&e);
314
+ }
315
+ }
316
+
317
+ static void directiveDefine (const int c)
318
+ {
319
+ if (isident1 (c))
320
+ {
321
+ readIdentifier (c, Cpp.directive.name);
322
+ if (! isIgnore ())
323
+ makeDefineTag (vStringValue (Cpp.directive.name));
324
+ }
325
+ Cpp.directive.state = DRCTV_NONE;
326
+ }
327
+
328
+ static void directivePragma (int c)
329
+ {
330
+ if (isident1 (c))
331
+ {
332
+ readIdentifier (c, Cpp.directive.name);
333
+ if (stringMatch (vStringValue (Cpp.directive.name), "weak"))
334
+ {
335
+ /* generate macro tag for weak name */
336
+ do
337
+ {
338
+ c = fileGetc ();
339
+ } while (c == SPACE);
340
+ if (isident1 (c))
341
+ {
342
+ readIdentifier (c, Cpp.directive.name);
343
+ makeDefineTag (vStringValue (Cpp.directive.name));
344
+ }
345
+ }
346
+ }
347
+ Cpp.directive.state = DRCTV_NONE;
348
+ }
349
+
350
+ static boolean directiveIf (const int c)
351
+ {
352
+ DebugStatement ( const boolean ignore0 = isIgnore (); )
353
+ const boolean ignore = pushConditional ((boolean) (c != '0'));
354
+
355
+ Cpp.directive.state = DRCTV_NONE;
356
+ DebugStatement ( debugCppNest (TRUE, Cpp.directive.nestLevel);
357
+ if (ignore != ignore0) debugCppIgnore (ignore); )
358
+
359
+ return ignore;
360
+ }
361
+
362
+ static boolean directiveHash (const int c)
363
+ {
364
+ boolean ignore = FALSE;
365
+ char directive [MaxDirectiveName];
366
+ DebugStatement ( const boolean ignore0 = isIgnore (); )
367
+
368
+ readDirective (c, directive, MaxDirectiveName);
369
+ if (stringMatch (directive, "define"))
370
+ Cpp.directive.state = DRCTV_DEFINE;
371
+ else if (stringMatch (directive, "undef"))
372
+ Cpp.directive.state = DRCTV_UNDEF;
373
+ else if (strncmp (directive, "if", (size_t) 2) == 0)
374
+ Cpp.directive.state = DRCTV_IF;
375
+ else if (stringMatch (directive, "elif") ||
376
+ stringMatch (directive, "else"))
377
+ {
378
+ ignore = setIgnore (isIgnoreBranch ());
379
+ if (! ignore && stringMatch (directive, "else"))
380
+ chooseBranch ();
381
+ Cpp.directive.state = DRCTV_NONE;
382
+ DebugStatement ( if (ignore != ignore0) debugCppIgnore (ignore); )
383
+ }
384
+ else if (stringMatch (directive, "endif"))
385
+ {
386
+ DebugStatement ( debugCppNest (FALSE, Cpp.directive.nestLevel); )
387
+ ignore = popConditional ();
388
+ Cpp.directive.state = DRCTV_NONE;
389
+ DebugStatement ( if (ignore != ignore0) debugCppIgnore (ignore); )
390
+ }
391
+ else if (stringMatch (directive, "pragma"))
392
+ Cpp.directive.state = DRCTV_PRAGMA;
393
+ else
394
+ Cpp.directive.state = DRCTV_NONE;
395
+
396
+ return ignore;
397
+ }
398
+
399
+ /* Handles a pre-processor directive whose first character is given by "c".
400
+ */
401
+ static boolean handleDirective (const int c)
402
+ {
403
+ boolean ignore = isIgnore ();
404
+
405
+ switch (Cpp.directive.state)
406
+ {
407
+ case DRCTV_NONE: ignore = isIgnore (); break;
408
+ case DRCTV_DEFINE: directiveDefine (c); break;
409
+ case DRCTV_HASH: ignore = directiveHash (c); break;
410
+ case DRCTV_IF: ignore = directiveIf (c); break;
411
+ case DRCTV_PRAGMA: directivePragma (c); break;
412
+ case DRCTV_UNDEF: directiveDefine (c); break;
413
+ }
414
+ return ignore;
415
+ }
416
+
417
+ /* Called upon reading of a slash ('/') characters, determines whether a
418
+ * comment is encountered, and its type.
419
+ */
420
+ static Comment isComment (void)
421
+ {
422
+ Comment comment;
423
+ const int next = fileGetc ();
424
+
425
+ if (next == '*')
426
+ comment = COMMENT_C;
427
+ else if (next == '/')
428
+ comment = COMMENT_CPLUS;
429
+ else
430
+ {
431
+ fileUngetc (next);
432
+ comment = COMMENT_NONE;
433
+ }
434
+ return comment;
435
+ }
436
+
437
+ /* Skips over a C style comment. According to ANSI specification a comment
438
+ * is treated as white space, so we perform this substitution.
439
+ */
440
+ int skipOverCComment (void)
441
+ {
442
+ int c = fileGetc ();
443
+
444
+ while (c != EOF)
445
+ {
446
+ if (c != '*')
447
+ c = fileGetc ();
448
+ else
449
+ {
450
+ const int next = fileGetc ();
451
+
452
+ if (next != '/')
453
+ c = next;
454
+ else
455
+ {
456
+ c = SPACE; /* replace comment with space */
457
+ break;
458
+ }
459
+ }
460
+ }
461
+ return c;
462
+ }
463
+
464
+ /* Skips over a C++ style comment.
465
+ */
466
+ static int skipOverCplusComment (void)
467
+ {
468
+ int c;
469
+
470
+ while ((c = fileGetc ()) != EOF)
471
+ {
472
+ if (c == BACKSLASH)
473
+ fileGetc (); /* throw away next character, too */
474
+ else if (c == NEWLINE)
475
+ break;
476
+ }
477
+ return c;
478
+ }
479
+
480
+ /* Skips to the end of a string, returning a special character to
481
+ * symbolically represent a generic string.
482
+ */
483
+ static int skipToEndOfString (boolean ignoreBackslash)
484
+ {
485
+ int c;
486
+
487
+ while ((c = fileGetc ()) != EOF)
488
+ {
489
+ if (c == BACKSLASH && ! ignoreBackslash)
490
+ fileGetc (); /* throw away next character, too */
491
+ else if (c == DOUBLE_QUOTE)
492
+ break;
493
+ }
494
+ return STRING_SYMBOL; /* symbolic representation of string */
495
+ }
496
+
497
+ /* Skips to the end of the three (possibly four) 'c' sequence, returning a
498
+ * special character to symbolically represent a generic character.
499
+ * Also detects Vera numbers that include a base specifier (ie. 'b1010).
500
+ */
501
+ static int skipToEndOfChar (void)
502
+ {
503
+ int c;
504
+ int count = 0, veraBase = '\0';
505
+
506
+ while ((c = fileGetc ()) != EOF)
507
+ {
508
+ ++count;
509
+ if (c == BACKSLASH)
510
+ fileGetc (); /* throw away next character, too */
511
+ else if (c == SINGLE_QUOTE)
512
+ break;
513
+ else if (c == NEWLINE)
514
+ {
515
+ fileUngetc (c);
516
+ break;
517
+ }
518
+ else if (count == 1 && strchr ("DHOB", toupper (c)) != NULL)
519
+ veraBase = c;
520
+ else if (veraBase != '\0' && ! isalnum (c))
521
+ {
522
+ fileUngetc (c);
523
+ break;
524
+ }
525
+ }
526
+ return CHAR_SYMBOL; /* symbolic representation of character */
527
+ }
528
+
529
+ /* This function returns the next character, stripping out comments,
530
+ * C pre-processor directives, and the contents of single and double
531
+ * quoted strings. In short, strip anything which places a burden upon
532
+ * the tokenizer.
533
+ */
534
+ extern int cppGetc (void)
535
+ {
536
+ boolean directive = FALSE;
537
+ boolean ignore = FALSE;
538
+ int c;
539
+
540
+ if (Cpp.ungetch != '\0')
541
+ {
542
+ c = Cpp.ungetch;
543
+ Cpp.ungetch = Cpp.ungetch2;
544
+ Cpp.ungetch2 = '\0';
545
+ return c; /* return here to avoid re-calling debugPutc () */
546
+ }
547
+ else do
548
+ {
549
+ c = fileGetc ();
550
+ process:
551
+ switch (c)
552
+ {
553
+ case EOF:
554
+ ignore = FALSE;
555
+ directive = FALSE;
556
+ break;
557
+
558
+ case TAB:
559
+ case SPACE:
560
+ break; /* ignore most white space */
561
+
562
+ case NEWLINE:
563
+ if (directive && ! ignore)
564
+ directive = FALSE;
565
+ Cpp.directive.accept = TRUE;
566
+ break;
567
+
568
+ case DOUBLE_QUOTE:
569
+ Cpp.directive.accept = FALSE;
570
+ c = skipToEndOfString (FALSE);
571
+ break;
572
+
573
+ case '#':
574
+ if (Cpp.directive.accept)
575
+ {
576
+ directive = TRUE;
577
+ Cpp.directive.state = DRCTV_HASH;
578
+ Cpp.directive.accept = FALSE;
579
+ }
580
+ break;
581
+
582
+ case SINGLE_QUOTE:
583
+ Cpp.directive.accept = FALSE;
584
+ c = skipToEndOfChar ();
585
+ break;
586
+
587
+ case '/':
588
+ {
589
+ const Comment comment = isComment ();
590
+
591
+ if (comment == COMMENT_C)
592
+ c = skipOverCComment ();
593
+ else if (comment == COMMENT_CPLUS)
594
+ {
595
+ c = skipOverCplusComment ();
596
+ if (c == NEWLINE)
597
+ fileUngetc (c);
598
+ }
599
+ else
600
+ Cpp.directive.accept = FALSE;
601
+ break;
602
+ }
603
+
604
+ case BACKSLASH:
605
+ {
606
+ int next = fileGetc ();
607
+
608
+ if (next == NEWLINE)
609
+ continue;
610
+ else if (next == '?')
611
+ cppUngetc (next);
612
+ else
613
+ fileUngetc (next);
614
+ break;
615
+ }
616
+
617
+ case '?':
618
+ {
619
+ int next = fileGetc ();
620
+ if (next != '?')
621
+ fileUngetc (next);
622
+ else
623
+ {
624
+ next = fileGetc ();
625
+ switch (next)
626
+ {
627
+ case '(': c = '['; break;
628
+ case ')': c = ']'; break;
629
+ case '<': c = '{'; break;
630
+ case '>': c = '}'; break;
631
+ case '/': c = BACKSLASH; goto process;
632
+ case '!': c = '|'; break;
633
+ case SINGLE_QUOTE: c = '^'; break;
634
+ case '-': c = '~'; break;
635
+ case '=': c = '#'; goto process;
636
+ default:
637
+ fileUngetc (next);
638
+ cppUngetc ('?');
639
+ break;
640
+ }
641
+ }
642
+ } break;
643
+
644
+ default:
645
+ if (c == '@' && Cpp.hasAtLiteralStrings)
646
+ {
647
+ int next = fileGetc ();
648
+ if (next == DOUBLE_QUOTE)
649
+ {
650
+ Cpp.directive.accept = FALSE;
651
+ c = skipToEndOfString (TRUE);
652
+ break;
653
+ }
654
+ }
655
+ Cpp.directive.accept = FALSE;
656
+ if (directive)
657
+ ignore = handleDirective (c);
658
+ break;
659
+ }
660
+ } while (directive || ignore);
661
+
662
+ DebugStatement ( debugPutc (DEBUG_CPP, c); )
663
+ DebugStatement ( if (c == NEWLINE)
664
+ debugPrintf (DEBUG_CPP, "%6ld: ", getInputLineNumber () + 1); )
665
+
666
+ return c;
667
+ }
668
+
669
+ /* vi:set tabstop=4 shiftwidth=4: */
@@ -0,0 +1,50 @@
1
+ /*
2
+ * $Id: get.h 525 2007-05-28 01:50:41Z elliotth $
3
+ *
4
+ * Copyright (c) 1998-2002, Darren Hiebert
5
+ *
6
+ * This source code is released for free distribution under the terms of the
7
+ * GNU General Public License.
8
+ *
9
+ * External interface to get.c
10
+ */
11
+ #ifndef _GET_H
12
+ #define _GET_H
13
+
14
+ /*
15
+ * INCLUDE FILES
16
+ */
17
+ #include "general.h" /* must always come first */
18
+
19
+ #include "ctags.h" /* to define langType */
20
+
21
+ /*
22
+ * MACROS
23
+ */
24
+ /* Is the character valid as a character of a C identifier?
25
+ * VMS allows '$' in identifiers.
26
+ */
27
+ #define isident(c) (isalnum(c) || (c) == '_' || (c) == '$')
28
+
29
+ /* Is the character valid as the first character of a C identifier?
30
+ * C++ allows '~' in destructors.
31
+ * VMS allows '$' in identifiers.
32
+ */
33
+ #define isident1(c) (isalpha(c) || (c) == '_' || (c) == '~' || (c) == '$')
34
+
35
+ /*
36
+ * FUNCTION PROTOTYPES
37
+ */
38
+ extern boolean isBraceFormat (void);
39
+ extern unsigned int getDirectiveNestLevel (void);
40
+ extern void cppInit (const boolean state, const boolean hasAtLiteralStrings);
41
+ extern void cppTerminate (void);
42
+ extern void cppBeginStatement (void);
43
+ extern void cppEndStatement (void);
44
+ extern void cppUngetc (const int c);
45
+ extern int cppGetc (void);
46
+ extern int skipOverCComment (void);
47
+
48
+ #endif /* _GET_H */
49
+
50
+ /* vi:set tabstop=4 shiftwidth=4: */