int GetSubKey (const char* const* Keys, unsigned Count) /* Search for a subkey in a table of keywords. The current token must be an ** identifier and all keys must be in upper case. The identifier will be ** uppercased in the process. The function returns the index of the keyword, ** or -1 if the keyword was not found. */ { unsigned I; /* Must have an identifier */ PRECONDITION (CurTok.Tok == TOK_IDENT); /* If we aren't in ignore case mode, we have to uppercase the identifier */ if (!IgnoreCase) { UpcaseSVal (); } /* Do a linear search (a binary search is not worth the effort) */ for (I = 0; I < Count; ++I) { if (SB_CompareStr (&CurTok.SVal, Keys [I]) == 0) { /* Found it */ return I; } } /* Not found */ return -1; }
static void FlagPragma (StrBuf* B, IntStack* Stack) /* Handle a pragma that expects a boolean paramater */ { StrBuf Ident = AUTO_STRBUF_INITIALIZER; long Val; int Push; /* Try to read an identifier */ int IsIdent = SB_GetSym (B, &Ident, 0); /* Check if we have a first argument named "pop" */ if (IsIdent && SB_CompareStr (&Ident, "pop") == 0) { PopInt (Stack); /* No other arguments allowed */ return; } /* Check if we have a first argument named "push" */ if (IsIdent && SB_CompareStr (&Ident, "push") == 0) { Push = 1; if (!GetComma (B)) { goto ExitPoint; } IsIdent = SB_GetSym (B, &Ident, 0); } else { Push = 0; } /* Boolean argument follows */ if (IsIdent) { Val = BoolKeyword (&Ident); } else if (!GetNumber (B, &Val)) { goto ExitPoint; } /* Set/push the new value */ if (Push) { PushInt (Stack, Val); } else { IS_Set (Stack, Val); } ExitPoint: /* Free the identifier */ SB_Done (&Ident); }
static void RepeatTokenCheck (TokList* L) /* Called each time a token from a repeat token list is set. Is used to check * for and replace identifiers that are the repeat counter. */ { if (Tok == TOK_IDENT && L->Data != 0 && SB_CompareStr (&SVal, L->Data) == 0) { /* Must replace by the repeat counter */ Tok = TOK_INTCON; IVal = L->RepCount; } }
static PushPopResult ParsePushPop (StrBuf* B) /* Check for and parse the "push" and "pop" keywords. In case of "push", a * following comma is expected and skipped. */ { StrBuf Ident = AUTO_STRBUF_INITIALIZER; PushPopResult Res = PP_NONE; /* Remember the current string index, so we can go back in case of errors */ unsigned Index = SB_GetIndex (B); /* Try to read an identifier */ if (SB_GetSym (B, &Ident, 0)) { /* Check if we have a first argument named "pop" */ if (SB_CompareStr (&Ident, "pop") == 0) { Res = PP_POP; /* Check if we have a first argument named "push" */ } else if (SB_CompareStr (&Ident, "push") == 0) { Res = PP_PUSH; /* Skip the following comma */ if (!GetComma (B)) { /* Error already flagged by GetComma */ Res = PP_ERROR; } } else { /* Unknown keyword, roll back */ SB_SetIndex (B, Index); } } /* Free the string buffer and return the result */ SB_Done (&Ident); return Res; }
static int BoolKeyword (StrBuf* Ident) /* Check if the identifier in Ident is a keyword for a boolean value. Currently * accepted are true/false/on/off. */ { if (SB_CompareStr (Ident, "true") == 0) { return 1; } if (SB_CompareStr (Ident, "on") == 0) { return 1; } if (SB_CompareStr (Ident, "false") == 0) { return 0; } if (SB_CompareStr (Ident, "off") == 0) { return 0; } /* Error */ Error ("Pragma argument must be one of `on', `off', `true' or `false'"); return 0; }
feature_t FindFeature (const StrBuf* Key) /* Find the feature in a table and return the corresponding enum value. If the * feature is invalid, return FEAT_UNKNOWN. */ { feature_t F; /* This is not time critical, so do a linear search */ for (F = (feature_t) 0; F < FEAT_COUNT; ++F) { if (SB_CompareStr (Key, FeatureKeys[F]) == 0) { /* Found, index is enum value */ return F; } } /* Not found */ return FEAT_UNKNOWN; }
void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name) /* Map an identifier to one of the special tokens in the table */ { unsigned I; /* We need an identifier */ if (CfgTok == CFGTOK_IDENT) { /* Make it upper case */ SB_ToUpper (&CfgSVal); /* Linear search */ for (I = 0; I < Size; ++I) { if (SB_CompareStr (&CfgSVal, Table[I].Ident) == 0) { CfgTok = Table[I].Tok; return; } } } /* Not found or no identifier */ CfgError (&CfgErrorPos, "%s expected", Name); }