ctags.rb 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. data/Gemfile +2 -0
  2. data/Rakefile +23 -0
  3. data/ctags.rb.gemspec +23 -0
  4. data/ext/.gitignore +3 -0
  5. data/ext/extconf.rb +15 -0
  6. data/ext/vendor/exuberant-ctags/.gitignore +6 -0
  7. data/ext/vendor/exuberant-ctags/.indent.pro +31 -0
  8. data/ext/vendor/exuberant-ctags/COPYING +340 -0
  9. data/ext/vendor/exuberant-ctags/EXTENDING.html +386 -0
  10. data/ext/vendor/exuberant-ctags/FAQ +371 -0
  11. data/ext/vendor/exuberant-ctags/INSTALL +215 -0
  12. data/ext/vendor/exuberant-ctags/INSTALL.oth +73 -0
  13. data/ext/vendor/exuberant-ctags/MAINTAINERS +88 -0
  14. data/ext/vendor/exuberant-ctags/Makefile.in +222 -0
  15. data/ext/vendor/exuberant-ctags/NEWS +871 -0
  16. data/ext/vendor/exuberant-ctags/README +73 -0
  17. data/ext/vendor/exuberant-ctags/ant.c +42 -0
  18. data/ext/vendor/exuberant-ctags/argproc.c +505 -0
  19. data/ext/vendor/exuberant-ctags/args.c +274 -0
  20. data/ext/vendor/exuberant-ctags/args.h +63 -0
  21. data/ext/vendor/exuberant-ctags/asm.c +387 -0
  22. data/ext/vendor/exuberant-ctags/asp.c +328 -0
  23. data/ext/vendor/exuberant-ctags/awk.c +81 -0
  24. data/ext/vendor/exuberant-ctags/basic.c +203 -0
  25. data/ext/vendor/exuberant-ctags/beta.c +321 -0
  26. data/ext/vendor/exuberant-ctags/c.c +2932 -0
  27. data/ext/vendor/exuberant-ctags/cobol.c +50 -0
  28. data/ext/vendor/exuberant-ctags/config.h.in +277 -0
  29. data/ext/vendor/exuberant-ctags/configure +7704 -0
  30. data/ext/vendor/exuberant-ctags/configure.ac +532 -0
  31. data/ext/vendor/exuberant-ctags/ctags.1 +1186 -0
  32. data/ext/vendor/exuberant-ctags/ctags.h +28 -0
  33. data/ext/vendor/exuberant-ctags/ctags.html +2087 -0
  34. data/ext/vendor/exuberant-ctags/ctags.spec +40 -0
  35. data/ext/vendor/exuberant-ctags/debug.c +113 -0
  36. data/ext/vendor/exuberant-ctags/debug.h +70 -0
  37. data/ext/vendor/exuberant-ctags/descrip.mms +68 -0
  38. data/ext/vendor/exuberant-ctags/dosbatch.c +42 -0
  39. data/ext/vendor/exuberant-ctags/e_amiga.h +24 -0
  40. data/ext/vendor/exuberant-ctags/e_djgpp.h +47 -0
  41. data/ext/vendor/exuberant-ctags/e_mac.h +143 -0
  42. data/ext/vendor/exuberant-ctags/e_msoft.h +76 -0
  43. data/ext/vendor/exuberant-ctags/e_os2.h +37 -0
  44. data/ext/vendor/exuberant-ctags/e_qdos.h +34 -0
  45. data/ext/vendor/exuberant-ctags/e_riscos.h +58 -0
  46. data/ext/vendor/exuberant-ctags/e_vms.h +31 -0
  47. data/ext/vendor/exuberant-ctags/eiffel.c +1352 -0
  48. data/ext/vendor/exuberant-ctags/entry.c +847 -0
  49. data/ext/vendor/exuberant-ctags/entry.h +103 -0
  50. data/ext/vendor/exuberant-ctags/erlang.c +189 -0
  51. data/ext/vendor/exuberant-ctags/flex.c +2243 -0
  52. data/ext/vendor/exuberant-ctags/fortran.c +2197 -0
  53. data/ext/vendor/exuberant-ctags/general.h +127 -0
  54. data/ext/vendor/exuberant-ctags/get.c +669 -0
  55. data/ext/vendor/exuberant-ctags/get.h +50 -0
  56. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/all-wcprops +47 -0
  57. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/entries +112 -0
  58. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/README.txt.svn-base +5 -0
  59. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regcomp.c.svn-base +3818 -0
  60. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex.c.svn-base +74 -0
  61. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex.h.svn-base +575 -0
  62. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex_internal.c.svn-base +1713 -0
  63. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex_internal.h.svn-base +773 -0
  64. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regexec.c.svn-base +4338 -0
  65. data/ext/vendor/exuberant-ctags/gnu_regex/README.txt +5 -0
  66. data/ext/vendor/exuberant-ctags/gnu_regex/regcomp.c +3818 -0
  67. data/ext/vendor/exuberant-ctags/gnu_regex/regex.c +74 -0
  68. data/ext/vendor/exuberant-ctags/gnu_regex/regex.h +575 -0
  69. data/ext/vendor/exuberant-ctags/gnu_regex/regex_internal.c +1713 -0
  70. data/ext/vendor/exuberant-ctags/gnu_regex/regex_internal.h +773 -0
  71. data/ext/vendor/exuberant-ctags/gnu_regex/regexec.c +4338 -0
  72. data/ext/vendor/exuberant-ctags/html.c +49 -0
  73. data/ext/vendor/exuberant-ctags/jscript.c +1572 -0
  74. data/ext/vendor/exuberant-ctags/keyword.c +258 -0
  75. data/ext/vendor/exuberant-ctags/keyword.h +34 -0
  76. data/ext/vendor/exuberant-ctags/lisp.c +139 -0
  77. data/ext/vendor/exuberant-ctags/lregex.c +704 -0
  78. data/ext/vendor/exuberant-ctags/lua.c +133 -0
  79. data/ext/vendor/exuberant-ctags/mac.c +273 -0
  80. data/ext/vendor/exuberant-ctags/magic.diff +21 -0
  81. data/ext/vendor/exuberant-ctags/main.c +584 -0
  82. data/ext/vendor/exuberant-ctags/main.h +32 -0
  83. data/ext/vendor/exuberant-ctags/maintainer.mak +476 -0
  84. data/ext/vendor/exuberant-ctags/make.c +217 -0
  85. data/ext/vendor/exuberant-ctags/matlab.c +44 -0
  86. data/ext/vendor/exuberant-ctags/mk_bc3.mak +46 -0
  87. data/ext/vendor/exuberant-ctags/mk_bc5.mak +49 -0
  88. data/ext/vendor/exuberant-ctags/mk_djg.mak +18 -0
  89. data/ext/vendor/exuberant-ctags/mk_manx.mak +65 -0
  90. data/ext/vendor/exuberant-ctags/mk_mingw.mak +31 -0
  91. data/ext/vendor/exuberant-ctags/mk_mpw.mak +130 -0
  92. data/ext/vendor/exuberant-ctags/mk_mvc.mak +40 -0
  93. data/ext/vendor/exuberant-ctags/mk_os2.mak +104 -0
  94. data/ext/vendor/exuberant-ctags/mk_qdos.mak +100 -0
  95. data/ext/vendor/exuberant-ctags/mk_sas.mak +63 -0
  96. data/ext/vendor/exuberant-ctags/mkinstalldirs +40 -0
  97. data/ext/vendor/exuberant-ctags/ocaml.c +1842 -0
  98. data/ext/vendor/exuberant-ctags/options.c +1842 -0
  99. data/ext/vendor/exuberant-ctags/options.h +155 -0
  100. data/ext/vendor/exuberant-ctags/parse.c +677 -0
  101. data/ext/vendor/exuberant-ctags/parse.h +129 -0
  102. data/ext/vendor/exuberant-ctags/parsers.h +63 -0
  103. data/ext/vendor/exuberant-ctags/pascal.c +267 -0
  104. data/ext/vendor/exuberant-ctags/perl.c +382 -0
  105. data/ext/vendor/exuberant-ctags/php.c +237 -0
  106. data/ext/vendor/exuberant-ctags/python.c +771 -0
  107. data/ext/vendor/exuberant-ctags/qdos.c +106 -0
  108. data/ext/vendor/exuberant-ctags/read.c +569 -0
  109. data/ext/vendor/exuberant-ctags/read.h +116 -0
  110. data/ext/vendor/exuberant-ctags/readtags.c +959 -0
  111. data/ext/vendor/exuberant-ctags/readtags.h +252 -0
  112. data/ext/vendor/exuberant-ctags/rexx.c +39 -0
  113. data/ext/vendor/exuberant-ctags/routines.c +891 -0
  114. data/ext/vendor/exuberant-ctags/routines.h +134 -0
  115. data/ext/vendor/exuberant-ctags/ruby.c +408 -0
  116. data/ext/vendor/exuberant-ctags/scheme.c +111 -0
  117. data/ext/vendor/exuberant-ctags/sh.c +115 -0
  118. data/ext/vendor/exuberant-ctags/slang.c +41 -0
  119. data/ext/vendor/exuberant-ctags/sml.c +212 -0
  120. data/ext/vendor/exuberant-ctags/sort.c +230 -0
  121. data/ext/vendor/exuberant-ctags/sort.h +32 -0
  122. data/ext/vendor/exuberant-ctags/source.mak +122 -0
  123. data/ext/vendor/exuberant-ctags/sql.c +2112 -0
  124. data/ext/vendor/exuberant-ctags/strlist.c +281 -0
  125. data/ext/vendor/exuberant-ctags/strlist.h +54 -0
  126. data/ext/vendor/exuberant-ctags/tcl.c +116 -0
  127. data/ext/vendor/exuberant-ctags/tex.c +524 -0
  128. data/ext/vendor/exuberant-ctags/verilog.c +340 -0
  129. data/ext/vendor/exuberant-ctags/vhdl.c +835 -0
  130. data/ext/vendor/exuberant-ctags/vim.c +636 -0
  131. data/ext/vendor/exuberant-ctags/vstring.c +232 -0
  132. data/ext/vendor/exuberant-ctags/vstring.h +85 -0
  133. data/ext/vendor/exuberant-ctags/yacc.c +40 -0
  134. data/lib/ctags/exuberant.rb +45 -0
  135. data/lib/ctags/version.rb +3 -0
  136. data/lib/ctags.rb +6 -0
  137. data/test/test_ctags.rb +24 -0
  138. metadata +233 -0
@@ -0,0 +1,106 @@
1
+ /*
2
+ * $Id: qdos.c 443 2006-05-30 04:37:13Z darren $
3
+ *
4
+ * Copyright (c) 1999, Thierry Godefroy <godefroy@imaginet.fr>
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 to handle wildcard expansion and file name
10
+ * conversion under QDOS.
11
+ */
12
+
13
+ #include <stdio.h>
14
+ #include <stdlib.h>
15
+ #include <unistd.h>
16
+ #include <fcntl.h>
17
+ #include <qdos.h>
18
+ #include <string.h>
19
+ #include <errno.h>
20
+ #include "ctags.h"
21
+
22
+ /* Translate the filenames from UNIX to QDOS conventions on open calls */
23
+ int (*_Open) (const char *, int, ...) = qopen;
24
+
25
+ long _stack = 24576; /* Plenty of stack space */
26
+ long _memincr = 10240; /* Big increments to cut fragmentation */
27
+ char _prog_name [] = "ctags";
28
+ char _version [] = PROGRAM_VERSION;
29
+ char _copyright [32] = __DATE__;
30
+ char *_endmsg = "\nPress a key to exit.";
31
+ int custom_expand (char * param, char ***argvptr, int *argcptr);
32
+ int (*_cmdwildcard) () = custom_expand;
33
+
34
+
35
+ struct WINDOWDEF _condetails = { 208, 1, 0, 7, 512, 256, 0, 0};
36
+ void (*_consetup) () = consetup_title;
37
+
38
+ /* custom cmdexpand: also expands directory names */
39
+
40
+ #define FILEBUF_INIT 1024 /* Initial allocation size for buffer */
41
+ #define FILEBUF_INCR 1024 /* Increment size for buffer */
42
+
43
+ int custom_expand (char * param, char ***argvptr, int *argcptr)
44
+ {
45
+ int count,sl;
46
+ size_t bufsize;
47
+ char *filenamebuf;
48
+ char *ptr,*safeptr;
49
+
50
+ /*
51
+ * Check to see if we should do wild card expansion.
52
+ * We only perform wildcard expansion if the parameter
53
+ * was not a string and if it contains one of the
54
+ * wild card characters.
55
+ *
56
+ * We also do not expand any option that starts with '-'
57
+ * as we then assume that it is a unix stylew option.
58
+ */
59
+ if ((*param == '-') || (strpbrk (param,"*?") == NULL) ) {
60
+ return 0;
61
+ }
62
+
63
+ if ((filenamebuf = malloc (bufsize = FILEBUF_INIT)) == NULL) {
64
+ return -1;
65
+ }
66
+ TRYAGAIN:
67
+ count = getfnl (param, filenamebuf, bufsize, QDR_ALL);
68
+ if (count == -1 && errno == ENOMEM) {
69
+ /*
70
+ * We have overflowed the buffer, so we try
71
+ * to get a bigger buffer and try again.
72
+ */
73
+ bufsize += FILEBUF_INCR;
74
+ if ((filenamebuf = realloc (filenamebuf, bufsize)) == NULL) {
75
+ return -1;
76
+ } else {
77
+ goto TRYAGAIN;
78
+ }
79
+ }
80
+ /*
81
+ * If no files were found, then return unexpanded.
82
+ */
83
+ if (count == 0) {
84
+ free (filenamebuf);
85
+ return 0;
86
+ }
87
+ /*
88
+ * Files were found, so add these to the list instead
89
+ * of the original parameter typed by the user.
90
+ */
91
+ for ( ptr=filenamebuf ; count > 0 ; count -- ) {
92
+ *argvptr = (char **) realloc (*argvptr, (size_t) (((*argcptr) + 2) * sizeof (char *)));
93
+ safeptr= (char *) malloc ((size_t) (sl=strlen (ptr) + 1));
94
+ if (safeptr == NULL || *argvptr == NULL) {
95
+ return -1;
96
+ }
97
+ (void) memcpy (safeptr,ptr, (size_t) sl);
98
+ (*argvptr) [*argcptr] = safeptr;
99
+ *argcptr += 1;
100
+ ptr += sl;
101
+ }
102
+ free (filenamebuf);
103
+ return *argcptr;
104
+ }
105
+
106
+ /* vi:set tabstop=4 shiftwidth=4: */
@@ -0,0 +1,569 @@
1
+ /*
2
+ * $Id: read.c 708 2009-07-04 05:29:02Z dhiebert $
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 low level source and tag file read functions (newline
10
+ * conversion for source files are performed at this level).
11
+ */
12
+
13
+ /*
14
+ * INCLUDE FILES
15
+ */
16
+ #include "general.h" /* must always come first */
17
+
18
+ #include <string.h>
19
+ #include <ctype.h>
20
+
21
+ #define FILE_WRITE
22
+ #include "read.h"
23
+ #include "debug.h"
24
+ #include "entry.h"
25
+ #include "main.h"
26
+ #include "routines.h"
27
+ #include "options.h"
28
+
29
+ /*
30
+ * DATA DEFINITIONS
31
+ */
32
+ inputFile File; /* globally read through macros */
33
+ static fpos_t StartOfLine; /* holds deferred position of start of line */
34
+
35
+ /*
36
+ * FUNCTION DEFINITIONS
37
+ */
38
+
39
+ extern void freeSourceFileResources (void)
40
+ {
41
+ if (File.name != NULL)
42
+ vStringDelete (File.name);
43
+ if (File.path != NULL)
44
+ vStringDelete (File.path);
45
+ if (File.source.name != NULL)
46
+ vStringDelete (File.source.name);
47
+ if (File.source.tagPath != NULL)
48
+ eFree (File.source.tagPath);
49
+ if (File.line != NULL)
50
+ vStringDelete (File.line);
51
+ }
52
+
53
+ /*
54
+ * Source file access functions
55
+ */
56
+
57
+ static void setInputFileName (const char *const fileName)
58
+ {
59
+ const char *const head = fileName;
60
+ const char *const tail = baseFilename (head);
61
+
62
+ if (File.name != NULL)
63
+ vStringDelete (File.name);
64
+ File.name = vStringNewInit (fileName);
65
+
66
+ if (File.path != NULL)
67
+ vStringDelete (File.path);
68
+ if (tail == head)
69
+ File.path = NULL;
70
+ else
71
+ {
72
+ const size_t length = tail - head - 1;
73
+ File.path = vStringNew ();
74
+ vStringNCopyS (File.path, fileName, length);
75
+ }
76
+ }
77
+
78
+ static void setSourceFileParameters (vString *const fileName)
79
+ {
80
+ if (File.source.name != NULL)
81
+ vStringDelete (File.source.name);
82
+ File.source.name = fileName;
83
+
84
+ if (File.source.tagPath != NULL)
85
+ eFree (File.source.tagPath);
86
+ if (! Option.tagRelative || isAbsolutePath (vStringValue (fileName)))
87
+ File.source.tagPath = eStrdup (vStringValue (fileName));
88
+ else
89
+ File.source.tagPath =
90
+ relativeFilename (vStringValue (fileName), TagFile.directory);
91
+
92
+ if (vStringLength (fileName) > TagFile.max.file)
93
+ TagFile.max.file = vStringLength (fileName);
94
+
95
+ File.source.isHeader = isIncludeFile (vStringValue (fileName));
96
+ File.source.language = getFileLanguage (vStringValue (fileName));
97
+ }
98
+
99
+ static boolean setSourceFileName (vString *const fileName)
100
+ {
101
+ boolean result = FALSE;
102
+ if (getFileLanguage (vStringValue (fileName)) != LANG_IGNORE)
103
+ {
104
+ vString *pathName;
105
+ if (isAbsolutePath (vStringValue (fileName)) || File.path == NULL)
106
+ pathName = vStringNewCopy (fileName);
107
+ else
108
+ pathName = combinePathAndFile (
109
+ vStringValue (File.path), vStringValue (fileName));
110
+ setSourceFileParameters (pathName);
111
+ result = TRUE;
112
+ }
113
+ return result;
114
+ }
115
+
116
+ /*
117
+ * Line directive parsing
118
+ */
119
+
120
+ static int skipWhite (void)
121
+ {
122
+ int c;
123
+ do
124
+ c = getc (File.fp);
125
+ while (c == ' ' || c == '\t');
126
+ return c;
127
+ }
128
+
129
+ static unsigned long readLineNumber (void)
130
+ {
131
+ unsigned long lNum = 0;
132
+ int c = skipWhite ();
133
+ while (c != EOF && isdigit (c))
134
+ {
135
+ lNum = (lNum * 10) + (c - '0');
136
+ c = getc (File.fp);
137
+ }
138
+ ungetc (c, File.fp);
139
+ if (c != ' ' && c != '\t')
140
+ lNum = 0;
141
+
142
+ return lNum;
143
+ }
144
+
145
+ /* While ANSI only permits lines of the form:
146
+ * # line n "filename"
147
+ * Earlier compilers generated lines of the form
148
+ * # n filename
149
+ * GNU C will output lines of the form:
150
+ * # n "filename"
151
+ * So we need to be fairly flexible in what we accept.
152
+ */
153
+ static vString *readFileName (void)
154
+ {
155
+ vString *const fileName = vStringNew ();
156
+ boolean quoteDelimited = FALSE;
157
+ int c = skipWhite ();
158
+
159
+ if (c == '"')
160
+ {
161
+ c = getc (File.fp); /* skip double-quote */
162
+ quoteDelimited = TRUE;
163
+ }
164
+ while (c != EOF && c != '\n' &&
165
+ (quoteDelimited ? (c != '"') : (c != ' ' && c != '\t')))
166
+ {
167
+ vStringPut (fileName, c);
168
+ c = getc (File.fp);
169
+ }
170
+ if (c == '\n')
171
+ ungetc (c, File.fp);
172
+ vStringPut (fileName, '\0');
173
+
174
+ return fileName;
175
+ }
176
+
177
+ static boolean parseLineDirective (void)
178
+ {
179
+ boolean result = FALSE;
180
+ int c = skipWhite ();
181
+ DebugStatement ( const char* lineStr = ""; )
182
+
183
+ if (isdigit (c))
184
+ {
185
+ ungetc (c, File.fp);
186
+ result = TRUE;
187
+ }
188
+ else if (c == 'l' && getc (File.fp) == 'i' &&
189
+ getc (File.fp) == 'n' && getc (File.fp) == 'e')
190
+ {
191
+ c = getc (File.fp);
192
+ if (c == ' ' || c == '\t')
193
+ {
194
+ DebugStatement ( lineStr = "line"; )
195
+ result = TRUE;
196
+ }
197
+ }
198
+ if (result)
199
+ {
200
+ const unsigned long lNum = readLineNumber ();
201
+ if (lNum == 0)
202
+ result = FALSE;
203
+ else
204
+ {
205
+ vString *const fileName = readFileName ();
206
+ if (vStringLength (fileName) == 0)
207
+ {
208
+ File.source.lineNumber = lNum - 1; /* applies to NEXT line */
209
+ DebugStatement ( debugPrintf (DEBUG_RAW, "#%s %ld", lineStr, lNum); )
210
+ }
211
+ else if (setSourceFileName (fileName))
212
+ {
213
+ File.source.lineNumber = lNum - 1; /* applies to NEXT line */
214
+ DebugStatement ( debugPrintf (DEBUG_RAW, "#%s %ld \"%s\"",
215
+ lineStr, lNum, vStringValue (fileName)); )
216
+ }
217
+
218
+ if (Option.include.fileNames && vStringLength (fileName) > 0 &&
219
+ lNum == 1)
220
+ {
221
+ tagEntryInfo tag;
222
+ initTagEntry (&tag, baseFilename (vStringValue (fileName)));
223
+
224
+ tag.isFileEntry = TRUE;
225
+ tag.lineNumberEntry = TRUE;
226
+ tag.lineNumber = 1;
227
+ tag.kindName = "file";
228
+ tag.kind = 'F';
229
+
230
+ makeTagEntry (&tag);
231
+ }
232
+ vStringDelete (fileName);
233
+ result = TRUE;
234
+ }
235
+ }
236
+ return result;
237
+ }
238
+
239
+ /*
240
+ * Source file I/O operations
241
+ */
242
+
243
+ /* This function opens a source file, and resets the line counter. If it
244
+ * fails, it will display an error message and leave the File.fp set to NULL.
245
+ */
246
+ extern boolean fileOpen (const char *const fileName, const langType language)
247
+ {
248
+ #ifdef VMS
249
+ const char *const openMode = "r";
250
+ #else
251
+ const char *const openMode = "rb";
252
+ #endif
253
+ boolean opened = FALSE;
254
+
255
+ /* If another file was already open, then close it.
256
+ */
257
+ if (File.fp != NULL)
258
+ {
259
+ fclose (File.fp); /* close any open source file */
260
+ File.fp = NULL;
261
+ }
262
+
263
+ if (Option.stdinFileName) {
264
+ File.fp = stdin;
265
+ } else {
266
+ File.fp = fopen (fileName, openMode);
267
+ }
268
+
269
+ if (File.fp == NULL)
270
+ error (WARNING | PERROR, "cannot open \"%s\"", fileName);
271
+ else
272
+ {
273
+ opened = TRUE;
274
+
275
+ setInputFileName (fileName);
276
+ fgetpos (File.fp, &StartOfLine);
277
+ fgetpos (File.fp, &File.filePosition);
278
+ File.currentLine = NULL;
279
+ File.language = language;
280
+ File.lineNumber = 0L;
281
+ File.eof = FALSE;
282
+ File.newLine = TRUE;
283
+
284
+ if (File.line != NULL)
285
+ vStringClear (File.line);
286
+
287
+ setSourceFileParameters (vStringNewInit (fileName));
288
+ File.source.lineNumber = 0L;
289
+
290
+ verbose ("OPENING %s as %s language %sfile\n", fileName,
291
+ getLanguageName (language),
292
+ File.source.isHeader ? "include " : "");
293
+ }
294
+ return opened;
295
+ }
296
+
297
+ extern void fileClose (void)
298
+ {
299
+ if (File.fp != NULL)
300
+ {
301
+ /* The line count of the file is 1 too big, since it is one-based
302
+ * and is incremented upon each newline.
303
+ */
304
+ if (Option.printTotals)
305
+ {
306
+ fileStatus *status = eStat (vStringValue (File.name));
307
+ addTotals (0, File.lineNumber - 1L, status->size);
308
+ }
309
+ fclose (File.fp);
310
+ File.fp = NULL;
311
+ }
312
+ }
313
+
314
+ extern boolean fileEOF (void)
315
+ {
316
+ return File.eof;
317
+ }
318
+
319
+ /* Action to take for each encountered source newline.
320
+ */
321
+ static void fileNewline (void)
322
+ {
323
+ File.filePosition = StartOfLine;
324
+ File.newLine = FALSE;
325
+ File.lineNumber++;
326
+ File.source.lineNumber++;
327
+ DebugStatement ( if (Option.breakLine == File.lineNumber) lineBreak (); )
328
+ DebugStatement ( debugPrintf (DEBUG_RAW, "%6ld: ", File.lineNumber); )
329
+ }
330
+
331
+ /* This function reads a single character from the stream, performing newline
332
+ * canonicalization.
333
+ */
334
+ static int iFileGetc (void)
335
+ {
336
+ int c;
337
+ readnext:
338
+ c = getc (File.fp);
339
+
340
+ /* If previous character was a newline, then we're starting a line.
341
+ */
342
+ if (File.newLine && c != EOF)
343
+ {
344
+ fileNewline ();
345
+ if (c == '#' && Option.lineDirectives)
346
+ {
347
+ if (parseLineDirective ())
348
+ goto readnext;
349
+ else
350
+ {
351
+ fsetpos (File.fp, &StartOfLine);
352
+ c = getc (File.fp);
353
+ }
354
+ }
355
+ }
356
+
357
+ if (c == EOF)
358
+ File.eof = TRUE;
359
+ else if (c == NEWLINE)
360
+ {
361
+ File.newLine = TRUE;
362
+ fgetpos (File.fp, &StartOfLine);
363
+ }
364
+ else if (c == CRETURN)
365
+ {
366
+ /* Turn line breaks into a canonical form. The three commonly
367
+ * used forms if line breaks: LF (UNIX/Mac OS X), CR (Mac OS 9),
368
+ * and CR-LF (MS-DOS) are converted into a generic newline.
369
+ */
370
+ #ifndef macintosh
371
+ const int next = getc (File.fp); /* is CR followed by LF? */
372
+ if (next != NEWLINE)
373
+ ungetc (next, File.fp);
374
+ else
375
+ #endif
376
+ {
377
+ c = NEWLINE; /* convert CR into newline */
378
+ File.newLine = TRUE;
379
+ fgetpos (File.fp, &StartOfLine);
380
+ }
381
+ }
382
+ DebugStatement ( debugPutc (DEBUG_RAW, c); )
383
+ return c;
384
+ }
385
+
386
+ extern void fileUngetc (int c)
387
+ {
388
+ File.ungetch = c;
389
+ }
390
+
391
+ static vString *iFileGetLine (void)
392
+ {
393
+ vString *result = NULL;
394
+ int c;
395
+ if (File.line == NULL)
396
+ File.line = vStringNew ();
397
+ vStringClear (File.line);
398
+ do
399
+ {
400
+ c = iFileGetc ();
401
+ if (c != EOF)
402
+ vStringPut (File.line, c);
403
+ if (c == '\n' || (c == EOF && vStringLength (File.line) > 0))
404
+ {
405
+ vStringTerminate (File.line);
406
+ #ifdef HAVE_REGEX
407
+ if (vStringLength (File.line) > 0)
408
+ matchRegex (File.line, File.source.language);
409
+ #endif
410
+ result = File.line;
411
+ break;
412
+ }
413
+ } while (c != EOF);
414
+ Assert (result != NULL || File.eof);
415
+ return result;
416
+ }
417
+
418
+ /* Do not mix use of fileReadLine () and fileGetc () for the same file.
419
+ */
420
+ extern int fileGetc (void)
421
+ {
422
+ int c;
423
+
424
+ /* If there is an ungotten character, then return it. Don't do any
425
+ * other processing on it, though, because we already did that the
426
+ * first time it was read through fileGetc ().
427
+ */
428
+ if (File.ungetch != '\0')
429
+ {
430
+ c = File.ungetch;
431
+ File.ungetch = '\0';
432
+ return c; /* return here to avoid re-calling debugPutc () */
433
+ }
434
+ do
435
+ {
436
+ if (File.currentLine != NULL)
437
+ {
438
+ c = *File.currentLine++;
439
+ if (c == '\0')
440
+ File.currentLine = NULL;
441
+ }
442
+ else
443
+ {
444
+ vString* const line = iFileGetLine ();
445
+ if (line != NULL)
446
+ File.currentLine = (unsigned char*) vStringValue (line);
447
+ if (File.currentLine == NULL)
448
+ c = EOF;
449
+ else
450
+ c = '\0';
451
+ }
452
+ } while (c == '\0');
453
+ DebugStatement ( debugPutc (DEBUG_READ, c); )
454
+ return c;
455
+ }
456
+
457
+ extern int fileSkipToCharacter (int c)
458
+ {
459
+ int d;
460
+ do
461
+ {
462
+ d = fileGetc ();
463
+ } while (d != EOF && d != c);
464
+ return d;
465
+ }
466
+
467
+ /* An alternative interface to fileGetc (). Do not mix use of fileReadLine()
468
+ * and fileGetc() for the same file. The returned string does not contain
469
+ * the terminating newline. A NULL return value means that all lines in the
470
+ * file have been read and we are at the end of file.
471
+ */
472
+ extern const unsigned char *fileReadLine (void)
473
+ {
474
+ vString* const line = iFileGetLine ();
475
+ const unsigned char* result = NULL;
476
+ if (line != NULL)
477
+ {
478
+ result = (const unsigned char*) vStringValue (line);
479
+ vStringStripNewline (line);
480
+ DebugStatement ( debugPrintf (DEBUG_READ, "%s\n", result); )
481
+ }
482
+ return result;
483
+ }
484
+
485
+ /*
486
+ * Source file line reading with automatic buffer sizing
487
+ */
488
+ extern char *readLine (vString *const vLine, FILE *const fp)
489
+ {
490
+ char *result = NULL;
491
+
492
+ vStringClear (vLine);
493
+ if (fp == NULL) /* to free memory allocated to buffer */
494
+ error (FATAL, "NULL file pointer");
495
+ else
496
+ {
497
+ boolean reReadLine;
498
+
499
+ /* If reading the line places any character other than a null or a
500
+ * newline at the last character position in the buffer (one less
501
+ * than the buffer size), then we must resize the buffer and
502
+ * reattempt to read the line.
503
+ */
504
+ do
505
+ {
506
+ char *const pLastChar = vStringValue (vLine) + vStringSize (vLine) -2;
507
+ fpos_t startOfLine;
508
+
509
+ fgetpos (fp, &startOfLine);
510
+ reReadLine = FALSE;
511
+ *pLastChar = '\0';
512
+ result = fgets (vStringValue (vLine), (int) vStringSize (vLine), fp);
513
+ if (result == NULL)
514
+ {
515
+ if (! feof (fp))
516
+ error (FATAL | PERROR, "Failure on attempt to read file");
517
+ }
518
+ else if (*pLastChar != '\0' &&
519
+ *pLastChar != '\n' && *pLastChar != '\r')
520
+ {
521
+ /* buffer overflow */
522
+ reReadLine = vStringAutoResize (vLine);
523
+ if (reReadLine)
524
+ fsetpos (fp, &startOfLine);
525
+ else
526
+ error (FATAL | PERROR, "input line too big; out of memory");
527
+ }
528
+ else
529
+ {
530
+ char* eol;
531
+ vStringSetLength (vLine);
532
+ /* canonicalize new line */
533
+ eol = vStringValue (vLine) + vStringLength (vLine) - 1;
534
+ if (*eol == '\r')
535
+ *eol = '\n';
536
+ else if (*(eol - 1) == '\r' && *eol == '\n')
537
+ {
538
+ *(eol - 1) = '\n';
539
+ *eol = '\0';
540
+ --vLine->length;
541
+ }
542
+ }
543
+ } while (reReadLine);
544
+ }
545
+ return result;
546
+ }
547
+
548
+ /* Places into the line buffer the contents of the line referenced by
549
+ * "location".
550
+ */
551
+ extern char *readSourceLine (
552
+ vString *const vLine, fpos_t location, long *const pSeekValue)
553
+ {
554
+ fpos_t orignalPosition;
555
+ char *result;
556
+
557
+ fgetpos (File.fp, &orignalPosition);
558
+ fsetpos (File.fp, &location);
559
+ if (pSeekValue != NULL)
560
+ *pSeekValue = ftell (File.fp);
561
+ result = readLine (vLine, File.fp);
562
+ if (result == NULL)
563
+ error (FATAL, "Unexpected end of file: %s", vStringValue (File.name));
564
+ fsetpos (File.fp, &orignalPosition);
565
+
566
+ return result;
567
+ }
568
+
569
+ /* vi:set tabstop=4 shiftwidth=4: */