xref: /Universal-ctags/parsers/asm.c (revision aaaac7eeac8399141aa8e6d9e6ec0379931848b2)
13ae02089SMasatake YAMATO /*
23ae02089SMasatake YAMATO *   Copyright (c) 2000-2003, Darren Hiebert
33ae02089SMasatake YAMATO *
43ae02089SMasatake YAMATO *   This source code is released for free distribution under the terms of the
50ce38835Sviccuad *   GNU General Public License version 2 or (at your option) any later version.
63ae02089SMasatake YAMATO *
73ae02089SMasatake YAMATO *   This module contains functions for generating tags for assembly language
83ae02089SMasatake YAMATO *   files.
93ae02089SMasatake YAMATO */
103ae02089SMasatake YAMATO 
113ae02089SMasatake YAMATO /*
123ae02089SMasatake YAMATO *   INCLUDE FILES
133ae02089SMasatake YAMATO */
143ae02089SMasatake YAMATO #include "general.h"  /* must always come first */
153ae02089SMasatake YAMATO 
163ae02089SMasatake YAMATO #include <string.h>
173ae02089SMasatake YAMATO 
1887214e15SMasatake YAMATO #include "cpreprocessor.h"
193ae02089SMasatake YAMATO #include "debug.h"
2014781660SMasatake YAMATO #include "entry.h"
213ae02089SMasatake YAMATO #include "keyword.h"
223ae02089SMasatake YAMATO #include "parse.h"
233ae02089SMasatake YAMATO #include "read.h"
243ae02089SMasatake YAMATO #include "routines.h"
25ab3b3869SMasatake YAMATO #include "selectors.h"
263ae02089SMasatake YAMATO #include "vstring.h"
273ae02089SMasatake YAMATO 
283ae02089SMasatake YAMATO /*
293ae02089SMasatake YAMATO *   DATA DECLARATIONS
303ae02089SMasatake YAMATO */
313ae02089SMasatake YAMATO typedef enum {
3264a990a1SMasatake YAMATO 	K_PSUEDO_MACRO_END = -2,
332e62bfe5SMasatake YAMATO 	K_NONE = -1, K_DEFINE, K_LABEL, K_MACRO, K_TYPE,
342e62bfe5SMasatake YAMATO 	K_SECTION,
3512ab91a0SMasatake YAMATO 	K_PARAM,
363ae02089SMasatake YAMATO } AsmKind;
373ae02089SMasatake YAMATO 
383ae02089SMasatake YAMATO typedef enum {
393ae02089SMasatake YAMATO 	OP_UNDEFINED = -1,
403ae02089SMasatake YAMATO 	OP_ALIGN,
413ae02089SMasatake YAMATO 	OP_COLON_EQUAL,
423ae02089SMasatake YAMATO 	OP_END,
433ae02089SMasatake YAMATO 	OP_ENDM,
443ae02089SMasatake YAMATO 	OP_ENDMACRO,
453ae02089SMasatake YAMATO 	OP_ENDP,
463ae02089SMasatake YAMATO 	OP_ENDS,
473ae02089SMasatake YAMATO 	OP_EQU,
483ae02089SMasatake YAMATO 	OP_EQUAL,
493ae02089SMasatake YAMATO 	OP_LABEL,
503ae02089SMasatake YAMATO 	OP_MACRO,
513ae02089SMasatake YAMATO 	OP_PROC,
523ae02089SMasatake YAMATO 	OP_RECORD,
533ae02089SMasatake YAMATO 	OP_SECTIONS,
542e62bfe5SMasatake YAMATO 	OP_SECTION,
553ae02089SMasatake YAMATO 	OP_SET,
563ae02089SMasatake YAMATO 	OP_STRUCT,
573ae02089SMasatake YAMATO 	OP_LAST
583ae02089SMasatake YAMATO } opKeyword;
593ae02089SMasatake YAMATO 
602e62bfe5SMasatake YAMATO typedef enum {
612e62bfe5SMasatake YAMATO 	ASM_SECTION_PLACEMENT,
622e62bfe5SMasatake YAMATO } asmSectionRole;
632e62bfe5SMasatake YAMATO 
643ae02089SMasatake YAMATO typedef struct {
653ae02089SMasatake YAMATO 	opKeyword keyword;
663ae02089SMasatake YAMATO 	AsmKind kind;
673ae02089SMasatake YAMATO } opKind;
683ae02089SMasatake YAMATO 
6995f7e705SMasatake YAMATO typedef enum {
7095f7e705SMasatake YAMATO 	F_PROPERTIES,
7195f7e705SMasatake YAMATO } asmField;
7295f7e705SMasatake YAMATO 
7395f7e705SMasatake YAMATO static fieldDefinition AsmFields[] = {
7495f7e705SMasatake YAMATO 	{ .name = "properties",
7595f7e705SMasatake YAMATO 	  .description = "properties (req, vararg for parameters)",
7695f7e705SMasatake YAMATO 	  .enabled = true },
7795f7e705SMasatake YAMATO };
7895f7e705SMasatake YAMATO 
793ae02089SMasatake YAMATO /*
803ae02089SMasatake YAMATO *   DATA DEFINITIONS
813ae02089SMasatake YAMATO */
823ae02089SMasatake YAMATO static langType Lang_asm;
833ae02089SMasatake YAMATO 
8413457258SMasatake YAMATO static roleDefinition asmSectionRoles [] = {
852e62bfe5SMasatake YAMATO 	{ true, "placement", "placement where the assembled code goes" },
862e62bfe5SMasatake YAMATO };
872e62bfe5SMasatake YAMATO 
88e112e8abSMasatake YAMATO static kindDefinition AsmKinds [] = {
89ce990805SThomas Braun 	{ true, 'd', "define", "defines" },
90ce990805SThomas Braun 	{ true, 'l', "label",  "labels"  },
91ce990805SThomas Braun 	{ true, 'm', "macro",  "macros"  },
922e62bfe5SMasatake YAMATO 	{ true, 't', "type",   "types (structs and records)"   },
932e62bfe5SMasatake YAMATO 	{ true, 's', "section",   "sections",
942e62bfe5SMasatake YAMATO 	  .referenceOnly = true, ATTACH_ROLES(asmSectionRoles)},
9512ab91a0SMasatake YAMATO 	{ false,'z', "parameter", "parameters for a macro" },
963ae02089SMasatake YAMATO };
973ae02089SMasatake YAMATO 
9882c11d8cSRich Siegel static const keywordTable AsmKeywords [] = {
993ae02089SMasatake YAMATO 	{ "align",    OP_ALIGN       },
1003ae02089SMasatake YAMATO 	{ "endmacro", OP_ENDMACRO    },
1013ae02089SMasatake YAMATO 	{ "endm",     OP_ENDM        },
1023ae02089SMasatake YAMATO 	{ "end",      OP_END         },
1033ae02089SMasatake YAMATO 	{ "endp",     OP_ENDP        },
1043ae02089SMasatake YAMATO 	{ "ends",     OP_ENDS        },
1053ae02089SMasatake YAMATO 	{ "equ",      OP_EQU         },
1063ae02089SMasatake YAMATO 	{ "label",    OP_LABEL       },
1073ae02089SMasatake YAMATO 	{ "macro",    OP_MACRO       },
1083ae02089SMasatake YAMATO 	{ ":=",       OP_COLON_EQUAL },
1093ae02089SMasatake YAMATO 	{ "=",        OP_EQUAL       },
1103ae02089SMasatake YAMATO 	{ "proc",     OP_PROC        },
1113ae02089SMasatake YAMATO 	{ "record",   OP_RECORD      },
1123ae02089SMasatake YAMATO 	{ "sections", OP_SECTIONS    },
1132e62bfe5SMasatake YAMATO 
114e1bc2a34Smarkferry 	/* These are used in GNU as. */
1152e62bfe5SMasatake YAMATO 	{ "section",  OP_SECTION     },
116e1bc2a34Smarkferry 	{ "equiv",    OP_EQU         },
117e1bc2a34Smarkferry 	{ "eqv",      OP_EQU         },
1182e62bfe5SMasatake YAMATO 
1193ae02089SMasatake YAMATO 	{ "set",      OP_SET         },
1203ae02089SMasatake YAMATO 	{ "struct",   OP_STRUCT      }
1213ae02089SMasatake YAMATO };
1223ae02089SMasatake YAMATO 
1233ae02089SMasatake YAMATO static const opKind OpKinds [] = {
1243ae02089SMasatake YAMATO 	/* must be ordered same as opKeyword enumeration */
1253ae02089SMasatake YAMATO 	{ OP_ALIGN,       K_NONE   },
1263ae02089SMasatake YAMATO 	{ OP_COLON_EQUAL, K_DEFINE },
1273ae02089SMasatake YAMATO 	{ OP_END,         K_NONE   },
12864a990a1SMasatake YAMATO 	{ OP_ENDM,        K_PSUEDO_MACRO_END },
1293ae02089SMasatake YAMATO 	{ OP_ENDMACRO,    K_NONE   },
1303ae02089SMasatake YAMATO 	{ OP_ENDP,        K_NONE   },
1313ae02089SMasatake YAMATO 	{ OP_ENDS,        K_NONE   },
1323ae02089SMasatake YAMATO 	{ OP_EQU,         K_DEFINE },
1333ae02089SMasatake YAMATO 	{ OP_EQUAL,       K_DEFINE },
1343ae02089SMasatake YAMATO 	{ OP_LABEL,       K_LABEL  },
1353ae02089SMasatake YAMATO 	{ OP_MACRO,       K_MACRO  },
1363ae02089SMasatake YAMATO 	{ OP_PROC,        K_LABEL  },
1373ae02089SMasatake YAMATO 	{ OP_RECORD,      K_TYPE   },
1383ae02089SMasatake YAMATO 	{ OP_SECTIONS,    K_NONE   },
1392e62bfe5SMasatake YAMATO 	{ OP_SECTION,     K_SECTION },
1403ae02089SMasatake YAMATO 	{ OP_SET,         K_DEFINE },
1413ae02089SMasatake YAMATO 	{ OP_STRUCT,      K_TYPE   }
1423ae02089SMasatake YAMATO };
1433ae02089SMasatake YAMATO 
1443ae02089SMasatake YAMATO /*
1453ae02089SMasatake YAMATO *   FUNCTION DEFINITIONS
1463ae02089SMasatake YAMATO */
analyzeOperator(const vString * const op)1473ae02089SMasatake YAMATO static opKeyword analyzeOperator (const vString *const op)
1483ae02089SMasatake YAMATO {
1493ae02089SMasatake YAMATO 	vString *keyword = vStringNew ();
1503ae02089SMasatake YAMATO 	opKeyword result;
1513ae02089SMasatake YAMATO 
1523ae02089SMasatake YAMATO 	vStringCopyToLower (keyword, op);
1533ae02089SMasatake YAMATO 	result = (opKeyword) lookupKeyword (vStringValue (keyword), Lang_asm);
1543ae02089SMasatake YAMATO 	vStringDelete (keyword);
1553ae02089SMasatake YAMATO 	return result;
1563ae02089SMasatake YAMATO }
1573ae02089SMasatake YAMATO 
isInitialSymbolCharacter(int c)158ce990805SThomas Braun static bool isInitialSymbolCharacter (int c)
1593ae02089SMasatake YAMATO {
160ce990805SThomas Braun 	return (bool) (c != '\0' && (isalpha (c) || strchr ("_$", c) != NULL));
1613ae02089SMasatake YAMATO }
1623ae02089SMasatake YAMATO 
isSymbolCharacter(int c)163ce990805SThomas Braun static bool isSymbolCharacter (int c)
1643ae02089SMasatake YAMATO {
1653ae02089SMasatake YAMATO 	/* '?' character is allowed in AMD 29K family */
166ce990805SThomas Braun 	return (bool) (c != '\0' && (isalnum (c) || strchr ("_$?", c) != NULL));
1673ae02089SMasatake YAMATO }
1683ae02089SMasatake YAMATO 
operatorKind(const vString * const operator,bool * const found)1693ae02089SMasatake YAMATO static AsmKind operatorKind (
1703ae02089SMasatake YAMATO 		const vString *const operator,
171ce990805SThomas Braun 		bool *const found)
1723ae02089SMasatake YAMATO {
1733ae02089SMasatake YAMATO 	AsmKind result = K_NONE;
1743ae02089SMasatake YAMATO 	const opKeyword kw = analyzeOperator (operator);
175ce990805SThomas Braun 	*found = (bool) (kw != OP_UNDEFINED);
1763ae02089SMasatake YAMATO 	if (*found)
1773ae02089SMasatake YAMATO 	{
1783ae02089SMasatake YAMATO 		result = OpKinds [kw].kind;
1793ae02089SMasatake YAMATO 		Assert (OpKinds [kw].keyword == kw);
1803ae02089SMasatake YAMATO 	}
1813ae02089SMasatake YAMATO 	return result;
1823ae02089SMasatake YAMATO }
1833ae02089SMasatake YAMATO 
1843ae02089SMasatake YAMATO /*  We must check for "DB", "DB.L", "DCB.W" (68000)
1853ae02089SMasatake YAMATO  */
isDefineOperator(const vString * const operator)186ce990805SThomas Braun static bool isDefineOperator (const vString *const operator)
1873ae02089SMasatake YAMATO {
1883ae02089SMasatake YAMATO 	const unsigned char *const op =
1893ae02089SMasatake YAMATO 		(unsigned char*) vStringValue (operator);
1903ae02089SMasatake YAMATO 	const size_t length = vStringLength (operator);
191ce990805SThomas Braun 	const bool result = (bool) (length > 0  &&
1923ae02089SMasatake YAMATO 		toupper ((int) *op) == 'D'  &&
1933ae02089SMasatake YAMATO 		(length == 2 ||
1943ae02089SMasatake YAMATO 		 (length == 4  &&  (int) op [2] == '.') ||
1953ae02089SMasatake YAMATO 		 (length == 5  &&  (int) op [3] == '.')));
1963ae02089SMasatake YAMATO 	return result;
1973ae02089SMasatake YAMATO }
1983ae02089SMasatake YAMATO 
makeAsmTag(const vString * const name,const vString * const operator,const bool labelCandidate,const bool nameFollows,const bool directive,int * scope)19912ab91a0SMasatake YAMATO static int makeAsmTag (
2003ae02089SMasatake YAMATO 		const vString *const name,
2013ae02089SMasatake YAMATO 		const vString *const operator,
202ce990805SThomas Braun 		const bool labelCandidate,
203221968f4SMasatake YAMATO 		const bool nameFollows,
20464a990a1SMasatake YAMATO 		const bool directive,
205a5db887dSMasatake YAMATO 		int *scope)
2063ae02089SMasatake YAMATO {
20712ab91a0SMasatake YAMATO 	int r = CORK_NIL;
20812ab91a0SMasatake YAMATO 
2093ae02089SMasatake YAMATO 	if (vStringLength (name) > 0)
2103ae02089SMasatake YAMATO 	{
211ce990805SThomas Braun 		bool found;
2123ae02089SMasatake YAMATO 		const AsmKind kind = operatorKind (operator, &found);
2133ae02089SMasatake YAMATO 		if (found)
2143ae02089SMasatake YAMATO 		{
21564a990a1SMasatake YAMATO 			if (kind > K_NONE)
21612ab91a0SMasatake YAMATO 				r = makeSimpleTag (name, kind);
2173ae02089SMasatake YAMATO 		}
2183ae02089SMasatake YAMATO 		else if (isDefineOperator (operator))
2193ae02089SMasatake YAMATO 		{
2203ae02089SMasatake YAMATO 			if (! nameFollows)
22112ab91a0SMasatake YAMATO 				r = makeSimpleTag (name, K_DEFINE);
2223ae02089SMasatake YAMATO 		}
2233ae02089SMasatake YAMATO 		else if (labelCandidate)
2243ae02089SMasatake YAMATO 		{
2253ae02089SMasatake YAMATO 			operatorKind (name, &found);
2263ae02089SMasatake YAMATO 			if (! found)
22712ab91a0SMasatake YAMATO 				r = makeSimpleTag (name, K_LABEL);
2283ae02089SMasatake YAMATO 		}
229221968f4SMasatake YAMATO 		else if (directive)
230221968f4SMasatake YAMATO 		{
23164a990a1SMasatake YAMATO 			bool found_dummy;
23264a990a1SMasatake YAMATO 			const AsmKind kind_for_directive = operatorKind (name, &found_dummy);
23364a990a1SMasatake YAMATO 			tagEntryInfo *macro_tag;
234221968f4SMasatake YAMATO 
23564a990a1SMasatake YAMATO 			switch (kind_for_directive)
23664a990a1SMasatake YAMATO 			{
23764a990a1SMasatake YAMATO 			case K_NONE:
23864a990a1SMasatake YAMATO 				break;
23964a990a1SMasatake YAMATO 			case K_MACRO:
240a5db887dSMasatake YAMATO 				r = makeSimpleTag (operator, kind_for_directive);
241a5db887dSMasatake YAMATO 				macro_tag = getEntryInCorkQueue (r);
242a5db887dSMasatake YAMATO 				if (macro_tag)
243a5db887dSMasatake YAMATO 				{
244a5db887dSMasatake YAMATO 					macro_tag->extensionFields.scopeIndex = *scope;
245a5db887dSMasatake YAMATO 					registerEntry (r);
246a5db887dSMasatake YAMATO 					*scope = r;
247a5db887dSMasatake YAMATO 				}
24864a990a1SMasatake YAMATO 				break;
24964a990a1SMasatake YAMATO 			case K_PSUEDO_MACRO_END:
250a5db887dSMasatake YAMATO 				macro_tag = getEntryInCorkQueue (*scope);
2513671ad72SMasatake YAMATO 				if (macro_tag)
252a5db887dSMasatake YAMATO 				{
25364a990a1SMasatake YAMATO 					macro_tag->extensionFields.endLine = getInputLineNumber ();
254a5db887dSMasatake YAMATO 					*scope = macro_tag->extensionFields.scopeIndex;
255a5db887dSMasatake YAMATO 				}
25664a990a1SMasatake YAMATO 				break;
2572e62bfe5SMasatake YAMATO 			case K_SECTION:
25812ab91a0SMasatake YAMATO 				r = makeSimpleRefTag (operator,
2592e62bfe5SMasatake YAMATO 									  kind_for_directive,
2602e62bfe5SMasatake YAMATO 									  ASM_SECTION_PLACEMENT);
2612e62bfe5SMasatake YAMATO 				break;
26264a990a1SMasatake YAMATO 			default:
26312ab91a0SMasatake YAMATO 				r = makeSimpleTag (operator, kind_for_directive);
26464a990a1SMasatake YAMATO 			}
265221968f4SMasatake YAMATO 		}
2663ae02089SMasatake YAMATO 	}
26712ab91a0SMasatake YAMATO 	return r;
2683ae02089SMasatake YAMATO }
2693ae02089SMasatake YAMATO 
readSymbol(const unsigned char * const start,vString * const sym)2703ae02089SMasatake YAMATO static const unsigned char *readSymbol (
2713ae02089SMasatake YAMATO 		const unsigned char *const start,
2723ae02089SMasatake YAMATO 		vString *const sym)
2733ae02089SMasatake YAMATO {
2743ae02089SMasatake YAMATO 	const unsigned char *cp = start;
2753ae02089SMasatake YAMATO 	vStringClear (sym);
2763ae02089SMasatake YAMATO 	if (isInitialSymbolCharacter ((int) *cp))
2773ae02089SMasatake YAMATO 	{
2783ae02089SMasatake YAMATO 		while (isSymbolCharacter ((int) *cp))
2793ae02089SMasatake YAMATO 		{
2803ae02089SMasatake YAMATO 			vStringPut (sym, *cp);
2813ae02089SMasatake YAMATO 			++cp;
2823ae02089SMasatake YAMATO 		}
2833ae02089SMasatake YAMATO 	}
2843ae02089SMasatake YAMATO 	return cp;
2853ae02089SMasatake YAMATO }
2863ae02089SMasatake YAMATO 
readOperator(const unsigned char * const start,vString * const operator)2873ae02089SMasatake YAMATO static const unsigned char *readOperator (
2883ae02089SMasatake YAMATO 		const unsigned char *const start,
2893ae02089SMasatake YAMATO 		vString *const operator)
2903ae02089SMasatake YAMATO {
2913ae02089SMasatake YAMATO 	const unsigned char *cp = start;
2923ae02089SMasatake YAMATO 	vStringClear (operator);
2932e62bfe5SMasatake YAMATO 	while (*cp != '\0'  &&  ! isspace ((int) *cp) && *cp != ',')
2943ae02089SMasatake YAMATO 	{
2953ae02089SMasatake YAMATO 		vStringPut (operator, *cp);
2963ae02089SMasatake YAMATO 		++cp;
2973ae02089SMasatake YAMATO 	}
2983ae02089SMasatake YAMATO 	return cp;
2993ae02089SMasatake YAMATO }
3003ae02089SMasatake YAMATO 
asmReadLineFromInputFile(void)30168284a8aSMasatake YAMATO static const unsigned char *asmReadLineFromInputFile (void)
30268284a8aSMasatake YAMATO {
30368284a8aSMasatake YAMATO 	static vString *line;
30468284a8aSMasatake YAMATO 	int c;
30568284a8aSMasatake YAMATO 
30668284a8aSMasatake YAMATO 	line = vStringNewOrClear (line);
30768284a8aSMasatake YAMATO 
30868284a8aSMasatake YAMATO 	while ((c = cppGetc()) != EOF)
30968284a8aSMasatake YAMATO 	{
31068284a8aSMasatake YAMATO 		if (c == '\n')
31168284a8aSMasatake YAMATO 			break;
3127f98a60aSMasatake YAMATO 		else if (c == STRING_SYMBOL || c == CHAR_SYMBOL)
3137f98a60aSMasatake YAMATO 		{
3147f98a60aSMasatake YAMATO 			/* We cannot store these values to vString
3157f98a60aSMasatake YAMATO 			 * Store a whitespace as a dummy value for them.
3167f98a60aSMasatake YAMATO 			 */
3177f98a60aSMasatake YAMATO 			vStringPut (line, ' ');
3187f98a60aSMasatake YAMATO 		}
3197f98a60aSMasatake YAMATO 		else
32068284a8aSMasatake YAMATO 			vStringPut (line, c);
32168284a8aSMasatake YAMATO 	}
32268284a8aSMasatake YAMATO 
32368284a8aSMasatake YAMATO 	if ((vStringLength (line) == 0)&& (c == EOF))
32468284a8aSMasatake YAMATO 		return NULL;
32568284a8aSMasatake YAMATO 	else
32668284a8aSMasatake YAMATO 		return (unsigned char *)vStringValue (line);
32768284a8aSMasatake YAMATO }
32868284a8aSMasatake YAMATO 
readMacroParameters(int index,tagEntryInfo * e,const unsigned char * cp)329b9706843SMasatake YAMATO static void  readMacroParameters (int index, tagEntryInfo *e, const unsigned char *cp)
33012ab91a0SMasatake YAMATO {
33112ab91a0SMasatake YAMATO 	vString *name = vStringNew ();
332b9706843SMasatake YAMATO 	vString *signature = vStringNew ();
333d0ccdc46SMasatake YAMATO 	int nth = 0;
33412ab91a0SMasatake YAMATO 
33512ab91a0SMasatake YAMATO 	if (*cp == ',')
33612ab91a0SMasatake YAMATO 		++cp;
33712ab91a0SMasatake YAMATO 
33812ab91a0SMasatake YAMATO 	while (*cp)
33912ab91a0SMasatake YAMATO 	{
34012ab91a0SMasatake YAMATO 		const unsigned char *tmp;
34195f7e705SMasatake YAMATO 		tagEntryInfo *e = NULL;
34212ab91a0SMasatake YAMATO 
34312ab91a0SMasatake YAMATO 		while (isspace ((int) *cp))
34412ab91a0SMasatake YAMATO 			++cp;
34512ab91a0SMasatake YAMATO 
34612ab91a0SMasatake YAMATO 		tmp = cp;
34712ab91a0SMasatake YAMATO 		cp = readSymbol (cp, name);
34812ab91a0SMasatake YAMATO 		if (cp == tmp)
34912ab91a0SMasatake YAMATO 			break;
35012ab91a0SMasatake YAMATO 
35112ab91a0SMasatake YAMATO 		{
35212ab91a0SMasatake YAMATO 			int r = makeSimpleTag (name, K_PARAM);
35395f7e705SMasatake YAMATO 			e = getEntryInCorkQueue (r);
35412ab91a0SMasatake YAMATO 			if (e)
355d0ccdc46SMasatake YAMATO 			{
35612ab91a0SMasatake YAMATO 				e->extensionFields.scopeIndex = index;
357d0ccdc46SMasatake YAMATO 				e->extensionFields.nth = nth++;
358d0ccdc46SMasatake YAMATO 			}
359b9706843SMasatake YAMATO 			if (vStringLength (signature) > 0 && vStringLast (signature) != ' ')
360b9706843SMasatake YAMATO 				vStringPut (signature, ' ');
361b9706843SMasatake YAMATO 			vStringCat (signature, name);
36212ab91a0SMasatake YAMATO 		}
36312ab91a0SMasatake YAMATO 
36412ab91a0SMasatake YAMATO 		if (*cp == ':')
36512ab91a0SMasatake YAMATO 		{
36612ab91a0SMasatake YAMATO 			cp++;
36795f7e705SMasatake YAMATO 			if (strncmp((const char *)cp, "req" ,3) == 0)
36895f7e705SMasatake YAMATO 			{
36995f7e705SMasatake YAMATO 				cp += 3;
37095f7e705SMasatake YAMATO 				if (e)
37195f7e705SMasatake YAMATO 					attachParserField (e, true, AsmFields[F_PROPERTIES].ftype,
37295f7e705SMasatake YAMATO 									   "req");
373b9706843SMasatake YAMATO 				vStringCatS (signature, ":req");
37495f7e705SMasatake YAMATO 			}
37595f7e705SMasatake YAMATO 			else if (strncmp((const char *)cp, "vararg", 6) == 0)
37695f7e705SMasatake YAMATO 			{
37795f7e705SMasatake YAMATO 				cp += 6;
37895f7e705SMasatake YAMATO 				if (e)
37995f7e705SMasatake YAMATO 					attachParserField (e, true, AsmFields[F_PROPERTIES].ftype,
38095f7e705SMasatake YAMATO 									   "vararg");
381b9706843SMasatake YAMATO 				vStringCatS (signature, ":vararg");
38295f7e705SMasatake YAMATO 			}
38312ab91a0SMasatake YAMATO 			cp = (const unsigned char *)strpbrk ((const char *)cp , " \t,=");
38412ab91a0SMasatake YAMATO 			if (cp == NULL)
38512ab91a0SMasatake YAMATO 				break;
38612ab91a0SMasatake YAMATO 		}
38712ab91a0SMasatake YAMATO 		if (*cp == '=')
38812ab91a0SMasatake YAMATO 		{
389b9706843SMasatake YAMATO 			const unsigned char *start = cp;
39012ab91a0SMasatake YAMATO 			cp = (const unsigned char *)strpbrk ((const char *)cp , " \t,");
391b9706843SMasatake YAMATO 
392b9706843SMasatake YAMATO 			if (cp)
393b9706843SMasatake YAMATO 				vStringNCatS (signature, (const char *)start, cp - start);
394b9706843SMasatake YAMATO 			else
395b9706843SMasatake YAMATO 			{
396b9706843SMasatake YAMATO 				vStringCatS (signature, (const char *)start);
39712ab91a0SMasatake YAMATO 				break;
39812ab91a0SMasatake YAMATO 			}
399b9706843SMasatake YAMATO 		}
40012ab91a0SMasatake YAMATO 
40112ab91a0SMasatake YAMATO 		while (isspace ((int) *cp))
40212ab91a0SMasatake YAMATO 			++cp;
40312ab91a0SMasatake YAMATO 
40412ab91a0SMasatake YAMATO 		if (*cp == ',')
40512ab91a0SMasatake YAMATO 			cp++;
40612ab91a0SMasatake YAMATO 	}
40712ab91a0SMasatake YAMATO 
408b9706843SMasatake YAMATO 	if (vStringLength (signature) > 0)
409b9706843SMasatake YAMATO 	{
410b9706843SMasatake YAMATO 		e->extensionFields.signature = vStringDeleteUnwrap (signature);
411b9706843SMasatake YAMATO 		signature = NULL;
412b9706843SMasatake YAMATO 	}
413b9706843SMasatake YAMATO 	vStringDelete (signature);	/* NULL is acceptable. */
41412ab91a0SMasatake YAMATO 	vStringDelete (name);
41512ab91a0SMasatake YAMATO }
41612ab91a0SMasatake YAMATO 
findAsmTags(void)4173ae02089SMasatake YAMATO static void findAsmTags (void)
4183ae02089SMasatake YAMATO {
4193ae02089SMasatake YAMATO 	vString *name = vStringNew ();
4203ae02089SMasatake YAMATO 	vString *operator = vStringNew ();
4213ae02089SMasatake YAMATO 	const unsigned char *line;
4223ae02089SMasatake YAMATO 
42368284a8aSMasatake YAMATO 	cppInit (false, false, false, false,
424d00bddf9SMasatake YAMATO 			 KIND_GHOST_INDEX, 0, 0, KIND_GHOST_INDEX, KIND_GHOST_INDEX, 0, 0,
425ee4d2ebdSMasatake YAMATO 			 FIELD_UNKNOWN);
42668284a8aSMasatake YAMATO 
427a5db887dSMasatake YAMATO 	 int scope = CORK_NIL;
42864a990a1SMasatake YAMATO 
42968284a8aSMasatake YAMATO 	while ((line = asmReadLineFromInputFile ()) != NULL)
4303ae02089SMasatake YAMATO 	{
4313ae02089SMasatake YAMATO 		const unsigned char *cp = line;
432ce990805SThomas Braun 		bool labelCandidate = (bool) (! isspace ((int) *cp));
433ce990805SThomas Braun 		bool nameFollows = false;
434221968f4SMasatake YAMATO 		bool directive = false;
435ce990805SThomas Braun 		const bool isComment = (bool)
4363ae02089SMasatake YAMATO 				(*cp != '\0' && strchr (";*@", *cp) != NULL);
4373ae02089SMasatake YAMATO 
4383ae02089SMasatake YAMATO 		/* skip comments */
43968284a8aSMasatake YAMATO 		if (isComment)
4403ae02089SMasatake YAMATO 			continue;
4413ae02089SMasatake YAMATO 
4423ae02089SMasatake YAMATO 		/* skip white space */
4433ae02089SMasatake YAMATO 		while (isspace ((int) *cp))
4443ae02089SMasatake YAMATO 			++cp;
4453ae02089SMasatake YAMATO 
4463ae02089SMasatake YAMATO 		/* read symbol */
447221968f4SMasatake YAMATO 		if (*cp == '.')
448221968f4SMasatake YAMATO 		{
449221968f4SMasatake YAMATO 			directive = true;
450221968f4SMasatake YAMATO 			labelCandidate = false;
451221968f4SMasatake YAMATO 			++cp;
452221968f4SMasatake YAMATO 		}
453221968f4SMasatake YAMATO 
4543ae02089SMasatake YAMATO 		cp = readSymbol (cp, name);
4551136a2d6SMasatake YAMATO 		if (vStringLength (name) > 0)
4561136a2d6SMasatake YAMATO 		{
4571136a2d6SMasatake YAMATO 			if (*cp == ':')
4583ae02089SMasatake YAMATO 			{
459ce990805SThomas Braun 				labelCandidate = true;
4603ae02089SMasatake YAMATO 				++cp;
4613ae02089SMasatake YAMATO 			}
4621136a2d6SMasatake YAMATO 			else if (anyKindEntryInScope (CORK_NIL,
4631136a2d6SMasatake YAMATO 										  vStringValue (name),
464*aaaac7eeSMasatake YAMATO 										  K_MACRO, true))
4651136a2d6SMasatake YAMATO 				labelCandidate = false;
4661136a2d6SMasatake YAMATO 		}
4673ae02089SMasatake YAMATO 
4683ae02089SMasatake YAMATO 		if (! isspace ((int) *cp)  &&  *cp != '\0')
4693ae02089SMasatake YAMATO 			continue;
4703ae02089SMasatake YAMATO 
4713ae02089SMasatake YAMATO 		/* skip white space */
4723ae02089SMasatake YAMATO 		while (isspace ((int) *cp))
4733ae02089SMasatake YAMATO 			++cp;
4743ae02089SMasatake YAMATO 
4753ae02089SMasatake YAMATO 		/* skip leading dot */
4763ae02089SMasatake YAMATO #if 0
4773ae02089SMasatake YAMATO 		if (*cp == '.')
4783ae02089SMasatake YAMATO 			++cp;
4793ae02089SMasatake YAMATO #endif
4803ae02089SMasatake YAMATO 
4813ae02089SMasatake YAMATO 		cp = readOperator (cp, operator);
4823ae02089SMasatake YAMATO 
4833ae02089SMasatake YAMATO 		/* attempt second read of symbol */
4843ae02089SMasatake YAMATO 		if (vStringLength (name) == 0)
4853ae02089SMasatake YAMATO 		{
4863ae02089SMasatake YAMATO 			while (isspace ((int) *cp))
4873ae02089SMasatake YAMATO 				++cp;
4883ae02089SMasatake YAMATO 			cp = readSymbol (cp, name);
489ce990805SThomas Braun 			nameFollows = true;
4903ae02089SMasatake YAMATO 		}
491a5db887dSMasatake YAMATO 		int r = makeAsmTag (name, operator, labelCandidate, nameFollows, directive, &scope);
49212ab91a0SMasatake YAMATO 		tagEntryInfo *e = getEntryInCorkQueue (r);
49312ab91a0SMasatake YAMATO 		if (e && e->kindIndex == K_MACRO && isRoleAssigned(e, ROLE_DEFINITION_INDEX))
494b9706843SMasatake YAMATO 			readMacroParameters (r, e, cp);
4953ae02089SMasatake YAMATO 	}
49668284a8aSMasatake YAMATO 
49768284a8aSMasatake YAMATO 	cppTerminate ();
49868284a8aSMasatake YAMATO 
4993ae02089SMasatake YAMATO 	vStringDelete (name);
5003ae02089SMasatake YAMATO 	vStringDelete (operator);
5013ae02089SMasatake YAMATO }
5023ae02089SMasatake YAMATO 
initialize(const langType language)5033ae02089SMasatake YAMATO static void initialize (const langType language)
5043ae02089SMasatake YAMATO {
5053ae02089SMasatake YAMATO 	Lang_asm = language;
5063ae02089SMasatake YAMATO }
5073ae02089SMasatake YAMATO 
AsmParser(void)5083ae02089SMasatake YAMATO extern parserDefinition* AsmParser (void)
5093ae02089SMasatake YAMATO {
5103ae02089SMasatake YAMATO 	static const char *const extensions [] = {
5113ae02089SMasatake YAMATO 		"asm", "ASM", "s", "S", NULL
5123ae02089SMasatake YAMATO 	};
5133ae02089SMasatake YAMATO 	static const char *const patterns [] = {
5143ae02089SMasatake YAMATO 		"*.A51",
5153ae02089SMasatake YAMATO 		"*.29[kK]",
5163ae02089SMasatake YAMATO 		"*.[68][68][kKsSxX]",
5173ae02089SMasatake YAMATO 		"*.[xX][68][68]",
5183ae02089SMasatake YAMATO 		NULL
5193ae02089SMasatake YAMATO 	};
520ab3b3869SMasatake YAMATO 	static selectLanguage selectors[] = { selectByArrowOfR,
521ab3b3869SMasatake YAMATO 					      NULL };
522ab3b3869SMasatake YAMATO 
5233ae02089SMasatake YAMATO 	parserDefinition* def = parserNew ("Asm");
52409ae690fSMasatake YAMATO 	def->kindTable      = AsmKinds;
5253db72c21SMasatake YAMATO 	def->kindCount  = ARRAY_SIZE (AsmKinds);
5263ae02089SMasatake YAMATO 	def->extensions = extensions;
5273ae02089SMasatake YAMATO 	def->patterns   = patterns;
5283ae02089SMasatake YAMATO 	def->parser     = findAsmTags;
5293ae02089SMasatake YAMATO 	def->initialize = initialize;
530c379c5d2SMasatake YAMATO 	def->keywordTable = AsmKeywords;
5313db72c21SMasatake YAMATO 	def->keywordCount = ARRAY_SIZE (AsmKeywords);
532ab3b3869SMasatake YAMATO 	def->selectLanguage = selectors;
5331136a2d6SMasatake YAMATO 	def->useCork = CORK_QUEUE | CORK_SYMTAB;
53495f7e705SMasatake YAMATO 	def->fieldTable = AsmFields;
53595f7e705SMasatake YAMATO 	def->fieldCount = ARRAY_SIZE (AsmFields);
5363ae02089SMasatake YAMATO 	return def;
5373ae02089SMasatake YAMATO }
538