Index: trunk/src/bldprogs/VBoxCPP.cpp
===================================================================
--- trunk/src/bldprogs/VBoxCPP.cpp	(revision 41217)
+++ trunk/src/bldprogs/VBoxCPP.cpp	(revision 41226)
@@ -109,25 +109,4 @@
 typedef VBCPPDEF *PVBCPPDEF;
 
-
-/**
- * Expansion context.
- */
-typedef struct VBCPPCTX
-{
-    /** The next context on the stack. */
-    struct VBCPPCTX    *pUp;
-    /** The define being expanded. */
-    PVBCPPDEF           pDef;
-    /** Arguments. */
-    struct VBCPPCTXARG
-    {
-        /** The value. */
-        const char *pchValue;
-        /** The value length. */
-        const char *cchValue;
-    }                   aArgs[1];
-} VBCPPCTX;
-/** Pointer to an define expansion context. */
-typedef VBCPPCTX *PVBCPPCTX;
 
 /**
@@ -279,14 +258,4 @@
      * should expand. */
     VBCPP_BITMAP_TYPE   bmDefined[VBCPP_BITMAP_SIZE];
-    /** Indicates whether a C-word might need argument expansion.
-     * The bitmap is indexed by C-word lead character.  Bits that are set
-     * indicates that the lead character is used in an argument of an currently
-     * expanding  \#define. */
-    VBCPP_BITMAP_TYPE   bmArgs[VBCPP_BITMAP_SIZE];
-
-    /** Expansion context stack. */
-    PVBCPPCTX           pExpStack;
-    /** The current expansion stack depth. */
-    uint32_t            cExpStackDepth;
 
     /** The current depth of the conditional stack. */
@@ -324,6 +293,7 @@
 *   Internal Functions                                                         *
 *******************************************************************************/
-static PVBCPPDEF vbcppDefineLookup(PVBCPP pThis, const char *pszDefine, size_t cchDefine);
-
+static PVBCPPDEF    vbcppMacroLookup(PVBCPP pThis, const char *pszDefine, size_t cchDefine);
+static RTEXITCODE   vbcppMacroExpandFunctionLike(PVBCPP pThis, PVBCPPDEF pMacro, PSCMSTREAM pStrmInput, char **ppszExpansion);
+static RTEXITCODE   vbcppMacroExpandObjectLike(PVBCPP pThis, PVBCPPDEF pMacro, PSCMSTREAM pStrmInput, char **ppszExpansion);
 
 
@@ -726,4 +696,30 @@
     }
     return ScmStreamTell(pStrmInput);
+}
+
+
+/**
+ * Looks for a left parenthesis in the input stream.
+ *
+ * Used during macro expansion.  Will ignore comments, newlines and other
+ * whitespace.
+ *
+ * @retval  true if found. The stream position at opening parenthesis.
+ * @retval  false if not found. The stream position is unchanged.
+ *
+ * @param   pThis               The C preprocessor instance.
+ * @param   pStrmInput          The input stream.
+ */
+static bool vbcppInputLookForLeftParenthesis(PVBCPP pThis, PSCMSTREAM pStrmInput)
+{
+    size_t offSaved = ScmStreamTell(pStrmInput);
+    RTEXITCODE rcExit = vbcppProcessSkipWhiteEscapedEolAndComments(pThis, pStrmInput);
+    unsigned ch = ScmStreamPeekCh(pStrmInput);
+    if (ch == '(')
+        return true;
+
+    int rc = ScmStreamSeekAbsolute(pStrmInput, offSaved);
+    AssertFatalRC(rc);
+    return false;
 }
 
@@ -901,5 +897,5 @@
  * @param   pStrmInput          The input stream.
  */
-static RTEXITCODE vbcppProcessDoubleQuotedString(PVBCPP pThis, PSCMSTREAM pStrmInput)
+static RTEXITCODE vbcppProcessStringLitteral(PVBCPP pThis, PSCMSTREAM pStrmInput)
 {
     RTEXITCODE rcExit = vbcppOutputCh(pThis, '"');
@@ -938,5 +934,5 @@
  * @param   pStrmInput          The input stream.
  */
-static RTEXITCODE vbcppProcessSingledQuotedString(PVBCPP pThis, PSCMSTREAM pStrmInput)
+static RTEXITCODE vbcppProcessCharacterConstant(PVBCPP pThis, PSCMSTREAM pStrmInput)
 {
     RTEXITCODE rcExit = vbcppOutputCh(pThis, '\'');
@@ -967,5 +963,34 @@
 
 /**
- * Processes a C word, possibly replacing it with a definition.
+ * Processes a integer or floating point number constant.
+ *
+ * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
+ * @param   pThis               The C preprocessor instance.
+ * @param   pStrmInput          The input stream.
+ * @param   chFirst             The first character.
+ */
+static RTEXITCODE vbcppProcessNumber(PVBCPP pThis, PSCMSTREAM pStrmInput, char chFirst)
+{
+    RTEXITCODE rcExit = vbcppOutputCh(pThis, chFirst);
+
+    unsigned ch;
+    while (   rcExit == RTEXITCODE_SUCCESS
+           && (ch = ScmStreamPeekCh(pStrmInput)) != ~(unsigned)0)
+    {
+        if (   !vbcppIsCIdentifierChar(ch)
+            && ch != '.')
+            break;
+
+        unsigned ch2 = ScmStreamGetCh(pStrmInput);
+        AssertBreakStmt(ch2 == ch, rcExit = vbcppError(pThis, "internal error"));
+        rcExit = vbcppOutputCh(pThis, ch);
+    }
+
+    return rcExit;
+}
+
+
+/**
+ * Processes a identifier, possibly replacing it with a definition.
  *
  * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
@@ -974,6 +999,7 @@
  * @param   ch                  The first character.
  */
-static RTEXITCODE vbcppProcessCWord(PVBCPP pThis, PSCMSTREAM pStrmInput, char ch)
-{
+static RTEXITCODE vbcppProcessIdentifier(PVBCPP pThis, PSCMSTREAM pStrmInput, char ch)
+{
+    int         rc     = VINF_SUCCESS;
     RTEXITCODE  rcExit = RTEXITCODE_SUCCESS;
     size_t      cchDefine;
@@ -981,30 +1007,32 @@
     AssertReturn(pchDefine, vbcppError(pThis, "Internal error in ScmStreamCGetWordM1"));
 
-
     /*
      * Does this look like a define we know?
      */
-    PVBCPPDEF pDef = vbcppDefineLookup(pThis, pchDefine, cchDefine);
-    if (pDef)
-    {
-        if (!pDef->fFunction)
-        {
-#if 0 /** @todo proper expansion! */
-            vbcppDefineExpandSimple(pThis, pDef, )
-#else
-            int rc = ScmStreamWrite(&pThis->StrmOutput, pDef->szValue, pDef->cchValue);
+    PVBCPPDEF pMacro = vbcppMacroLookup(pThis, pchDefine, cchDefine);
+    if (   pMacro
+        && (   !pMacro->fFunction
+            || vbcppInputLookForLeftParenthesis(pThis, pStrmInput)) )
+    {
+        char *pszExpansion = NULL;
+        if (!pMacro->fFunction)
+            rcExit = vbcppMacroExpandObjectLike(pThis, pMacro, pStrmInput, &pszExpansion);
+        else
+            rcExit = vbcppMacroExpandFunctionLike(pThis, pMacro, pStrmInput, &pszExpansion);
+        if (rcExit == RTEXITCODE_SUCCESS)
+        {
+            rc = ScmStreamWrite(&pThis->StrmOutput, pszExpansion, strlen(pszExpansion));
             if (RT_FAILURE(rc))
                 rcExit = vbcppError(pThis, "Output error: %Rrc", rc);
-#endif
-        }
-        else
-            rcExit = vbcppError(pThis, "Expanding function macros is not implemented\n");
+            RTMemFree(pszExpansion);
+        }
     }
     else
     {
         /*
-         * Not a define, just output the text unchanged.
+         * Not a macro or a function-macro name match but no invocation, just
+         * output the text unchanged.
          */
-        int rc = ScmStreamWrite(&pThis->StrmOutput, pchDefine, cchDefine);
+        rc = ScmStreamWrite(&pThis->StrmOutput, pchDefine, cchDefine);
         if (RT_FAILURE(rc))
             rcExit = vbcppError(pThis, "Output error: %Rrc", rc);
@@ -1022,9 +1050,9 @@
  *
  *
- * D E F I N E S
- * D E F I N E S
- * D E F I N E S
- * D E F I N E S
- * D E F I N E S
+ * D E F I N E S   /   M A C R O S
+ * D E F I N E S   /   M A C R O S
+ * D E F I N E S   /   M A C R O S
+ * D E F I N E S   /   M A C R O S
+ * D E F I N E S   /   M A C R O S
  *
  *
@@ -1041,5 +1069,5 @@
  * @param   cchDefine           The length of the name. RTSTR_MAX is ok.
  */
-static bool vbcppDefineExists(PVBCPP pThis, const char *pszDefine, size_t cchDefine)
+static bool vbcppMacroExists(PVBCPP pThis, const char *pszDefine, size_t cchDefine)
 {
     return cchDefine > 0
@@ -1058,5 +1086,5 @@
  * @param   cchDefine           The length of the name. RTSTR_MAX is ok.
  */
-static PVBCPPDEF vbcppDefineLookup(PVBCPP pThis, const char *pszDefine, size_t cchDefine)
+static PVBCPPDEF vbcppMacroLookup(PVBCPP pThis, const char *pszDefine, size_t cchDefine)
 {
     if (!cchDefine)
@@ -1068,4 +1096,22 @@
 
 
+
+static RTEXITCODE vbcppMacroExpandObjectLike(PVBCPP pThis, PVBCPPDEF pMacro, PSCMSTREAM pStrmInput, char **ppszExpansion)
+{
+    *ppszExpansion = RTStrDup(pMacro->szValue);
+    if (!*ppszExpansion)
+        return vbcppError(pThis, "out of memory");
+    return RTEXITCODE_SUCCESS;
+}
+
+
+static RTEXITCODE vbcppMacroExpandFunctionLike(PVBCPP pThis, PVBCPPDEF pMacro, PSCMSTREAM pStrmInput, char **ppszExpansion)
+{
+    *ppszExpansion = NULL;
+    return vbcppError(pThis, "Expansion of function like macros is not yet supported");
+}
+
+
+
 /**
  * Frees a define.
@@ -1075,5 +1121,5 @@
  * @param   pvUser              Unused.
  */
-static DECLCALLBACK(int) vbcppFreeDefine(PRTSTRSPACECORE pStr, void *pvUser)
+static DECLCALLBACK(int) vbcppMacroFree(PRTSTRSPACECORE pStr, void *pvUser)
 {
     RTMemFree(pStr);
@@ -1093,5 +1139,5 @@
  *                              preprocessing run it will evaluate to undefined.
  */
-static RTEXITCODE vbcppDefineUndef(PVBCPP pThis, const char *pszDefine, size_t cchDefine, bool fExplicitUndef)
+static RTEXITCODE vbcppMacroUndef(PVBCPP pThis, const char *pszDefine, size_t cchDefine, bool fExplicitUndef)
 {
     PRTSTRSPACECORE pHit = RTStrSpaceGetN(&pThis->StrSpace, pszDefine, cchDefine);
@@ -1099,5 +1145,5 @@
     {
         RTStrSpaceRemove(&pThis->StrSpace, pHit->pszString);
-        vbcppFreeDefine(pHit, NULL);
+        vbcppMacroFree(pHit, NULL);
     }
 
@@ -1127,15 +1173,15 @@
  * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE + msg.
  * @param   pThis               The C preprocessor instance.
- * @param   pDef                The define to insert.
- */
-static RTEXITCODE vbcppDefineInsert(PVBCPP pThis, PVBCPPDEF pDef)
+ * @param   pMacro              The define to insert.
+ */
+static RTEXITCODE vbcppMacroInsert(PVBCPP pThis, PVBCPPDEF pMacro)
 {
     /*
      * Reject illegal macro names.
      */
-    if (!strcmp(pDef->Core.pszString, "defined"))
-    {
-        RTEXITCODE rcExit = vbcppError(pThis, "Cannot use '%s' as a macro name", pDef->Core.pszString);
-        vbcppFreeDefine(&pDef->Core, NULL);
+    if (!strcmp(pMacro->Core.pszString, "defined"))
+    {
+        RTEXITCODE rcExit = vbcppError(pThis, "Cannot use '%s' as a macro name", pMacro->Core.pszString);
+        vbcppMacroFree(&pMacro->Core, NULL);
         return rcExit;
     }
@@ -1145,8 +1191,8 @@
      */
     if (   !pThis->fRespectSourceDefines
-        && !pDef->fCmdLine)
+        && !pMacro->fCmdLine)
     {
         /* Ignore*/
-        vbcppFreeDefine(&pDef->Core, NULL);
+        vbcppMacroFree(&pMacro->Core, NULL);
         return RTEXITCODE_SUCCESS;
     }
@@ -1155,6 +1201,6 @@
      * Insert it and update the lead character hint bitmap.
      */
-    if (RTStrSpaceInsert(&pThis->StrSpace, &pDef->Core))
-        VBCPP_BITMAP_SET(pThis->bmDefined, *pDef->Core.pszString);
+    if (RTStrSpaceInsert(&pThis->StrSpace, &pMacro->Core))
+        VBCPP_BITMAP_SET(pThis->bmDefined, *pMacro->Core.pszString);
     else
     {
@@ -1163,21 +1209,21 @@
          * line take precendece.
          */
-        PVBCPPDEF pOld = (PVBCPPDEF)RTStrSpaceGet(&pThis->StrSpace, pDef->Core.pszString); Assert(pOld);
+        PVBCPPDEF pOld = (PVBCPPDEF)RTStrSpaceGet(&pThis->StrSpace, pMacro->Core.pszString); Assert(pOld);
         if (   pThis->fAllowRedefiningCmdLineDefines
-            || pDef->fCmdLine == pOld->fCmdLine)
-        {
-            if (pDef->fCmdLine)
-                RTMsgWarning("Redefining '%s'\n", pDef->Core.pszString);
+            || pMacro->fCmdLine == pOld->fCmdLine)
+        {
+            if (pMacro->fCmdLine)
+                RTMsgWarning("Redefining '%s'", pMacro->Core.pszString);
 
             RTStrSpaceRemove(&pThis->StrSpace, pOld->Core.pszString);
-            vbcppFreeDefine(&pOld->Core, NULL);
-
-            bool fRc = RTStrSpaceInsert(&pThis->StrSpace, &pDef->Core);
+            vbcppMacroFree(&pOld->Core, NULL);
+
+            bool fRc = RTStrSpaceInsert(&pThis->StrSpace, &pMacro->Core);
             Assert(fRc);
         }
         else
         {
-            RTMsgWarning("Ignoring redefinition of '%s'\n", pDef->Core.pszString);
-            vbcppFreeDefine(&pDef->Core, NULL);
+            RTMsgWarning("Ignoring redefinition of '%s'", pMacro->Core.pszString);
+            vbcppMacroFree(&pMacro->Core, NULL);
         }
     }
@@ -1200,8 +1246,8 @@
  * @param   fCmdLine            Set if originating on the command line.
  */
-static RTEXITCODE vbcppDefineAddFn(PVBCPP pThis, const char *pszDefine, size_t cchDefine,
-                                   const char *pszParams, size_t cchParams,
-                                   const char *pszValue, size_t cchValue,
-                                   bool fCmdLine)
+static RTEXITCODE vbcppMacroAddFn(PVBCPP pThis, const char *pszDefine, size_t cchDefine,
+                                  const char *pszParams, size_t cchParams,
+                                  const char *pszValue, size_t cchValue,
+                                  bool fCmdLine)
 
 {
@@ -1253,22 +1299,22 @@
                     + sizeof(const char *) * cArgs;
     cbDef = RT_ALIGN_Z(cbDef, sizeof(const char *));
-    PVBCPPDEF pDef  = (PVBCPPDEF)RTMemAlloc(cbDef);
-    if (!pDef)
+    PVBCPPDEF pMacro  = (PVBCPPDEF)RTMemAlloc(cbDef);
+    if (!pMacro)
         return RTMsgErrorExit(RTEXITCODE_FAILURE, "out of memory");
 
-    char *pszDst = &pDef->szValue[cchValue + 1];
-    pDef->Core.pszString = pszDst;
+    char *pszDst = &pMacro->szValue[cchValue + 1];
+    pMacro->Core.pszString = pszDst;
     memcpy(pszDst, pszDefine, cchDefine);
     pszDst += cchDefine;
     *pszDst++ = '\0';
-    pDef->fFunction = true;
-    pDef->fVarArg   = false;
-    pDef->fCmdLine  = fCmdLine;
-    pDef->cArgs     = cArgs;
-    pDef->papszArgs = (const char **)((uintptr_t)pDef + cbDef - sizeof(const char *) * cArgs);
-    VBCPP_BITMAP_EMPTY(pDef->bmArgs);
-    pDef->cchValue  = cchValue;
-    memcpy(pDef->szValue, pszValue, cchValue);
-    pDef->szValue[cchValue] = '\0';
+    pMacro->fFunction = true;
+    pMacro->fVarArg   = false;
+    pMacro->fCmdLine  = fCmdLine;
+    pMacro->cArgs     = cArgs;
+    pMacro->papszArgs = (const char **)((uintptr_t)pMacro + cbDef - sizeof(const char *) * cArgs);
+    VBCPP_BITMAP_EMPTY(pMacro->bmArgs);
+    pMacro->cchValue  = cchValue;
+    memcpy(pMacro->szValue, pszValue, cchValue);
+    pMacro->szValue[cchValue] = '\0';
 
     /*
@@ -1294,5 +1340,5 @@
 
         /* Found and argument. First character is already validated. */
-        pDef->papszArgs[iArg] = pszDst;
+        pMacro->papszArgs[iArg] = pszDst;
         do
         {
@@ -1303,7 +1349,7 @@
         iArg++;
     }
-    Assert((uintptr_t)pszDst <= (uintptr_t)pDef->papszArgs);
-
-    return vbcppDefineInsert(pThis, pDef);
+    Assert((uintptr_t)pszDst <= (uintptr_t)pMacro->papszArgs);
+
+    return vbcppMacroInsert(pThis, pMacro);
 }
 
@@ -1321,6 +1367,6 @@
  * @param   fCmdLine            Set if originating on the command line.
  */
-static RTEXITCODE vbcppDefineAdd(PVBCPP pThis, const char *pszDefine, size_t cchDefine,
-                                 const char *pszValue, size_t cchValue, bool fCmdLine)
+static RTEXITCODE vbcppMacroAdd(PVBCPP pThis, const char *pszDefine, size_t cchDefine,
+                                const char *pszValue, size_t cchValue, bool fCmdLine)
 {
     /*
@@ -1357,5 +1403,5 @@
         pszParams++;
         cchParams -= 2;
-        return vbcppDefineAddFn(pThis, pszDefine, cchDefine, pszParams, cchParams, pszValue, cchValue, fCmdLine);
+        return vbcppMacroAddFn(pThis, pszDefine, cchDefine, pszParams, cchParams, pszValue, cchValue, fCmdLine);
     }
 
@@ -1366,22 +1412,22 @@
         return RTEXITCODE_FAILURE;
 
-    PVBCPPDEF pDef = (PVBCPPDEF)RTMemAlloc(RT_OFFSETOF(VBCPPDEF, szValue[cchValue + 1 + cchDefine + 1]));
-    if (!pDef)
+    PVBCPPDEF pMacro = (PVBCPPDEF)RTMemAlloc(RT_OFFSETOF(VBCPPDEF, szValue[cchValue + 1 + cchDefine + 1]));
+    if (!pMacro)
         return RTMsgErrorExit(RTEXITCODE_FAILURE, "out of memory");
 
-    pDef->Core.pszString = &pDef->szValue[cchValue + 1];
-    memcpy((char *)pDef->Core.pszString, pszDefine, cchDefine);
-    ((char *)pDef->Core.pszString)[cchDefine] = '\0';
-    pDef->fFunction = false;
-    pDef->fVarArg   = false;
-    pDef->fCmdLine  = fCmdLine;
-    pDef->cArgs     = 0;
-    pDef->papszArgs = NULL;
-    VBCPP_BITMAP_EMPTY(pDef->bmArgs);
-    pDef->cchValue  = cchValue;
-    memcpy(pDef->szValue, pszValue, cchValue);
-    pDef->szValue[cchValue] = '\0';
-
-    return vbcppDefineInsert(pThis, pDef);
+    pMacro->Core.pszString = &pMacro->szValue[cchValue + 1];
+    memcpy((char *)pMacro->Core.pszString, pszDefine, cchDefine);
+    ((char *)pMacro->Core.pszString)[cchDefine] = '\0';
+    pMacro->fFunction = false;
+    pMacro->fVarArg   = false;
+    pMacro->fCmdLine  = fCmdLine;
+    pMacro->cArgs     = 0;
+    pMacro->papszArgs = NULL;
+    VBCPP_BITMAP_EMPTY(pMacro->bmArgs);
+    pMacro->cchValue  = cchValue;
+    memcpy(pMacro->szValue, pszValue, cchValue);
+    pMacro->szValue[cchValue] = '\0';
+
+    return vbcppMacroInsert(pThis, pMacro);
 }
 
@@ -1396,5 +1442,5 @@
  *                              started (for pass thru).
  */
-static RTEXITCODE vbcppProcessDefine(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
+static RTEXITCODE vbcppDirectiveDefine(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
 {
     /*
@@ -1466,7 +1512,7 @@
                  */
                 if (pchParams)
-                    rcExit = vbcppDefineAddFn(pThis, pchDefine, cchDefine, pchParams, cchParams, pchValue, cchValue, false);
+                    rcExit = vbcppMacroAddFn(pThis, pchDefine, cchDefine, pchParams, cchParams, pchValue, cchValue, false);
                 else
-                    rcExit = vbcppDefineAdd(pThis, pchDefine, cchDefine, pchValue, cchValue, false);
+                    rcExit = vbcppMacroAdd(pThis, pchDefine, cchDefine, pchValue, cchValue, false);
 
                 /*
@@ -1506,5 +1552,5 @@
  *                              started (for pass thru).
  */
-static RTEXITCODE vbcppProcessUndef(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
+static RTEXITCODE vbcppDirectiveUndef(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
 {
     return vbcppError(pThis, "Not implemented %s", __FUNCTION__);
@@ -1770,6 +1816,6 @@
 
             /* Does it exist?  Will save a whole lot of trouble if it doesn't. */
-            PVBCPPDEF pDef = vbcppDefineLookup(pThis, &pszExpr[offIdentifier], cchIdentifier);
-            if (pDef)
+            PVBCPPDEF pMacro = vbcppMacroLookup(pThis, &pszExpr[offIdentifier], cchIdentifier);
+            if (pMacro)
             {
                 /* Skip white space and check for parenthesis. */
@@ -1787,14 +1833,14 @@
                 {
                     /* Expand simple define if found. */
-                    if (pDef->cchValue + 2 < cchIdentifier)
+                    if (pMacro->cchValue + 2 < cchIdentifier)
                     {
-                        size_t offDelta = cchIdentifier - pDef->cchValue - 2;
+                        size_t offDelta = cchIdentifier - pMacro->cchValue - 2;
                         memmove(&pszExpr[offIdentifier], &pszExpr[offIdentifier + offDelta],
                                 cchExpr - offIdentifier - offDelta + 1); /* Lazy bird is moving too much! */
                         cchExpr -= offDelta;
                     }
-                    else if (pDef->cchValue + 2 > cchIdentifier)
+                    else if (pMacro->cchValue + 2 > cchIdentifier)
                     {
-                        size_t offDelta = pDef->cchValue + 2 - cchIdentifier;
+                        size_t offDelta = pMacro->cchValue + 2 - cchIdentifier;
                         if (cchExpr + offDelta + 1 > cbExprAlloc)
                         {
@@ -1819,6 +1865,6 @@
                        standard compliant this is... */
                     pszExpr[offIdentifier] = ' ';
-                    memcpy(&pszExpr[offIdentifier + 1], pDef->szValue, pDef->cchValue);
-                    pszExpr[offIdentifier + 1 + pDef->cchValue] = ' ';
+                    memcpy(&pszExpr[offIdentifier + 1], pMacro->szValue, pMacro->cchValue);
+                    pszExpr[offIdentifier + 1 + pMacro->cchValue] = ' ';
 
                     /* Restart parsing at the inserted macro. */
@@ -1935,5 +1981,5 @@
  * @param   enmKind             The kind of directive we're processing.
  */
-static RTEXITCODE vbcppProcessIfOrElif(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart,
+static RTEXITCODE vbcppDirectiveIfOrElif(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart,
                                        VBCPPCONDKIND enmKind)
 {
@@ -2036,5 +2082,5 @@
  *                              started (for pass thru).
  */
-static RTEXITCODE vbcppProcessIfDef(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
+static RTEXITCODE vbcppDirectiveIfDef(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
 {
     /*
@@ -2055,5 +2101,5 @@
                  */
                 VBCPPEVAL enmEval;
-                if (vbcppDefineExists(pThis, pchDefine, cchDefine))
+                if (vbcppMacroExists(pThis, pchDefine, cchDefine))
                     enmEval = kVBCppEval_True;
                 else if (   !pThis->fUndecidedConditionals
@@ -2082,5 +2128,5 @@
  *                              started (for pass thru).
  */
-static RTEXITCODE vbcppProcessIfNDef(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
+static RTEXITCODE vbcppDirectiveIfNDef(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
 {
     /*
@@ -2101,5 +2147,5 @@
                  */
                 VBCPPEVAL enmEval;
-                if (vbcppDefineExists(pThis, pchDefine, cchDefine))
+                if (vbcppMacroExists(pThis, pchDefine, cchDefine))
                     enmEval = kVBCppEval_False;
                 else if (   !pThis->fUndecidedConditionals
@@ -2128,5 +2174,5 @@
  *                              started (for pass thru).
  */
-static RTEXITCODE vbcppProcessElse(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
+static RTEXITCODE vbcppDirectiveElse(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
 {
     /*
@@ -2191,5 +2237,5 @@
  *                              started (for pass thru).
  */
-static RTEXITCODE vbcppProcessEndif(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
+static RTEXITCODE vbcppDirectiveEndif(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
 {
     /*
@@ -2282,5 +2328,5 @@
  *                              started (for pass thru).
  */
-static RTEXITCODE vbcppProcessInclude(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
+static RTEXITCODE vbcppDirectiveInclude(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
 {
     /*
@@ -2389,5 +2435,5 @@
  *                              started (for pass thru).
  */
-static RTEXITCODE vbcppProcessPragma(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
+static RTEXITCODE vbcppDirectivePragma(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
 {
     /*
@@ -2441,5 +2487,5 @@
 
 /**
- * Processes a abbreviated line number directive.
+ * Processes an error directive.
  *
  * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
@@ -2449,5 +2495,20 @@
  *                              started (for pass thru).
  */
-static RTEXITCODE vbcppProcessLineNo(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
+static RTEXITCODE vbcppDirectiveError(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
+{
+    return vbcppError(pThis, "Hit an #error");
+}
+
+
+/**
+ * Processes a abbreviated line number directive.
+ *
+ * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
+ * @param   pThis               The C preprocessor instance.
+ * @param   pStrmInput          The input stream.
+ * @param   offStart            The stream position where the directive
+ *                              started (for pass thru).
+ */
+static RTEXITCODE vbcppDirectiveLineNo(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
 {
     return vbcppError(pThis, "Not implemented: %s", __FUNCTION__);
@@ -2462,5 +2523,5 @@
  * @param   pStrmInput          The input stream.
  */
-static RTEXITCODE vbcppProcessLineNoShort(PVBCPP pThis, PSCMSTREAM pStrmInput)
+static RTEXITCODE vbcppDirectiveLineNoShort(PVBCPP pThis, PSCMSTREAM pStrmInput)
 {
     return vbcppError(pThis, "Not implemented: %s", __FUNCTION__);
@@ -2490,27 +2551,29 @@
 #define IS_DIRECTIVE(a_sz) ( sizeof(a_sz) - 1 == cchDirective && strncmp(pchDirective, a_sz, sizeof(a_sz) - 1) == 0)
         if (IS_DIRECTIVE("if"))
-            rcExit = vbcppProcessIfOrElif(pThis, pStrmInput, offStart, kVBCppCondKind_If);
+            rcExit = vbcppDirectiveIfOrElif(pThis, pStrmInput, offStart, kVBCppCondKind_If);
         else if (IS_DIRECTIVE("elif"))
-            rcExit = vbcppProcessIfOrElif(pThis, pStrmInput, offStart, kVBCppCondKind_ElIf);
+            rcExit = vbcppDirectiveIfOrElif(pThis, pStrmInput, offStart, kVBCppCondKind_ElIf);
         else if (IS_DIRECTIVE("ifdef"))
-            rcExit = vbcppProcessIfDef(pThis, pStrmInput, offStart);
+            rcExit = vbcppDirectiveIfDef(pThis, pStrmInput, offStart);
         else if (IS_DIRECTIVE("ifndef"))
-            rcExit = vbcppProcessIfNDef(pThis, pStrmInput, offStart);
+            rcExit = vbcppDirectiveIfNDef(pThis, pStrmInput, offStart);
         else if (IS_DIRECTIVE("else"))
-            rcExit = vbcppProcessElse(pThis, pStrmInput, offStart);
+            rcExit = vbcppDirectiveElse(pThis, pStrmInput, offStart);
         else if (IS_DIRECTIVE("endif"))
-            rcExit = vbcppProcessEndif(pThis, pStrmInput, offStart);
+            rcExit = vbcppDirectiveEndif(pThis, pStrmInput, offStart);
         else if (!pThis->fIf0Mode)
         {
             if (IS_DIRECTIVE("include"))
-                rcExit = vbcppProcessInclude(pThis, pStrmInput, offStart);
+                rcExit = vbcppDirectiveInclude(pThis, pStrmInput, offStart);
             else if (IS_DIRECTIVE("define"))
-                rcExit = vbcppProcessDefine(pThis, pStrmInput, offStart);
+                rcExit = vbcppDirectiveDefine(pThis, pStrmInput, offStart);
             else if (IS_DIRECTIVE("undef"))
-                rcExit = vbcppProcessUndef(pThis, pStrmInput, offStart);
+                rcExit = vbcppDirectiveUndef(pThis, pStrmInput, offStart);
             else if (IS_DIRECTIVE("pragma"))
-                rcExit = vbcppProcessPragma(pThis, pStrmInput, offStart);
+                rcExit = vbcppDirectivePragma(pThis, pStrmInput, offStart);
+            else if (IS_DIRECTIVE("error"))
+                rcExit = vbcppDirectiveError(pThis, pStrmInput, offStart);
             else if (IS_DIRECTIVE("line"))
-                rcExit = vbcppProcessLineNo(pThis, pStrmInput, offStart);
+                rcExit = vbcppDirectiveLineNo(pThis, pStrmInput, offStart);
             else
                 rcExit = vbcppError(pThis, "Unknown preprocessor directive '#%.*s'", cchDirective, pchDirective);
@@ -2523,5 +2586,5 @@
         unsigned ch = ScmStreamPeekCh(pStrmInput);
         if (RT_C_IS_DIGIT(ch))
-            rcExit = vbcppProcessLineNoShort(pThis, pStrmInput);
+            rcExit = vbcppDirectiveLineNoShort(pThis, pStrmInput);
         else
             rcExit = vbcppError(pThis, "Malformed preprocessor directive");
@@ -2605,9 +2668,11 @@
                 {
                     if (ch == '"')
-                        rcExit = vbcppProcessDoubleQuotedString(pThis, pStrmInput);
+                        rcExit = vbcppProcessStringLitteral(pThis, pStrmInput);
                     else if (ch == '\'')
-                        rcExit = vbcppProcessSingledQuotedString(pThis, pStrmInput);
+                        rcExit = vbcppProcessCharacterConstant(pThis, pStrmInput);
                     else if (vbcppIsCIdentifierLeadChar(ch))
-                        rcExit = vbcppProcessCWord(pThis, pStrmInput, ch);
+                        rcExit = vbcppProcessIdentifier(pThis, pStrmInput, ch);
+                    else if (RT_C_IS_DIGIT(ch))
+                        rcExit = vbcppProcessNumber(pThis, pStrmInput, ch);
                     else
                         rcExit = vbcppOutputCh(pThis, ch);
@@ -2784,7 +2849,7 @@
                 const char *pszEqual = strchr(ValueUnion.psz, '=');
                 if (pszEqual)
-                    rcExit = vbcppDefineAdd(pThis, ValueUnion.psz, pszEqual - ValueUnion.psz, pszEqual + 1, RTSTR_MAX, true);
+                    rcExit = vbcppMacroAdd(pThis, ValueUnion.psz, pszEqual - ValueUnion.psz, pszEqual + 1, RTSTR_MAX, true);
                 else
-                    rcExit = vbcppDefineAdd(pThis, ValueUnion.psz, RTSTR_MAX, "1", 1, true);
+                    rcExit = vbcppMacroAdd(pThis, ValueUnion.psz, RTSTR_MAX, "1", 1, true);
                 if (rcExit != RTEXITCODE_SUCCESS)
                     return rcExit;
@@ -2799,5 +2864,5 @@
 
             case 'U':
-                rcExit = vbcppDefineUndef(pThis, ValueUnion.psz, RTSTR_MAX, true);
+                rcExit = vbcppMacroUndef(pThis, ValueUnion.psz, RTSTR_MAX, true);
                 break;
 
@@ -2881,5 +2946,5 @@
     ScmStreamDelete(&pThis->StrmOutput);
 
-    RTStrSpaceDestroy(&pThis->StrSpace, vbcppFreeDefine, NULL);
+    RTStrSpaceDestroy(&pThis->StrSpace, vbcppMacroFree, NULL);
     pThis->StrSpace = NULL;
 
@@ -2908,6 +2973,4 @@
     pThis->StrSpace         = NULL;
     pThis->UndefStrSpace    = NULL;
-    pThis->pExpStack        = NULL;
-    pThis->cExpStackDepth   = 0;
     pThis->cCondStackDepth  = 0;
     pThis->pCondStack       = NULL;
@@ -2916,5 +2979,4 @@
     pThis->fMaybePreprocessorLine = true;
     VBCPP_BITMAP_EMPTY(pThis->bmDefined);
-    VBCPP_BITMAP_EMPTY(pThis->bmArgs);
     pThis->cCondStackDepth  = 0;
     pThis->pInputStack      = NULL;
