📄 asm.c
字号:
/** $Id: asm.c,v 1.17 2003/07/17 03:08:23 darren Exp $** Copyright (c) 2000-2003, Darren Hiebert** This source code is released for free distribution under the terms of the* GNU General Public License.** This module contains functions for generating tags for assembly language* files.*//** INCLUDE FILES*/#include "general.h" /* must always come first */#include <string.h>#include "debug.h"#include "keyword.h"#include "parse.h"#include "read.h"#include "routines.h"#include "vstring.h"/** DATA DECLARATIONS*/typedef enum { K_NONE = -1, K_DEFINE, K_LABEL, K_MACRO, K_TYPE} AsmKind;typedef enum { OP_UNDEFINED = -1, OP_ALIGN, OP_COLON_EQUAL, OP_END, OP_ENDM, OP_ENDMACRO, OP_ENDP, OP_ENDS, OP_EQU, OP_EQUAL, OP_LABEL, OP_MACRO, OP_PROC, OP_RECORD, OP_SECTIONS, OP_SET, OP_STRUCT, OP_LAST} opKeyword;typedef struct { const char *operator; opKeyword keyword;} asmKeyword;typedef struct { opKeyword keyword; AsmKind kind;} opKind;/** DATA DEFINITIONS*/static langType Lang_asm;static kindOption AsmKinds [] = { { TRUE, 'd', "define", "defines" }, { TRUE, 'l', "label", "labels" }, { TRUE, 'm', "macro", "macros" }, { TRUE, 't', "type", "types (structs and records)" }};static const asmKeyword AsmKeywords [] = { { "align", OP_ALIGN }, { "endmacro", OP_ENDMACRO }, { "endm", OP_ENDM }, { "end", OP_END }, { "endp", OP_ENDP }, { "ends", OP_ENDS }, { "equ", OP_EQU }, { "label", OP_LABEL }, { "macro", OP_MACRO }, { ":=", OP_COLON_EQUAL }, { "=", OP_EQUAL }, { "proc", OP_PROC }, { "record", OP_RECORD }, { "sections", OP_SECTIONS }, { "set", OP_SET }, { "struct", OP_STRUCT }};static const opKind OpKinds [] = { /* must be ordered same as opKeyword enumeration */ { OP_ALIGN, K_NONE }, { OP_COLON_EQUAL, K_DEFINE }, { OP_END, K_NONE }, { OP_ENDM, K_NONE }, { OP_ENDMACRO, K_NONE }, { OP_ENDP, K_NONE }, { OP_ENDS, K_NONE }, { OP_EQU, K_DEFINE }, { OP_EQUAL, K_DEFINE }, { OP_LABEL, K_LABEL }, { OP_MACRO, K_MACRO }, { OP_PROC, K_LABEL }, { OP_RECORD, K_TYPE }, { OP_SECTIONS, K_NONE }, { OP_SET, K_DEFINE }, { OP_STRUCT, K_TYPE }};/** FUNCTION DEFINITIONS*/static void buildAsmKeywordHash (void){ const size_t count = sizeof (AsmKeywords) / sizeof (AsmKeywords [0]); size_t i; for (i = 0 ; i < count ; ++i) { const asmKeyword* const p = AsmKeywords + i; addKeyword (p->operator, Lang_asm, (int) p->keyword); }}static opKeyword analyzeOperator (const vString *const op){ static vString *keyword = NULL; opKeyword result = OP_UNDEFINED; if (keyword == NULL) keyword = vStringNew (); vStringCopyToLower (keyword, op); result = (opKeyword) lookupKeyword (vStringValue (keyword), Lang_asm); return result;}static boolean isInitialSymbolCharacter (int c){ return (boolean) (c != '\0' && (isalpha (c) || strchr ("_$", c) != NULL));}static boolean isSymbolCharacter (int c){ /* '?' character is allowed in AMD 29K family */ return (boolean) (c != '\0' && (isalnum (c) || strchr ("_$?", c) != NULL));}static boolean readPreProc (const unsigned char *const line){ boolean result; const unsigned char *cp = line; vString *name = vStringNew (); while (isSymbolCharacter ((int) *cp)) { vStringPut (name, *cp); ++cp; } vStringTerminate (name); result = (boolean) (strcmp (vStringValue (name), "define") == 0); if (result) { while (isspace ((int) *cp)) ++cp; vStringClear (name); while (isSymbolCharacter ((int) *cp)) { vStringPut (name, *cp); ++cp; } vStringTerminate (name); makeSimpleTag (name, AsmKinds, K_DEFINE); } vStringDelete (name); return result;}static AsmKind operatorKind ( const vString *const operator, boolean *const found){ AsmKind result = K_NONE; const opKeyword kw = analyzeOperator (operator); *found = (boolean) (kw != OP_UNDEFINED); if (*found) { result = OpKinds [kw].kind; Assert (OpKinds [kw].keyword == kw); } return result;}/* We must check for "DB", "DB.L", "DCB.W" (68000) */static boolean isDefineOperator (const vString *const operator){ const unsigned char *const op = (unsigned char*) vStringValue (operator); const size_t length = vStringLength (operator); const boolean result = (boolean) (length > 0 && toupper ((int) *op) == 'D' && (length == 2 || (length == 4 && (int) op [2] == '.') || (length == 5 && (int) op [3] == '.'))); return result;}static void makeAsmTag ( const vString *const name, const vString *const operator, const boolean labelCandidate, const boolean nameFollows){ if (vStringLength (name) > 0) { boolean found; const AsmKind kind = operatorKind (operator, &found); if (found) { if (kind != K_NONE) makeSimpleTag (name, AsmKinds, kind); } else if (isDefineOperator (operator)) { if (! nameFollows) makeSimpleTag (name, AsmKinds, K_DEFINE); } else if (labelCandidate) { operatorKind (name, &found); if (! found) makeSimpleTag (name, AsmKinds, K_LABEL); } }}static const unsigned char *readSymbol ( const unsigned char *const start, vString *const sym){ const unsigned char *cp = start; vStringClear (sym); if (isInitialSymbolCharacter ((int) *cp)) { while (isSymbolCharacter ((int) *cp)) { vStringPut (sym, *cp); ++cp; } vStringTerminate (sym); } return cp;}static const unsigned char *readOperator ( const unsigned char *const start, vString *const operator){ const unsigned char *cp = start; vStringClear (operator); while (*cp != '\0' && ! isspace ((int) *cp)) { vStringPut (operator, *cp); ++cp; } vStringTerminate (operator); return cp;}static void findAsmTags (void){ vString *name = vStringNew (); vString *operator = vStringNew (); const unsigned char *line; boolean inCComment = FALSE; while ((line = fileReadLine ()) != NULL) { const unsigned char *cp = line; boolean labelCandidate = (boolean) (! isspace ((int) *cp)); boolean nameFollows = FALSE; const boolean isComment = (boolean) (*cp != '\0' && strchr (";*@", *cp) != NULL); /* skip comments */ if (strncmp ((const char*) cp, "/*", (size_t) 2) == 0) { inCComment = TRUE; cp += 2; } if (inCComment) { do { if (strncmp ((const char*) cp, "*/", (size_t) 2) == 0) { inCComment = FALSE; cp += 2; break; } ++cp; } while (*cp != '\0'); } if (isComment || inCComment) continue; /* read preprocessor defines */ if (*cp == '#') { ++cp; readPreProc (cp); continue; } /* skip white space */ while (isspace ((int) *cp)) ++cp; /* read symbol */ cp = readSymbol (cp, name); if (vStringLength (name) > 0 && *cp == ':') { labelCandidate = TRUE; ++cp; } if (! isspace ((int) *cp) && *cp != '\0') continue; /* skip white space */ while (isspace ((int) *cp)) ++cp; /* skip leading dot */#if 0 if (*cp == '.') ++cp;#endif cp = readOperator (cp, operator); /* attempt second read of symbol */ if (vStringLength (name) == 0) { while (isspace ((int) *cp)) ++cp; cp = readSymbol (cp, name); nameFollows = TRUE; } makeAsmTag (name, operator, labelCandidate, nameFollows); } vStringDelete (name); vStringDelete (operator);}static void initialize (const langType language){ Lang_asm = language; buildAsmKeywordHash ();}extern parserDefinition* AsmParser (void){ static const char *const extensions [] = { "asm", "ASM", "s", "S", NULL }; static const char *const patterns [] = { "*.A51", "*.29[kK]", "*.[68][68][kKsSxX]", "*.[xX][68][68]", NULL }; parserDefinition* def = parserNew ("Asm"); def->kinds = AsmKinds; def->kindCount = KIND_COUNT (AsmKinds); def->extensions = extensions; def->patterns = patterns; def->parser = findAsmTags; def->initialize = initialize; return def;}/* vi:set tabstop=8 shiftwidth=4: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -