/* * find a label, given it's name. if the label is not * found, it is added to the label table */ Label* get_label(Assembly* assembly, char* name) { static int id = 0; Label* label; /* find it */ label = (Label*)HT_Find(assembly->labels, name); if (!label) { /* not found, create */ label = (Label*)malloc(sizeof(Label)); label->name = malloc(strlen(name)+1); strcpy(label->name, name); label->segment = UNKNOWN; label->location = 0; label->exported = FALSE; label->imported = FALSE; label->debuginfo = LABEL_DEBUG_NONE; label->accessed = 0; label->id = ++id; label->ref = 0; /* add */ HT_Add(assembly->labels, label, name); } else { label->accessed++; } /* return */ return label; }
Macro* FindMacro (const StrBuf* Name) /* Try to find the macro with the given name and return it. If no macro with * this name was found, return NULL. */ { Macro* M = HT_Find (&MacroTab, Name); return (M != 0 && M->Style == MAC_STYLE_CLASSIC)? M : 0; }
Macro* FindDefine (const StrBuf* Name) /* Try to find the define style macro with the given name and return it. If no * such macro was found, return NULL. */ { Macro* M; /* Never if disabled */ if (DisableDefines) { return 0; } /* Check if we have such a macro */ M = HT_Find (&MacroTab, Name); return (M != 0 && M->Style == MAC_STYLE_DEFINE)? M : 0; }
unsigned GetFileIndex (const StrBuf* Name) /* Return the file index for the given file name. */ { /* Get the string pool index from the name */ unsigned NameIdx = GetStrBufId (Name); /* Search in the hash table for the name */ const FileEntry* F = HT_Find (&HashTab, &NameIdx); /* If we don't have this index, print a diagnostic and use the main file */ if (F == 0) { Error ("File name `%m%p' not found in file table", Name); return 0; } else { return F->Index; } }
void MacUndef (const StrBuf* Name, unsigned char Style) /* Undefine the macro with the given name and style. A style mismatch is * treated as if the macro didn't exist. */ { /* Search for the macro */ Macro* M = HT_Find (&MacroTab, Name); /* Don't let the user kid with us */ if (M == 0 || M->Style != Style) { Error ("No such macro: %m%p", Name); return; } if (M->Expansions > 0) { Error ("Cannot delete a macro that is currently expanded"); return; } /* Remove the macro from the macro table */ HT_Remove (&MacroTab, M); /* Free the macro structure */ FreeMacro (M); }
char inventory_has(const char* filename){ int data=0; return HT_Find(g_inventory, filename, &data) != 0; }
void MacDef (unsigned Style) /* Parse a macro definition */ { Macro* M; TokNode* N; int HaveParams; /* We expect a macro name here */ if (CurTok.Tok != TOK_IDENT) { Error ("Identifier expected"); MacSkipDef (Style); return; } else if (!UbiquitousIdents && FindInstruction (&CurTok.SVal) >= 0) { /* The identifier is a name of a 6502 instruction, which is not * allowed if not explicitly enabled. */ Error ("Cannot use an instruction as macro name"); MacSkipDef (Style); return; } /* Did we already define that macro? */ if (HT_Find (&MacroTab, &CurTok.SVal) != 0) { /* Macro is already defined */ Error ("A macro named `%m%p' is already defined", &CurTok.SVal); /* Skip tokens until we reach the final .endmacro */ MacSkipDef (Style); return; } /* Define the macro */ M = NewMacro (&CurTok.SVal, Style); /* Switch to raw token mode and skip the macro name */ EnterRawTokenMode (); NextTok (); /* If we have a DEFINE style macro, we may have parameters in braces, * otherwise we may have parameters without braces. */ if (Style == MAC_STYLE_CLASSIC) { HaveParams = 1; } else { if (CurTok.Tok == TOK_LPAREN) { HaveParams = 1; NextTok (); } else { HaveParams = 0; } } /* Parse the parameter list */ if (HaveParams) { while (CurTok.Tok == TOK_IDENT) { /* Create a struct holding the identifier */ IdDesc* I = NewIdDesc (&CurTok.SVal); /* Insert the struct into the list, checking for duplicate idents */ if (M->ParamCount == 0) { M->Params = I; } else { IdDesc* List = M->Params; while (1) { if (SB_Compare (&List->Id, &CurTok.SVal) == 0) { Error ("Duplicate symbol `%m%p'", &CurTok.SVal); } if (List->Next == 0) { break; } else { List = List->Next; } } List->Next = I; } ++M->ParamCount; /* Skip the name */ NextTok (); /* Maybe there are more params... */ if (CurTok.Tok == TOK_COMMA) { NextTok (); } else { break; } } } /* For class macros, we expect a separator token, for define style macros, * we expect the closing paren. */ if (Style == MAC_STYLE_CLASSIC) { ConsumeSep (); } else if (HaveParams) { ConsumeRParen (); } /* Preparse the macro body. We will read the tokens until we reach end of * file, or a .endmacro (or end of line for DEFINE style macros) and store * them into an token list internal to the macro. For classic macros, there * the .LOCAL command is detected and removed at this time. */ while (1) { /* Check for end of macro */ if (Style == MAC_STYLE_CLASSIC) { /* In classic macros, only .endmacro is allowed */ if (CurTok.Tok == TOK_ENDMACRO) { /* Done */ break; } /* May not have end of file in a macro definition */ if (CurTok.Tok == TOK_EOF) { Error ("`.ENDMACRO' expected"); goto Done; } } else { /* Accept a newline or end of file for new style macros */ if (TokIsSep (CurTok.Tok)) { break; } } /* Check for a .LOCAL declaration */ if (CurTok.Tok == TOK_LOCAL && Style == MAC_STYLE_CLASSIC) { while (1) { IdDesc* I; /* Skip .local or comma */ NextTok (); /* Need an identifer */ if (CurTok.Tok != TOK_IDENT && CurTok.Tok != TOK_LOCAL_IDENT) { Error ("Identifier expected"); SkipUntilSep (); break; } /* Put the identifier into the locals list and skip it */ I = NewIdDesc (&CurTok.SVal); I->Next = M->Locals; M->Locals = I; ++M->LocalCount; NextTok (); /* Check for end of list */ if (CurTok.Tok != TOK_COMMA) { break; } } /* We need end of line after the locals */ ConsumeSep (); continue; } /* Create a token node for the current token */ N = NewTokNode (); /* If the token is an identifier, check if it is a local parameter */ if (CurTok.Tok == TOK_IDENT) { unsigned Count = 0; IdDesc* I = M->Params; while (I) { if (SB_Compare (&I->Id, &CurTok.SVal) == 0) { /* Local param name, replace it */ N->T.Tok = TOK_MACPARAM; N->T.IVal = Count; break; } ++Count; I = I->Next; } } /* Insert the new token in the list */ if (M->TokCount == 0) { /* First token */ M->TokRoot = M->TokLast = N; } else { /* We have already tokens */ M->TokLast->Next = N; M->TokLast = N; } ++M->TokCount; /* Read the next token */ NextTok (); } /* Skip the .endmacro for a classic macro */ if (Style == MAC_STYLE_CLASSIC) { NextTok (); } /* Reset the Incomplete flag now that parsing is done */ M->Incomplete = 0; Done: /* Switch out of raw token mode */ LeaveRawTokenMode (); }
int IsMacro (const StrBuf* Name) /* Return true if the given name is the name of a macro */ { return (HT_Find (&MacroTab, Name) != 0); }