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,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: */
|