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,274 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* $Id: args.c 536 2007-06-02 06:09:00Z elliotth $
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 1999-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 functions for reading command line arguments.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
* INCLUDE FILES
|
|
14
|
+
*/
|
|
15
|
+
#include "general.h" /* must always come first */
|
|
16
|
+
|
|
17
|
+
#include <stdio.h>
|
|
18
|
+
#include <string.h>
|
|
19
|
+
#include <ctype.h>
|
|
20
|
+
|
|
21
|
+
#include "args.h"
|
|
22
|
+
#include "debug.h"
|
|
23
|
+
#include "routines.h"
|
|
24
|
+
|
|
25
|
+
/*
|
|
26
|
+
* FUNCTION DEFINITIONS
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
static char *nextStringArg (const char** const next)
|
|
30
|
+
{
|
|
31
|
+
char* result = NULL;
|
|
32
|
+
const char* start;
|
|
33
|
+
|
|
34
|
+
Assert (*next != NULL);
|
|
35
|
+
for (start = *next ; isspace ((int) *start) ; ++start)
|
|
36
|
+
;
|
|
37
|
+
if (*start == '\0')
|
|
38
|
+
*next = start;
|
|
39
|
+
else
|
|
40
|
+
{
|
|
41
|
+
size_t length;
|
|
42
|
+
const char* end;
|
|
43
|
+
|
|
44
|
+
for (end = start ; *end != '\0' && ! isspace ((int) *end) ; ++end)
|
|
45
|
+
;
|
|
46
|
+
length = end - start;
|
|
47
|
+
Assert (length > 0);
|
|
48
|
+
result = xMalloc (length + 1, char);
|
|
49
|
+
strncpy (result, start, length);
|
|
50
|
+
result [length] = '\0';
|
|
51
|
+
*next = end;
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static char* nextStringLine (const char** const next)
|
|
57
|
+
{
|
|
58
|
+
char* result = NULL;
|
|
59
|
+
size_t length;
|
|
60
|
+
const char* end;
|
|
61
|
+
|
|
62
|
+
Assert (*next != NULL);
|
|
63
|
+
for (end = *next ; *end != '\n' && *end != '\0' ; ++end)
|
|
64
|
+
;
|
|
65
|
+
length = end - *next;
|
|
66
|
+
if (length > 0)
|
|
67
|
+
{
|
|
68
|
+
result = xMalloc (length + 1, char);
|
|
69
|
+
strncpy (result, *next, length);
|
|
70
|
+
result [length] = '\0';
|
|
71
|
+
}
|
|
72
|
+
if (*end == '\n')
|
|
73
|
+
++end;
|
|
74
|
+
else if (*end == '\r')
|
|
75
|
+
{
|
|
76
|
+
++end;
|
|
77
|
+
if (*end == '\n')
|
|
78
|
+
++end;
|
|
79
|
+
}
|
|
80
|
+
*next = end;
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
static char* nextString (const Arguments* const current, const char** const next)
|
|
85
|
+
{
|
|
86
|
+
char* result;
|
|
87
|
+
if (current->lineMode)
|
|
88
|
+
result = nextStringLine (next);
|
|
89
|
+
else
|
|
90
|
+
result = nextStringArg (next);
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
static char* nextFileArg (FILE* const fp)
|
|
95
|
+
{
|
|
96
|
+
char* result = NULL;
|
|
97
|
+
Assert (fp != NULL);
|
|
98
|
+
if (! feof (fp))
|
|
99
|
+
{
|
|
100
|
+
vString* vs = vStringNew ();
|
|
101
|
+
int c;
|
|
102
|
+
do
|
|
103
|
+
c = fgetc (fp);
|
|
104
|
+
while (isspace (c));
|
|
105
|
+
|
|
106
|
+
if (c != EOF)
|
|
107
|
+
{
|
|
108
|
+
do
|
|
109
|
+
{
|
|
110
|
+
vStringPut (vs, c);
|
|
111
|
+
c = fgetc (fp);
|
|
112
|
+
} while (c != EOF && ! isspace (c));
|
|
113
|
+
vStringTerminate (vs);
|
|
114
|
+
Assert (vStringLength (vs) > 0);
|
|
115
|
+
result = xMalloc (vStringLength (vs) + 1, char);
|
|
116
|
+
strcpy (result, vStringValue (vs));
|
|
117
|
+
}
|
|
118
|
+
vStringDelete (vs);
|
|
119
|
+
}
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
static char* nextFileLine (FILE* const fp)
|
|
124
|
+
{
|
|
125
|
+
char* result = NULL;
|
|
126
|
+
if (! feof (fp))
|
|
127
|
+
{
|
|
128
|
+
vString* vs = vStringNew ();
|
|
129
|
+
int c;
|
|
130
|
+
|
|
131
|
+
Assert (fp != NULL);
|
|
132
|
+
c = fgetc (fp);
|
|
133
|
+
while (c != EOF)
|
|
134
|
+
{
|
|
135
|
+
if (c != '\n' && c != '\r')
|
|
136
|
+
vStringPut (vs, c);
|
|
137
|
+
else if (vStringLength (vs) > 0)
|
|
138
|
+
break;
|
|
139
|
+
c = fgetc (fp);
|
|
140
|
+
}
|
|
141
|
+
if (c != EOF || vStringLength (vs) > 0)
|
|
142
|
+
{
|
|
143
|
+
if (c == '\r')
|
|
144
|
+
{
|
|
145
|
+
c = fgetc (fp);
|
|
146
|
+
if (c != '\n')
|
|
147
|
+
c = ungetc (c, fp);
|
|
148
|
+
}
|
|
149
|
+
vStringTerminate (vs);
|
|
150
|
+
vStringStripTrailing (vs);
|
|
151
|
+
result = xMalloc (vStringLength (vs) + 1, char);
|
|
152
|
+
strcpy (result, vStringValue (vs));
|
|
153
|
+
}
|
|
154
|
+
vStringDelete (vs);
|
|
155
|
+
}
|
|
156
|
+
return result;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
static char* nextFileString (const Arguments* const current, FILE* const fp)
|
|
160
|
+
{
|
|
161
|
+
char* result;
|
|
162
|
+
if (current->lineMode)
|
|
163
|
+
result = nextFileLine (fp);
|
|
164
|
+
else
|
|
165
|
+
result = nextFileArg (fp);
|
|
166
|
+
return result;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
extern Arguments* argNewFromString (const char* const string)
|
|
170
|
+
{
|
|
171
|
+
Arguments* result = xMalloc (1, Arguments);
|
|
172
|
+
memset (result, 0, sizeof (Arguments));
|
|
173
|
+
result->type = ARG_STRING;
|
|
174
|
+
result->u.stringArgs.string = string;
|
|
175
|
+
result->u.stringArgs.item = string;
|
|
176
|
+
result->u.stringArgs.next = string;
|
|
177
|
+
result->item = nextString (result, &result->u.stringArgs.next);
|
|
178
|
+
return result;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
extern Arguments* argNewFromArgv (char* const* const argv)
|
|
182
|
+
{
|
|
183
|
+
Arguments* result = xMalloc (1, Arguments);
|
|
184
|
+
memset (result, 0, sizeof (Arguments));
|
|
185
|
+
result->type = ARG_ARGV;
|
|
186
|
+
result->u.argvArgs.argv = argv;
|
|
187
|
+
result->u.argvArgs.item = result->u.argvArgs.argv;
|
|
188
|
+
result->item = *result->u.argvArgs.item;
|
|
189
|
+
return result;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
extern Arguments* argNewFromFile (FILE* const fp)
|
|
193
|
+
{
|
|
194
|
+
Arguments* result = xMalloc (1, Arguments);
|
|
195
|
+
memset (result, 0, sizeof (Arguments));
|
|
196
|
+
result->type = ARG_FILE;
|
|
197
|
+
result->u.fileArgs.fp = fp;
|
|
198
|
+
result->item = nextFileString (result, result->u.fileArgs.fp);
|
|
199
|
+
return result;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
extern Arguments* argNewFromLineFile (FILE* const fp)
|
|
203
|
+
{
|
|
204
|
+
Arguments* result = xMalloc (1, Arguments);
|
|
205
|
+
memset (result, 0, sizeof (Arguments));
|
|
206
|
+
result->type = ARG_FILE;
|
|
207
|
+
result->lineMode = TRUE;
|
|
208
|
+
result->u.fileArgs.fp = fp;
|
|
209
|
+
result->item = nextFileString (result, result->u.fileArgs.fp);
|
|
210
|
+
return result;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
extern char *argItem (const Arguments* const current)
|
|
214
|
+
{
|
|
215
|
+
Assert (current != NULL);
|
|
216
|
+
Assert (! argOff (current));
|
|
217
|
+
return current->item;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
extern boolean argOff (const Arguments* const current)
|
|
221
|
+
{
|
|
222
|
+
Assert (current != NULL);
|
|
223
|
+
return (boolean) (current->item == NULL);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
extern void argSetWordMode (Arguments* const current)
|
|
227
|
+
{
|
|
228
|
+
Assert (current != NULL);
|
|
229
|
+
current->lineMode = FALSE;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
extern void argSetLineMode (Arguments* const current)
|
|
233
|
+
{
|
|
234
|
+
Assert (current != NULL);
|
|
235
|
+
current->lineMode = TRUE;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
extern void argForth (Arguments* const current)
|
|
239
|
+
{
|
|
240
|
+
Assert (current != NULL);
|
|
241
|
+
Assert (! argOff (current));
|
|
242
|
+
switch (current->type)
|
|
243
|
+
{
|
|
244
|
+
case ARG_STRING:
|
|
245
|
+
if (current->item != NULL)
|
|
246
|
+
eFree (current->item);
|
|
247
|
+
current->u.stringArgs.item = current->u.stringArgs.next;
|
|
248
|
+
current->item = nextString (current, ¤t->u.stringArgs.next);
|
|
249
|
+
break;
|
|
250
|
+
case ARG_ARGV:
|
|
251
|
+
++current->u.argvArgs.item;
|
|
252
|
+
current->item = *current->u.argvArgs.item;
|
|
253
|
+
break;
|
|
254
|
+
case ARG_FILE:
|
|
255
|
+
if (current->item != NULL)
|
|
256
|
+
eFree (current->item);
|
|
257
|
+
current->item = nextFileString (current, current->u.fileArgs.fp);
|
|
258
|
+
break;
|
|
259
|
+
default:
|
|
260
|
+
Assert ("Invalid argument type" == NULL);
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
extern void argDelete (Arguments* const current)
|
|
266
|
+
{
|
|
267
|
+
Assert (current != NULL);
|
|
268
|
+
if (current->type == ARG_STRING && current->item != NULL)
|
|
269
|
+
eFree (current->item);
|
|
270
|
+
memset (current, 0, sizeof (Arguments));
|
|
271
|
+
eFree (current);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/* vi:set tabstop=4 shiftwidth=4: */
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* $Id: args.h 443 2006-05-30 04:37:13Z darren $
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 1999-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
|
+
* Defines external interface to command line argument reading.
|
|
10
|
+
*/
|
|
11
|
+
#ifndef _ARGS_H
|
|
12
|
+
#define _ARGS_H
|
|
13
|
+
|
|
14
|
+
/*
|
|
15
|
+
* INCLUDE FILES
|
|
16
|
+
*/
|
|
17
|
+
#include "general.h" /* must always come first */
|
|
18
|
+
|
|
19
|
+
#include <stdio.h>
|
|
20
|
+
|
|
21
|
+
/*
|
|
22
|
+
* DATA DECLARATIONS
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
typedef enum { ARG_NONE, ARG_STRING, ARG_ARGV, ARG_FILE } argType;
|
|
26
|
+
|
|
27
|
+
typedef struct sArgs {
|
|
28
|
+
argType type;
|
|
29
|
+
union {
|
|
30
|
+
struct sStringArgs {
|
|
31
|
+
const char* string;
|
|
32
|
+
const char* next;
|
|
33
|
+
const char* item;
|
|
34
|
+
} stringArgs;
|
|
35
|
+
struct sArgvArgs {
|
|
36
|
+
char* const* argv;
|
|
37
|
+
char* const* item;
|
|
38
|
+
} argvArgs;
|
|
39
|
+
struct sFileArgs {
|
|
40
|
+
FILE* fp;
|
|
41
|
+
} fileArgs;
|
|
42
|
+
} u;
|
|
43
|
+
char* item;
|
|
44
|
+
boolean lineMode;
|
|
45
|
+
} Arguments;
|
|
46
|
+
|
|
47
|
+
/*
|
|
48
|
+
* FUNCTION PROTOTYPES
|
|
49
|
+
*/
|
|
50
|
+
extern Arguments* argNewFromString (const char* const string);
|
|
51
|
+
extern Arguments* argNewFromArgv (char* const* const argv);
|
|
52
|
+
extern Arguments* argNewFromFile (FILE* const fp);
|
|
53
|
+
extern Arguments* argNewFromLineFile (FILE* const fp);
|
|
54
|
+
extern char *argItem (const Arguments* const current);
|
|
55
|
+
extern boolean argOff (const Arguments* const current);
|
|
56
|
+
extern void argSetWordMode (Arguments* const current);
|
|
57
|
+
extern void argSetLineMode (Arguments* const current);
|
|
58
|
+
extern void argForth (Arguments* const current);
|
|
59
|
+
extern void argDelete (Arguments* const current);
|
|
60
|
+
|
|
61
|
+
#endif /* _ARGS_H */
|
|
62
|
+
|
|
63
|
+
/* vi:set tabstop=4 shiftwidth=4: */
|
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* $Id: asm.c 536 2007-06-02 06:09:00Z elliotth $
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2000-2003, 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 functions for generating tags for assembly language
|
|
10
|
+
* files.
|
|
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 "keyword.h"
|
|
22
|
+
#include "parse.h"
|
|
23
|
+
#include "read.h"
|
|
24
|
+
#include "routines.h"
|
|
25
|
+
#include "vstring.h"
|
|
26
|
+
|
|
27
|
+
/*
|
|
28
|
+
* DATA DECLARATIONS
|
|
29
|
+
*/
|
|
30
|
+
typedef enum {
|
|
31
|
+
K_NONE = -1, K_DEFINE, K_LABEL, K_MACRO, K_TYPE
|
|
32
|
+
} AsmKind;
|
|
33
|
+
|
|
34
|
+
typedef enum {
|
|
35
|
+
OP_UNDEFINED = -1,
|
|
36
|
+
OP_ALIGN,
|
|
37
|
+
OP_COLON_EQUAL,
|
|
38
|
+
OP_END,
|
|
39
|
+
OP_ENDM,
|
|
40
|
+
OP_ENDMACRO,
|
|
41
|
+
OP_ENDP,
|
|
42
|
+
OP_ENDS,
|
|
43
|
+
OP_EQU,
|
|
44
|
+
OP_EQUAL,
|
|
45
|
+
OP_LABEL,
|
|
46
|
+
OP_MACRO,
|
|
47
|
+
OP_PROC,
|
|
48
|
+
OP_RECORD,
|
|
49
|
+
OP_SECTIONS,
|
|
50
|
+
OP_SET,
|
|
51
|
+
OP_STRUCT,
|
|
52
|
+
OP_LAST
|
|
53
|
+
} opKeyword;
|
|
54
|
+
|
|
55
|
+
typedef struct {
|
|
56
|
+
const char *operator;
|
|
57
|
+
opKeyword keyword;
|
|
58
|
+
} asmKeyword;
|
|
59
|
+
|
|
60
|
+
typedef struct {
|
|
61
|
+
opKeyword keyword;
|
|
62
|
+
AsmKind kind;
|
|
63
|
+
} opKind;
|
|
64
|
+
|
|
65
|
+
/*
|
|
66
|
+
* DATA DEFINITIONS
|
|
67
|
+
*/
|
|
68
|
+
static langType Lang_asm;
|
|
69
|
+
|
|
70
|
+
static kindOption AsmKinds [] = {
|
|
71
|
+
{ TRUE, 'd', "define", "defines" },
|
|
72
|
+
{ TRUE, 'l', "label", "labels" },
|
|
73
|
+
{ TRUE, 'm', "macro", "macros" },
|
|
74
|
+
{ TRUE, 't', "type", "types (structs and records)" }
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
static const asmKeyword AsmKeywords [] = {
|
|
78
|
+
{ "align", OP_ALIGN },
|
|
79
|
+
{ "endmacro", OP_ENDMACRO },
|
|
80
|
+
{ "endm", OP_ENDM },
|
|
81
|
+
{ "end", OP_END },
|
|
82
|
+
{ "endp", OP_ENDP },
|
|
83
|
+
{ "ends", OP_ENDS },
|
|
84
|
+
{ "equ", OP_EQU },
|
|
85
|
+
{ "label", OP_LABEL },
|
|
86
|
+
{ "macro", OP_MACRO },
|
|
87
|
+
{ ":=", OP_COLON_EQUAL },
|
|
88
|
+
{ "=", OP_EQUAL },
|
|
89
|
+
{ "proc", OP_PROC },
|
|
90
|
+
{ "record", OP_RECORD },
|
|
91
|
+
{ "sections", OP_SECTIONS },
|
|
92
|
+
{ "set", OP_SET },
|
|
93
|
+
{ "struct", OP_STRUCT }
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
static const opKind OpKinds [] = {
|
|
97
|
+
/* must be ordered same as opKeyword enumeration */
|
|
98
|
+
{ OP_ALIGN, K_NONE },
|
|
99
|
+
{ OP_COLON_EQUAL, K_DEFINE },
|
|
100
|
+
{ OP_END, K_NONE },
|
|
101
|
+
{ OP_ENDM, K_NONE },
|
|
102
|
+
{ OP_ENDMACRO, K_NONE },
|
|
103
|
+
{ OP_ENDP, K_NONE },
|
|
104
|
+
{ OP_ENDS, K_NONE },
|
|
105
|
+
{ OP_EQU, K_DEFINE },
|
|
106
|
+
{ OP_EQUAL, K_DEFINE },
|
|
107
|
+
{ OP_LABEL, K_LABEL },
|
|
108
|
+
{ OP_MACRO, K_MACRO },
|
|
109
|
+
{ OP_PROC, K_LABEL },
|
|
110
|
+
{ OP_RECORD, K_TYPE },
|
|
111
|
+
{ OP_SECTIONS, K_NONE },
|
|
112
|
+
{ OP_SET, K_DEFINE },
|
|
113
|
+
{ OP_STRUCT, K_TYPE }
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
/*
|
|
117
|
+
* FUNCTION DEFINITIONS
|
|
118
|
+
*/
|
|
119
|
+
static void buildAsmKeywordHash (void)
|
|
120
|
+
{
|
|
121
|
+
const size_t count = sizeof (AsmKeywords) / sizeof (AsmKeywords [0]);
|
|
122
|
+
size_t i;
|
|
123
|
+
for (i = 0 ; i < count ; ++i)
|
|
124
|
+
{
|
|
125
|
+
const asmKeyword* const p = AsmKeywords + i;
|
|
126
|
+
addKeyword (p->operator, Lang_asm, (int) p->keyword);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
static opKeyword analyzeOperator (const vString *const op)
|
|
131
|
+
{
|
|
132
|
+
vString *keyword = vStringNew ();
|
|
133
|
+
opKeyword result;
|
|
134
|
+
|
|
135
|
+
vStringCopyToLower (keyword, op);
|
|
136
|
+
result = (opKeyword) lookupKeyword (vStringValue (keyword), Lang_asm);
|
|
137
|
+
vStringDelete (keyword);
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
static boolean isInitialSymbolCharacter (int c)
|
|
142
|
+
{
|
|
143
|
+
return (boolean) (c != '\0' && (isalpha (c) || strchr ("_$", c) != NULL));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
static boolean isSymbolCharacter (int c)
|
|
147
|
+
{
|
|
148
|
+
/* '?' character is allowed in AMD 29K family */
|
|
149
|
+
return (boolean) (c != '\0' && (isalnum (c) || strchr ("_$?", c) != NULL));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
static boolean readPreProc (const unsigned char *const line)
|
|
153
|
+
{
|
|
154
|
+
boolean result;
|
|
155
|
+
const unsigned char *cp = line;
|
|
156
|
+
vString *name = vStringNew ();
|
|
157
|
+
while (isSymbolCharacter ((int) *cp))
|
|
158
|
+
{
|
|
159
|
+
vStringPut (name, *cp);
|
|
160
|
+
++cp;
|
|
161
|
+
}
|
|
162
|
+
vStringTerminate (name);
|
|
163
|
+
result = (boolean) (strcmp (vStringValue (name), "define") == 0);
|
|
164
|
+
if (result)
|
|
165
|
+
{
|
|
166
|
+
while (isspace ((int) *cp))
|
|
167
|
+
++cp;
|
|
168
|
+
vStringClear (name);
|
|
169
|
+
while (isSymbolCharacter ((int) *cp))
|
|
170
|
+
{
|
|
171
|
+
vStringPut (name, *cp);
|
|
172
|
+
++cp;
|
|
173
|
+
}
|
|
174
|
+
vStringTerminate (name);
|
|
175
|
+
makeSimpleTag (name, AsmKinds, K_DEFINE);
|
|
176
|
+
}
|
|
177
|
+
vStringDelete (name);
|
|
178
|
+
return result;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
static AsmKind operatorKind (
|
|
182
|
+
const vString *const operator,
|
|
183
|
+
boolean *const found)
|
|
184
|
+
{
|
|
185
|
+
AsmKind result = K_NONE;
|
|
186
|
+
const opKeyword kw = analyzeOperator (operator);
|
|
187
|
+
*found = (boolean) (kw != OP_UNDEFINED);
|
|
188
|
+
if (*found)
|
|
189
|
+
{
|
|
190
|
+
result = OpKinds [kw].kind;
|
|
191
|
+
Assert (OpKinds [kw].keyword == kw);
|
|
192
|
+
}
|
|
193
|
+
return result;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/* We must check for "DB", "DB.L", "DCB.W" (68000)
|
|
197
|
+
*/
|
|
198
|
+
static boolean isDefineOperator (const vString *const operator)
|
|
199
|
+
{
|
|
200
|
+
const unsigned char *const op =
|
|
201
|
+
(unsigned char*) vStringValue (operator);
|
|
202
|
+
const size_t length = vStringLength (operator);
|
|
203
|
+
const boolean result = (boolean) (length > 0 &&
|
|
204
|
+
toupper ((int) *op) == 'D' &&
|
|
205
|
+
(length == 2 ||
|
|
206
|
+
(length == 4 && (int) op [2] == '.') ||
|
|
207
|
+
(length == 5 && (int) op [3] == '.')));
|
|
208
|
+
return result;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
static void makeAsmTag (
|
|
212
|
+
const vString *const name,
|
|
213
|
+
const vString *const operator,
|
|
214
|
+
const boolean labelCandidate,
|
|
215
|
+
const boolean nameFollows)
|
|
216
|
+
{
|
|
217
|
+
if (vStringLength (name) > 0)
|
|
218
|
+
{
|
|
219
|
+
boolean found;
|
|
220
|
+
const AsmKind kind = operatorKind (operator, &found);
|
|
221
|
+
if (found)
|
|
222
|
+
{
|
|
223
|
+
if (kind != K_NONE)
|
|
224
|
+
makeSimpleTag (name, AsmKinds, kind);
|
|
225
|
+
}
|
|
226
|
+
else if (isDefineOperator (operator))
|
|
227
|
+
{
|
|
228
|
+
if (! nameFollows)
|
|
229
|
+
makeSimpleTag (name, AsmKinds, K_DEFINE);
|
|
230
|
+
}
|
|
231
|
+
else if (labelCandidate)
|
|
232
|
+
{
|
|
233
|
+
operatorKind (name, &found);
|
|
234
|
+
if (! found)
|
|
235
|
+
makeSimpleTag (name, AsmKinds, K_LABEL);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
static const unsigned char *readSymbol (
|
|
241
|
+
const unsigned char *const start,
|
|
242
|
+
vString *const sym)
|
|
243
|
+
{
|
|
244
|
+
const unsigned char *cp = start;
|
|
245
|
+
vStringClear (sym);
|
|
246
|
+
if (isInitialSymbolCharacter ((int) *cp))
|
|
247
|
+
{
|
|
248
|
+
while (isSymbolCharacter ((int) *cp))
|
|
249
|
+
{
|
|
250
|
+
vStringPut (sym, *cp);
|
|
251
|
+
++cp;
|
|
252
|
+
}
|
|
253
|
+
vStringTerminate (sym);
|
|
254
|
+
}
|
|
255
|
+
return cp;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
static const unsigned char *readOperator (
|
|
259
|
+
const unsigned char *const start,
|
|
260
|
+
vString *const operator)
|
|
261
|
+
{
|
|
262
|
+
const unsigned char *cp = start;
|
|
263
|
+
vStringClear (operator);
|
|
264
|
+
while (*cp != '\0' && ! isspace ((int) *cp))
|
|
265
|
+
{
|
|
266
|
+
vStringPut (operator, *cp);
|
|
267
|
+
++cp;
|
|
268
|
+
}
|
|
269
|
+
vStringTerminate (operator);
|
|
270
|
+
return cp;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
static void findAsmTags (void)
|
|
274
|
+
{
|
|
275
|
+
vString *name = vStringNew ();
|
|
276
|
+
vString *operator = vStringNew ();
|
|
277
|
+
const unsigned char *line;
|
|
278
|
+
boolean inCComment = FALSE;
|
|
279
|
+
|
|
280
|
+
while ((line = fileReadLine ()) != NULL)
|
|
281
|
+
{
|
|
282
|
+
const unsigned char *cp = line;
|
|
283
|
+
boolean labelCandidate = (boolean) (! isspace ((int) *cp));
|
|
284
|
+
boolean nameFollows = FALSE;
|
|
285
|
+
const boolean isComment = (boolean)
|
|
286
|
+
(*cp != '\0' && strchr (";*@", *cp) != NULL);
|
|
287
|
+
|
|
288
|
+
/* skip comments */
|
|
289
|
+
if (strncmp ((const char*) cp, "/*", (size_t) 2) == 0)
|
|
290
|
+
{
|
|
291
|
+
inCComment = TRUE;
|
|
292
|
+
cp += 2;
|
|
293
|
+
}
|
|
294
|
+
if (inCComment)
|
|
295
|
+
{
|
|
296
|
+
do
|
|
297
|
+
{
|
|
298
|
+
if (strncmp ((const char*) cp, "*/", (size_t) 2) == 0)
|
|
299
|
+
{
|
|
300
|
+
inCComment = FALSE;
|
|
301
|
+
cp += 2;
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
++cp;
|
|
305
|
+
} while (*cp != '\0');
|
|
306
|
+
}
|
|
307
|
+
if (isComment || inCComment)
|
|
308
|
+
continue;
|
|
309
|
+
|
|
310
|
+
/* read preprocessor defines */
|
|
311
|
+
if (*cp == '#')
|
|
312
|
+
{
|
|
313
|
+
++cp;
|
|
314
|
+
readPreProc (cp);
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/* skip white space */
|
|
319
|
+
while (isspace ((int) *cp))
|
|
320
|
+
++cp;
|
|
321
|
+
|
|
322
|
+
/* read symbol */
|
|
323
|
+
cp = readSymbol (cp, name);
|
|
324
|
+
if (vStringLength (name) > 0 && *cp == ':')
|
|
325
|
+
{
|
|
326
|
+
labelCandidate = TRUE;
|
|
327
|
+
++cp;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
if (! isspace ((int) *cp) && *cp != '\0')
|
|
331
|
+
continue;
|
|
332
|
+
|
|
333
|
+
/* skip white space */
|
|
334
|
+
while (isspace ((int) *cp))
|
|
335
|
+
++cp;
|
|
336
|
+
|
|
337
|
+
/* skip leading dot */
|
|
338
|
+
#if 0
|
|
339
|
+
if (*cp == '.')
|
|
340
|
+
++cp;
|
|
341
|
+
#endif
|
|
342
|
+
|
|
343
|
+
cp = readOperator (cp, operator);
|
|
344
|
+
|
|
345
|
+
/* attempt second read of symbol */
|
|
346
|
+
if (vStringLength (name) == 0)
|
|
347
|
+
{
|
|
348
|
+
while (isspace ((int) *cp))
|
|
349
|
+
++cp;
|
|
350
|
+
cp = readSymbol (cp, name);
|
|
351
|
+
nameFollows = TRUE;
|
|
352
|
+
}
|
|
353
|
+
makeAsmTag (name, operator, labelCandidate, nameFollows);
|
|
354
|
+
}
|
|
355
|
+
vStringDelete (name);
|
|
356
|
+
vStringDelete (operator);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
static void initialize (const langType language)
|
|
360
|
+
{
|
|
361
|
+
Lang_asm = language;
|
|
362
|
+
buildAsmKeywordHash ();
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
extern parserDefinition* AsmParser (void)
|
|
366
|
+
{
|
|
367
|
+
static const char *const extensions [] = {
|
|
368
|
+
"asm", "ASM", "s", "S", NULL
|
|
369
|
+
};
|
|
370
|
+
static const char *const patterns [] = {
|
|
371
|
+
"*.A51",
|
|
372
|
+
"*.29[kK]",
|
|
373
|
+
"*.[68][68][kKsSxX]",
|
|
374
|
+
"*.[xX][68][68]",
|
|
375
|
+
NULL
|
|
376
|
+
};
|
|
377
|
+
parserDefinition* def = parserNew ("Asm");
|
|
378
|
+
def->kinds = AsmKinds;
|
|
379
|
+
def->kindCount = KIND_COUNT (AsmKinds);
|
|
380
|
+
def->extensions = extensions;
|
|
381
|
+
def->patterns = patterns;
|
|
382
|
+
def->parser = findAsmTags;
|
|
383
|
+
def->initialize = initialize;
|
|
384
|
+
return def;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/* vi:set tabstop=4 shiftwidth=4: */
|