15
#include "general.h" /* must always come first */
16
#include "general.h" /* must always come first */
17
18
#include <string.h>
21
24
#include "vstring.h"
30
K_NONE = -1, K_DEFINE, K_LABEL, K_MACRO, K_TYPE
27
K_DEFINE, K_LABEL, K_MACRO
67
static langType Lang_asm;
30
/* indexed by asmKind */
31
69
static kindOption AsmKinds [] = {
32
{ TRUE, 'd', "define", "defines (names assigned a specified value)"},
33
{ TRUE, 'l', "label", "labels (names assigned an address)"},
34
{ TRUE, 'm', "macro", "macros"}
70
{ TRUE, 'd', "macro", "defines" },
71
{ TRUE, 'l', "namespace", "labels" },
72
{ TRUE, 'm', "function", "macros" },
73
{ TRUE, 't', "struct", "types (structs and records)" }
76
static const asmKeyword AsmKeywords [] = {
77
{ "align", OP_ALIGN },
78
{ "endmacro", OP_ENDMACRO },
84
{ "label", OP_LABEL },
85
{ "macro", OP_MACRO },
86
{ ":=", OP_COLON_EQUAL },
89
{ "record", OP_RECORD },
90
{ "sections", OP_SECTIONS },
92
{ "struct", OP_STRUCT }
95
static const opKind OpKinds [] = {
96
/* must be ordered same as opKeyword enumeration */
98
{ OP_COLON_EQUAL, K_DEFINE },
101
{ OP_ENDMACRO, K_NONE },
104
{ OP_EQU, K_DEFINE },
105
{ OP_EQUAL, K_DEFINE },
106
{ OP_LABEL, K_LABEL },
107
{ OP_MACRO, K_MACRO },
108
{ OP_PROC, K_LABEL },
109
{ OP_RECORD, K_TYPE },
110
{ OP_SECTIONS, K_NONE },
111
{ OP_SET, K_DEFINE },
112
{ OP_STRUCT, K_TYPE }
38
116
* FUNCTION DEFINITIONS
41
/* Algorithm adapted from from GNU etags.
42
* By Bob Weiner, Motorola Inc., 4/3/94
43
* Unix and microcontroller assembly tag handling
44
* look for '^ [a-zA-Z_.$] [a-zA_Z0-9_.$]*[: ^I^J]'
46
static void findAsmTags (void)
48
vString *name = vStringNew ();
49
const unsigned char *line;
51
while ((line = fileReadLine ()) != NULL)
118
static void buildAsmKeywordHash (void)
120
const size_t count = sizeof (AsmKeywords) / sizeof (AsmKeywords [0]);
122
for (i = 0 ; i < count ; ++i)
124
const asmKeyword* const p = AsmKeywords + i;
125
addKeyword (p->operator, Lang_asm, (int) p->keyword);
129
static opKeyword analyzeOperator (const vString *const op)
131
vString *keyword = vStringNew ();
134
vStringCopyToLower (keyword, op);
135
result = (opKeyword) lookupKeyword (vStringValue (keyword), Lang_asm);
136
vStringDelete (keyword);
140
static boolean isInitialSymbolCharacter (int c)
142
return (boolean) (c != '\0' && (isalpha (c) || strchr ("_$", c) != NULL));
145
static boolean isSymbolCharacter (int c)
147
/* '?' character is allowed in AMD 29K family */
148
return (boolean) (c != '\0' && (isalnum (c) || strchr ("_$?", c) != NULL));
151
static boolean readPreProc (const unsigned char *const line)
53
154
const unsigned char *cp = line;
56
/* If first char is alphabetic or one of [_.$], test for colon
57
* following identifier.
59
if (isalpha (c) || c == '_' || c == '.' || c == '$')
63
while (isalnum (c) || c == '_' || c == '.' || c == '$')
68
vStringTerminate (name);
72
makeSimpleTag (name, AsmKinds, K_LABEL);
74
strncmp ((const char*) cp, "equ", (size_t) 3) == 0)
75
makeSimpleTag (name, AsmKinds, K_DEFINE);
76
else if (strcmp (vStringValue (name), ".macro") == 0)
155
vString *name = vStringNew ();
156
while (isSymbolCharacter ((int) *cp))
158
vStringPut (name, *cp);
161
vStringTerminate (name);
162
result = (boolean) (strcmp (vStringValue (name), "define") == 0);
165
while (isspace ((int) *cp))
78
167
vStringClear (name);
79
while (isalnum (c) || c == '_')
168
while (isSymbolCharacter ((int) *cp))
170
vStringPut (name, *cp);
84
173
vStringTerminate (name);
85
if (vStringLength (name) > 0)
86
makeSimpleTag (name, AsmKinds, K_MACRO);
174
makeSimpleTag (name, AsmKinds, K_DEFINE);
176
vStringDelete (name);
180
static AsmKind operatorKind (
181
const vString *const operator,
182
boolean *const found)
184
AsmKind result = K_NONE;
185
const opKeyword kw = analyzeOperator (operator);
186
*found = (boolean) (kw != OP_UNDEFINED);
189
result = OpKinds [kw].kind;
190
Assert (OpKinds [kw].keyword == kw);
195
/* We must check for "DB", "DB.L", "DCB.W" (68000)
197
static boolean isDefineOperator (const vString *const operator)
199
const unsigned char *const op =
200
(unsigned char*) vStringValue (operator);
201
const size_t length = vStringLength (operator);
202
const boolean result = (boolean) (length > 0 &&
203
toupper ((int) *op) == 'D' &&
205
(length == 4 && (int) op [2] == '.') ||
206
(length == 5 && (int) op [3] == '.')));
210
static void makeAsmTag (
211
const vString *const name,
212
const vString *const operator,
213
const boolean labelCandidate,
214
const boolean nameFollows)
216
if (vStringLength (name) > 0)
219
const AsmKind kind = operatorKind (operator, &found);
223
makeSimpleTag (name, AsmKinds, kind);
225
else if (isDefineOperator (operator))
228
makeSimpleTag (name, AsmKinds, K_DEFINE);
230
else if (labelCandidate)
232
operatorKind (name, &found);
234
makeSimpleTag (name, AsmKinds, K_LABEL);
239
static const unsigned char *readSymbol (
240
const unsigned char *const start,
243
const unsigned char *cp = start;
245
if (isInitialSymbolCharacter ((int) *cp))
247
while (isSymbolCharacter ((int) *cp))
249
vStringPut (sym, *cp);
252
vStringTerminate (sym);
257
static const unsigned char *readOperator (
258
const unsigned char *const start,
259
vString *const operator)
261
const unsigned char *cp = start;
262
vStringClear (operator);
263
while (*cp != '\0' && ! isspace ((int) *cp))
265
vStringPut (operator, *cp);
268
vStringTerminate (operator);
272
static void findAsmTags (void)
274
vString *name = vStringNew ();
275
vString *operator = vStringNew ();
276
const unsigned char *line;
277
boolean inCComment = FALSE;
279
while ((line = fileReadLine ()) != NULL)
281
const unsigned char *cp = line;
282
boolean labelCandidate = (boolean) (! isspace ((int) *cp));
283
boolean nameFollows = FALSE;
284
const boolean isComment = (boolean)
285
(*cp != '\0' && strchr (";*@", *cp) != NULL);
288
if (strncmp ((const char*) cp, "/*", (size_t) 2) == 0)
297
if (strncmp ((const char*) cp, "*/", (size_t) 2) == 0)
304
} while (*cp != '\0');
306
if (isComment || inCComment)
309
/* read preprocessor defines */
317
/* skip white space */
318
while (isspace ((int) *cp))
322
cp = readSymbol (cp, name);
323
if (vStringLength (name) > 0 && *cp == ':')
325
labelCandidate = TRUE;
329
if (! isspace ((int) *cp) && *cp != '\0')
332
/* skip white space */
333
while (isspace ((int) *cp))
336
/* skip leading dot */
342
cp = readOperator (cp, operator);
344
/* attempt second read of symbol */
345
if (vStringLength (name) == 0)
347
while (isspace ((int) *cp))
349
cp = readSymbol (cp, name);
352
makeAsmTag (name, operator, labelCandidate, nameFollows);
354
vStringDelete (name);
355
vStringDelete (operator);
358
static void initialize (const langType language)
361
buildAsmKeywordHash ();
94
364
extern parserDefinition* AsmParser (void)
96
static const char *const extensions [] = { "asm", "s", "S", NULL };
97
parserDefinition* def = parserNew ("ASM");
98
def->kinds = AsmKinds;
99
def->kindCount = KIND_COUNT (AsmKinds);
100
def->extensions = extensions;
101
def->parser = findAsmTags;
366
static const char *const extensions [] = {
367
"asm", "ASM", "s", "S", NULL
369
static const char *const patterns [] = {
372
"*.[68][68][kKsSxX]",
376
parserDefinition* def = parserNew ("Asm");
377
def->kinds = AsmKinds;
378
def->kindCount = KIND_COUNT (AsmKinds);
379
def->extensions = extensions;
380
def->patterns = patterns;
381
def->parser = findAsmTags;
382
def->initialize = initialize;
105
/* vi:set tabstop=8 shiftwidth=4: */
386
/* vi:set tabstop=4 shiftwidth=4: */