Example #1
0
WORD CMacroList::ImportMacro(WORD wMacroId, CMacroList* pSrcList)
{
/* Find the macro in the source list. */
	CMacro* pSrcMacro = pSrcList->FindMacro(wMacroId);
	ASSERT(pSrcMacro != NULL);		// It must be there.
	if (pSrcMacro != NULL)
	{
	/* First, see if this macro exists in our list. */
		CMacro* pOurMacro = FindMacro(pSrcMacro->Name());
		if (pOurMacro == NULL)
		{
		/* We need to create it. */
			pOurMacro = AddMacro(pSrcMacro->Name(), "");
			if (pOurMacro == NULL)
			{
				return 0;
			}
			else
			{
			/* Copy over the data. Don't change the new id. */
				pOurMacro->AssignData(pSrcMacro);
				return pOurMacro->Id();
			}
		}
		else
		{
		/* It exists. Just reference it. */
			return pOurMacro->Id();
		}
	}
/* Macro is missing from the source. */
	return 0;
}
Example #2
0
CMacro* CMacroList::AddMacroAt(int nIndex, LPCSTR pName, LPCSTR pValue)
{
	CMacro* pMacro = FindMacro(pName);
	
	if (pMacro == NULL)
	{
	// Safe 'new'...
		TRY
			pMacro = new CMacro;
		END_TRY
	
		WORD wID;
	
		if ((wID = UniqueID()) == 0)
		{
		/* Should never happen, but who knows? */
			return NULL;
		}
	
		if (pMacro != NULL)
		{
			pMacro->Id(wID);
			pMacro->Name(pName);
			pMacro->Value(pValue);
	
			InsertAt(nIndex, pMacro);
		}
	}
	return pMacro;			// And return it in case anybody cares.
}
Example #3
0
/*
 * ParseDirective
 * Note: macro directives are handled before recording
 */
void ParseDirective(const char *cline)
{
	char *line = strdup(strltrim(cline) + 1);	// skip '.' and allow strtok
//printf("'%s'\n", file->line);
//printf("'%s'\n", line);
	bool valid_directive = false;
	//bool done_directive = true;
//printf("Line: [%s]\n", cline);
	
	/*
	 * macro ending directives
	 */

	if (DIRECTIVE("endm", PARSE_MACRO_DIRECTIVES))
	{
		current_macro = 0;
		parse_directives = PARSE_ALL_DIRECTIVES;
	}
	else if (DIRECTIVE("endr", PARSE_REPT_DIRECTIVES))
	{
		current_macro = 0;
		parse_directives = PARSE_ALL_DIRECTIVES;
		while (repeat-- > 0) MacroExecute("_rept");
	}

	/*
	 * record to macro
	 */
	if (current_macro)
	{
		MacroLine(cline);		// record full line
		goto exit;				// only process macro ending directives
	}

	/*
	 * macro starting directives
	 */
	if (DIRECTIVE("macro", PARSE_MACRO_DIRECTIVES) || DIRECTIVE("macroicase", PARSE_MACRO_DIRECTIVES))
	{
		char *name = strtok((char *)strskipspace(line), delim_chars);
		current_macro = FindMacro(name);
		if (pass != PASS_ASM)
		{
			if (current_macro) { eprintf("Macro name already defined.\n"); eexit(); }
			current_macro = NewMacro(name, DIRECTIVE("macroicase", PARSE_MACRO_DIRECTIVES));
EEKS{printf("new macro at %p\n", current_macro);}
			char *paramname;
			while ((paramname = strtok(0, delim_chars)))
			{
				if (isspace2(paramname[0])) paramname = strskipspace(paramname);
				if (strchr(endline_chars, *paramname)) break;

				current_macro->AddParameter(paramname);
			}
		}
		parse_directives = PARSE_MACRO_DIRECTIVES;
	}
Example #4
0
void queryMacroList::AddOrUpdateMacro(const wxString &key, const wxString &name, const wxString &query)
{
	queryMacroItem *item = FindMacro(key);
	if (item != NULL)
	{
		item->Update(name, query);
	}
	else
	{
		AddNewMacro(key, name, query);
	}
}
Example #5
0
WORD CMacroList::UniqueID(void)
{
	// Brute force method. Start at 1 and look...

	// Look for an open ID. If we hit the max, fail...
	WORD wID = 1;

	while (wID < MACRO_Max)
	{
		if (FindMacro(wID) == NULL)
		{
			break;
		}
		wID++;
	}

	// Return what we found.
	return (wID == MACRO_Max) ? 0 : wID;
}
Example #6
0
static void MacroReplacement (StrBuf* Source, StrBuf* Target)
/* Perform macro replacement. */
{
    ident       Ident;
    Macro*      M;

    /* Remember the current input and switch to Source */
    StrBuf* OldSource = InitLine (Source);

    /* Loop substituting macros */
    while (CurC != '\0') {
        /* If we have an identifier, check if it's a macro */
        if (IsSym (Ident)) {
            /* Check if it's a macro */
            if ((M = FindMacro (Ident)) != 0 && !M->Expanding) {
                /* It's a macro, expand it */
                ExpandMacro (Target, M);
            } else {
                /* An identifier, keep it */
                SB_AppendStr (Target, Ident);
            }
        } else if (IsQuote (CurC)) {
            CopyQuotedString (Target);
        } else if (IsSpace (CurC)) {
            if (!IsSpace (SB_LookAtLast (Target))) {
                SB_AppendChar (Target, CurC);
            }
            NextChar ();
        } else {
            SB_AppendChar (Target, CurC);
            NextChar ();
        }
    }

    /* Switch back the input */
    InitLine (OldSource);
}
Example #7
0
static void DefineMacro (void)
/* Handle a macro definition. */
{
    ident       Ident;
    Macro*      M;
    Macro*      Existing;
    int         C89;

    /* Read the macro name */
    SkipWhitespace (0);
    if (!MacName (Ident)) {
        return;
    }

    /* Remember if we're in C89 mode */
    C89 = (IS_Get (&Standard) == STD_C89);

    /* Get an existing macro definition with this name */
    Existing = FindMacro (Ident);

    /* Create a new macro definition */
    M = NewMacro (Ident);

    /* Check if this is a function like macro */
    if (CurC == '(') {

        /* Skip the left paren */
        NextChar ();

        /* Set the marker that this is a function like macro */
        M->ArgCount = 0;

        /* Read the formal parameter list */
        while (1) {

            /* Skip white space and check for end of parameter list */
            SkipWhitespace (0);
            if (CurC == ')') {
                break;
            }

            /* The next token must be either an identifier, or - if not in
             * C89 mode - the ellipsis.
             */
            if (!C89 && CurC == '.') {
                /* Ellipsis */
                NextChar ();
                if (CurC != '.' || NextC != '.') {
                    PPError ("`...' expected");
                    ClearLine ();
                    return;
                }
                NextChar ();
                NextChar ();

                /* Remember that the macro is variadic and use __VA_ARGS__ as
                 * the argument name.
                 */
                AddMacroArg (M, "__VA_ARGS__");
                M->Variadic = 1;

            } else {
                /* Must be macro argument name */
                if (MacName (Ident) == 0) {
                    return;
                }

                /* __VA_ARGS__ is only allowed in C89 mode */
                if (!C89 && strcmp (Ident, "__VA_ARGS__") == 0) {
                    PPWarning ("`__VA_ARGS__' can only appear in the expansion "
                               "of a C99 variadic macro");
                }

                /* Add the macro argument */
                AddMacroArg (M, Ident);
            }

            /* If we had an ellipsis, or the next char is not a comma, we've
             * reached the end of the macro argument list.
             */
            SkipWhitespace (0);
            if (M->Variadic || CurC != ',') {
                break;
            }
            NextChar ();
        }

        /* Check for a right paren and eat it if we find one */
        if (CurC != ')') {
            PPError ("`)' expected");
            ClearLine ();
            return;
        }
        NextChar ();
    }

    /* Skip whitespace before the macro replacement */
    SkipWhitespace (0);

    /* Insert the macro into the macro table and allocate the ActualArgs array */
    InsertMacro (M);

    /* Remove whitespace and comments from the line, store the preprocessed
     * line into the macro replacement buffer.
     */
    Pass1 (Line, &M->Replacement);

    /* Remove whitespace from the end of the line */
    while (IsSpace (SB_LookAtLast (&M->Replacement))) {
        SB_Drop (&M->Replacement, 1);
    }
#if 0
    printf ("%s: <%.*s>\n", M->Name, SB_GetLen (&M->Replacement), SB_GetConstBuf (&M->Replacement));
#endif

    /* If we have an existing macro, check if the redefinition is identical.
     * Print a diagnostic if not.
     */
    if (Existing && MacroCmp (M, Existing) != 0) {
        PPError ("Macro redefinition is not identical");
    }
}
Example #8
0
File: struct.c Project: cc65/cc65
static long DoStructInternal (long Offs, unsigned Type)
/* Handle the .STRUCT command */
{
    long Size = 0;

    /* Outside of other structs, we need a name. Inside another struct or
    ** union, the struct may be anonymous, in which case no new lexical level
    ** is started.
    */
    int Anon = (CurTok.Tok != TOK_IDENT);
    if (!Anon) {
        /* Enter a new scope, then skip the name */
        SymEnterLevel (&CurTok.SVal, SCOPE_STRUCT, ADDR_SIZE_ABS, 0);
        NextTok ();
        /* Start at zero offset in the new scope */
        Offs = 0;
    }

    /* Test for end of line */
    ConsumeSep ();

    /* Read until end of struct */
    while (CurTok.Tok != TOK_ENDSTRUCT &&
           CurTok.Tok != TOK_ENDUNION  &&
           CurTok.Tok != TOK_EOF) {

        long      MemberSize;
        SymTable* Struct;
        SymEntry* Sym;

        /* Allow empty and comment lines */
        if (CurTok.Tok == TOK_SEP) {
            NextTok ();
            continue;
        }

        /* The format is "[identifier] storage-allocator [, multiplicator]" */
        Sym = 0;
        if (CurTok.Tok == TOK_IDENT) {

            /* Beware: An identifier may also be a macro, in which case we have
            ** to start over.
            */
            Macro* M = FindMacro (&CurTok.SVal);
            if (M) {
                MacExpandStart (M);
                continue;
            }

            /* We have an identifier, generate a symbol */
            Sym = SymFind (CurrentScope, &CurTok.SVal, SYM_ALLOC_NEW);

            /* Assign the symbol the offset of the current member */
            SymDef (Sym, GenLiteralExpr (Offs), ADDR_SIZE_DEFAULT, SF_NONE);

            /* Skip the member name */
            NextTok ();
        }

        /* Read storage allocators */
        MemberSize = 0;                 /* In case of errors, use zero */
        switch (CurTok.Tok) {

            case TOK_BYTE:
                NextTok ();
                MemberSize = Member (1);
                break;

            case TOK_DBYT:
            case TOK_WORD:
            case TOK_ADDR:
                NextTok ();
                MemberSize = Member (2);
                break;

            case TOK_FARADDR:
                NextTok ();
                MemberSize = Member (3);
                break;

            case TOK_DWORD:
                NextTok ();
                MemberSize = Member (4);
                break;

            case TOK_RES:
                NextTok ();
                if (CurTok.Tok == TOK_SEP) {
                    ErrorSkip ("Size is missing");
                } else {
                    MemberSize = Member (1);
                }
                break;

            case TOK_TAG:
                NextTok ();
                Struct = ParseScopedSymTable ();
                if (Struct == 0) {
                    ErrorSkip ("Unknown struct/union");
                } else if (GetSymTabType (Struct) != SCOPE_STRUCT) {
                    ErrorSkip ("Not a struct/union");
                } else {
                    SymEntry* SizeSym = GetSizeOfScope (Struct);
                    if (!SymIsDef (SizeSym) || !SymIsConst (SizeSym, &MemberSize)) {
                        ErrorSkip ("Size of struct/union is unknown");
                    }
                }
                MemberSize = Member (MemberSize);
                break;

            case TOK_STRUCT:
                NextTok ();
                MemberSize = DoStructInternal (Offs, STRUCT);
                break;

            case TOK_UNION:
                NextTok ();
                MemberSize = DoStructInternal (Offs, UNION);
                break;

            default:
                if (!CheckConditionals ()) {
                    /* Not a conditional directive */
                    ErrorSkip ("Invalid storage allocator in struct/union");
                }
        }

        /* Assign the size to the member if it has a name */
        if (Sym) {
            DefSizeOfSymbol (Sym, MemberSize);
        }

        /* Next member */
        if (Type == STRUCT) {
            /* Struct */
            Offs += MemberSize;
            Size += MemberSize;
        } else {
            /* Union */
            if (MemberSize > Size) {
                Size = MemberSize;
            }
        }

        /* Expect end of line */
        ConsumeSep ();
    }

    /* If this is not a anon struct, enter a special symbol named ".size"
    ** into the symbol table of the struct that holds the size of the
    ** struct. Since the symbol starts with a dot, it cannot be accessed
    ** by user code.
    ** Leave the struct scope level.
    */
    if (!Anon) {
        /* Add a symbol */
        SymEntry* SizeSym = GetSizeOfScope (CurrentScope);
        SymDef (SizeSym, GenLiteralExpr (Size), ADDR_SIZE_DEFAULT, SF_NONE);

        /* Close the struct scope */
        SymLeaveLevel ();
    }

    /* End of struct/union definition */
    if (Type == STRUCT) {
        Consume (TOK_ENDSTRUCT, "'.ENDSTRUCT' expected");
    } else {
        Consume (TOK_ENDUNION, "'.ENDUNION' expected");
    }

    /* Return the size of the struct */
    return Size;
}