+
+
+/*****************************************************************************/
+/* Low level preprocessor token handling */
+/*****************************************************************************/
+
+
+
+/* Types of preprocessor tokens */
+typedef enum {
+ PP_DEFINE,
+ PP_ELIF,
+ PP_ELSE,
+ PP_ENDIF,
+ PP_ERROR,
+ PP_IF,
+ PP_IFDEF,
+ PP_IFNDEF,
+ PP_INCLUDE,
+ PP_LINE,
+ PP_PRAGMA,
+ PP_UNDEF,
+ PP_ILLEGAL
+} pptoken_t;
+
+
+
+/* Preprocessor keyword to token mapping table */
+static const struct PPToken {
+ const char* Key; /* Keyword */
+ pptoken_t Tok; /* Token */
+} PPTokens[] = {
+ { "define", PP_DEFINE },
+ { "elif", PP_ELIF },
+ { "else", PP_ELSE },
+ { "endif", PP_ENDIF },
+ { "error", PP_ERROR },
+ { "if", PP_IF },
+ { "ifdef", PP_IFDEF },
+ { "ifndef", PP_IFNDEF },
+ { "include", PP_INCLUDE },
+ { "line", PP_LINE },
+ { "pragma", PP_PRAGMA },
+ { "undef", PP_UNDEF },
+};
+
+/* Number of preprocessor tokens */
+#define PPTOKEN_COUNT (sizeof(PPTokens) / sizeof(PPTokens[0]))
+
+
+
+static int CmpToken (const void* Key, const void* Elem)
+/* Compare function for bsearch */
+{
+ return strcmp ((const char*) Key, ((const struct PPToken*) Elem)->Key);
+}
+
+
+
+static pptoken_t FindPPToken (const char* Ident)
+/* Find a preprocessor token and return ut. Return PP_ILLEGAL if the identifier
+ * is not a valid preprocessor token.
+ */
+{
+ struct PPToken* P;
+ P = bsearch (Ident, PPTokens, PPTOKEN_COUNT, sizeof (PPTokens[0]), CmpToken);
+ return P? P->Tok : PP_ILLEGAL;
+}