ctags.rb 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,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: */
|