Index: /trunk/src/bldprogs/VBoxCPP.cpp
===================================================================
--- /trunk/src/bldprogs/VBoxCPP.cpp	(revision 41265)
+++ /trunk/src/bldprogs/VBoxCPP.cpp	(revision 41266)
@@ -69,4 +69,8 @@
 *   Structures and Typedefs                                                    *
 *******************************************************************************/
+/** Pointer to the C preprocessor instance data. */
+typedef struct VBCPP *PVBCPP;
+
+
 /**
  * Variable string buffer (very simple version of SCMSTREAM).
@@ -169,4 +173,164 @@
     kMacroReScanMode_End
 } VBCPPMACRORESCANMODE;
+
+
+/**
+ * Expression node type.
+ */
+typedef enum VBCPPEXPRKIND
+{
+    kVBCppExprKind_Invalid = 0,
+    kVBCppExprKind_Unary,
+    kVBCppExprKind_Binary,
+    kVBCppExprKind_Ternary,
+    kVBCppExprKind_SignedValue,
+    kVBCppExprKind_UnsignedValue,
+    kVBCppExprKind_End
+} VBCPPEXPRKIND;
+
+
+/** Macro used for the precedence field. */
+#define VBCPPOP_PRECEDENCE(a_iPrecedence)   ((a_iPrecedence) << 8)
+/** Mask for getting the precedence field value. */
+#define VBCPPOP_PRECEDENCE_MASK             0xff00
+/** Operator associativity - Left to right. */
+#define VBCPPOP_L2R                         (1 << 16)
+/** Operator associativity - Right to left. */
+#define VBCPPOP_R2L                         (2 << 16)
+
+/**
+ * Unary operators.
+ */
+typedef enum VBCPPUNARYOP
+{
+    kVBCppUnaryOp_Invalid = 0,
+    kVBCppUnaryOp_Pluss             = VBCPPOP_R2L | VBCPPOP_PRECEDENCE( 3) |  5,
+    kVBCppUnaryOp_Minus             = VBCPPOP_R2L | VBCPPOP_PRECEDENCE( 3) |  6,
+    kVBCppUnaryOp_LogicalNot        = VBCPPOP_R2L | VBCPPOP_PRECEDENCE( 3) |  7,
+    kVBCppUnaryOp_BitwiseNot        = VBCPPOP_R2L | VBCPPOP_PRECEDENCE( 3) |  8,
+    kVBCppUnaryOp_Parenthesis       = VBCPPOP_R2L | VBCPPOP_PRECEDENCE(15) |  9,
+    kVBCppUnaryOp_End
+} VBCPPUNARYOP;
+
+/**
+ * Binary operators.
+ */
+typedef enum VBCPPBINARYOP
+{
+    kVBCppBinary_Invalid = 0,
+    kVBCppBinary_Multiplication     = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 5) |  2,
+    kVBCppBinary_Division           = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 5) |  4,
+    kVBCppBinary_Modulo             = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 5) |  5,
+    kVBCppBinary_Addition           = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 6) |  6,
+    kVBCppBinary_Subtraction        = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 6) |  7,
+    kVBCppBinary_LeftShift          = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 7) |  8,
+    kVBCppBinary_RightShift         = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 7) |  9,
+    kVBCppBinary_LessThan           = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 8) | 10,
+    kVBCppBinary_LessThanOrEqual    = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 8) | 11,
+    kVBCppBinary_GreaterThan        = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 8) | 12,
+    kVBCppBinary_GreaterThanOrEqual = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 8) | 13,
+    kVBCppBinary_EqualTo            = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 9) | 14,
+    kVBCppBinary_NotEqualTo         = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 9) | 15,
+    kVBCppBinary_BitwiseAnd         = VBCPPOP_L2R | VBCPPOP_PRECEDENCE(10) | 16,
+    kVBCppBinary_BitwiseXor         = VBCPPOP_L2R | VBCPPOP_PRECEDENCE(11) | 17,
+    kVBCppBinary_BitwiseOr          = VBCPPOP_L2R | VBCPPOP_PRECEDENCE(12) | 18,
+    kVBCppBinary_LogicalAnd         = VBCPPOP_L2R | VBCPPOP_PRECEDENCE(13) | 19,
+    kVBCppBinary_LogicalOr          = VBCPPOP_L2R | VBCPPOP_PRECEDENCE(14) | 20,
+    kVBCppBinary_End
+} VBCPPBINARYOP;
+
+/** The precedence of the ternary operator (expr ? true : false). */
+#define VBCPPTERNAROP_PRECEDENCE   VBCPPOP_PRECEDENCE(16)
+
+
+/** Pointer to an expression parsing node. */
+typedef struct VBCPPEXPR *PVBCPPEXPR;
+/**
+ * Expression parsing node.
+ */
+typedef struct VBCPPEXPR
+{
+    /** Parent expression. */
+    PVBCPPEXPR          pParent;
+    /** Whether the expression is complete or not. */
+    bool                fComplete;
+    /** The kind of expression. */
+    VBCPPEXPRKIND       enmKind;
+    /** Kind specific content. */
+    union
+    {
+        /** kVBCppExprKind_Unary */
+        struct
+        {
+            VBCPPUNARYOP    enmOperator;
+            PVBCPPEXPR      pArg;
+        } Unary;
+
+        /** kVBCppExprKind_Binary */
+        struct
+        {
+            VBCPPBINARYOP   enmOperator;
+            PVBCPPEXPR      pLeft;
+            PVBCPPEXPR      pRight;
+        } Binary;
+
+        /** kVBCppExprKind_Ternary */
+        struct
+        {
+            PVBCPPEXPR      pExpr;
+            PVBCPPEXPR      pTrue;
+            PVBCPPEXPR      pFalse;
+        } Ternary;
+
+        /** kVBCppExprKind_SignedValue */
+        struct
+        {
+            int64_t         s64;
+        } SignedValue;
+
+        /** kVBCppExprKind_UnsignedValue */
+        struct
+        {
+            uint64_t        u64;
+        } UnsignedValue;
+    } u;
+} VBCPPEXPR;
+
+
+/**
+ * Operator return statuses.
+ */
+typedef enum VBCPPEXPRRET
+{
+    kExprRet_Error = -1,
+    kExprRet_Ok = 0,
+    kExprRet_UnaryOperator,
+    kExprRet_Value,
+    kExprRet_EndOfExpr,
+    kExprRet_End
+} VBCPPEXPRRET;
+
+/**
+ * Expression parser context.
+ */
+typedef struct VBCPPEXPRPARSER
+{
+    /** The current expression posistion. */
+    const char         *pszCur;
+    /** The root node. */
+    PVBCPPEXPR          pRoot;
+    /** The current expression node. */
+    PVBCPPEXPR          pCur;
+    /** Where to insert the next expression. */
+    PVBCPPEXPR         *ppCur;
+    /** The expression. */
+    const char         *pszExpr;
+    /** The number of undefined macros we've encountered while parsing. */
+    size_t              cUndefined;
+    /** Pointer to the C preprocessor instance. */
+    PVBCPP              pThis;
+} VBCPPEXPRPARSER;
+/** Pointer to an expression parser context. */
+typedef VBCPPEXPRPARSER *PVBCPPEXPRPARSER;
 
 
@@ -349,6 +513,4 @@
     bool                fStrmOutputValid;
 } VBCPP;
-/** Pointer to the C preprocessor instance data. */
-typedef VBCPP *PVBCPP;
 
 
@@ -470,4 +632,10 @@
 
 
+/**
+ * Initializes a string buffer.
+ *
+ * @param   pStrBuf             The buffer structure to initialize.
+ * @param   pThis               The C preprocessor instance.
+ */
 static void vbcppStrBufInit(PVBCPPSTRBUF pStrBuf, PVBCPP pThis)
 {
@@ -479,4 +647,9 @@
 
 
+/**
+ * Deletes a string buffer.
+ *
+ * @param   pStrBuf             Pointer to the string buffer.
+ */
 static void vbcppStrBufDelete(PVBCPPSTRBUF pStrBuf)
 {
@@ -486,4 +659,12 @@
 
 
+/**
+ * Ensures that sufficient bufferspace is available, growing the buffer if
+ * necessary.
+ *
+ * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
+ * @param   pStrBuf             Pointer to the string buffer.
+ * @param   cbMin               The minimum buffer size.
+ */
 static RTEXITCODE vbcppStrBufGrow(PVBCPPSTRBUF pStrBuf, size_t cbMin)
 {
@@ -504,4 +685,12 @@
 
 
+/**
+ * Appends a substring.
+ *
+ * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
+ * @param   pStrBuf             Pointer to the string buffer.
+ * @param   pchSrc              Pointer to the first character in the substring.
+ * @param   cchSrc              The length of the substring.
+ */
 static RTEXITCODE vbcppStrBufAppendN(PVBCPPSTRBUF pStrBuf, const char *pchSrc, size_t cchSrc)
 {
@@ -523,4 +712,11 @@
 
 
+/**
+ * Appends a character.
+ *
+ * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
+ * @param   pStrBuf             Pointer to the string buffer.
+ * @param   ch                  The charater to append.
+ */
 static RTEXITCODE vbcppStrBufAppendCh(PVBCPPSTRBUF pStrBuf, char ch)
 {
@@ -541,4 +737,11 @@
 
 
+/**
+ * Appends a string to the buffer.
+ *
+ * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
+ * @param   pStrBuf             Pointer to the string buffer.
+ * @param   psz                 The string to append.
+ */
 static RTEXITCODE vbcppStrBufAppend(PVBCPPSTRBUF pStrBuf, const char *psz)
 {
@@ -547,4 +750,10 @@
 
 
+/**
+ * Gets the last char in the buffer.
+ *
+ * @returns Last character, 0 if empty.
+ * @param   pStrBuf             Pointer to the string buffer.
+ */
 static char vbcppStrBufLastCh(PVBCPPSTRBUF pStrBuf)
 {
@@ -638,5 +847,5 @@
 }
 
-
+#if 0
 
 /**
@@ -794,4 +1003,7 @@
 }
 
+#endif
+
+
 
 
@@ -1117,5 +1329,4 @@
     return rcExit;
 }
-
 
 
@@ -1261,5 +1472,5 @@
  * Processes a single quoted constant.
  *
- * Must not replace any C-words in strings.
+ * Must not replace any C-words in character constants.
  *
  * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
@@ -1297,4 +1508,6 @@
 /**
  * Processes a integer or floating point number constant.
+ *
+ * Must not replace the type suffix.
  *
  * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
@@ -1471,6 +1684,4 @@
     return UINT32_MAX;
 }
-
-
 
 
@@ -3020,148 +3231,4 @@
 
 
-typedef enum VBCPPEXPRKIND
-{
-    kVBCppExprKind_Invalid = 0,
-    kVBCppExprKind_Unary,
-    kVBCppExprKind_Binary,
-    kVBCppExprKind_Ternary,
-    kVBCppExprKind_SignedValue,
-    kVBCppExprKind_UnsignedValue,
-    kVBCppExprKind_End
-} VBCPPEXPRKIND;
-
-#define VBCPPOP_PRECEDENCE(a_iPrecedence)   ((a_iPrecedence) << 8)
-#define VBCPPOP_PRECEDENCE_MASK             0xff00
-#define VBCPPOP_L2R                         (1 << 16)
-#define VBCPPOP_R2L                         (2 << 16)
-
-typedef enum VBCPPUNARYOP
-{
-    kVBCppUnaryOp_Invalid = 0,
-    kVBCppUnaryOp_Pluss             = VBCPPOP_R2L | VBCPPOP_PRECEDENCE( 3) |  5,
-    kVBCppUnaryOp_Minus             = VBCPPOP_R2L | VBCPPOP_PRECEDENCE( 3) |  6,
-    kVBCppUnaryOp_LogicalNot        = VBCPPOP_R2L | VBCPPOP_PRECEDENCE( 3) |  7,
-    kVBCppUnaryOp_BitwiseNot        = VBCPPOP_R2L | VBCPPOP_PRECEDENCE( 3) |  8,
-    kVBCppUnaryOp_Parenthesis       = VBCPPOP_R2L | VBCPPOP_PRECEDENCE(15) |  9,
-    kVBCppUnaryOp_End
-} VBCPPUNARYOP;
-
-typedef enum VBCPPBINARYOP
-{
-    kVBCppBinary_Invalid = 0,
-//    kVBCppBinary_SizeOf             = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 3) |  1,
-    kVBCppBinary_Multiplication     = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 5) |  2,
-    kVBCppBinary_Division           = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 5) |  4,
-    kVBCppBinary_Modulo             = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 5) |  5,
-    kVBCppBinary_Addition           = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 6) |  6,
-    kVBCppBinary_Subtraction        = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 6) |  7,
-    kVBCppBinary_LeftShift          = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 7) |  8,
-    kVBCppBinary_RightShift         = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 7) |  9,
-    kVBCppBinary_LessThan           = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 8) | 10,
-    kVBCppBinary_LessThanOrEqual    = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 8) | 11,
-    kVBCppBinary_GreaterThan        = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 8) | 12,
-    kVBCppBinary_GreaterThanOrEqual = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 8) | 13,
-    kVBCppBinary_EqualTo            = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 9) | 14,
-    kVBCppBinary_NotEqualTo         = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 9) | 15,
-    kVBCppBinary_BitwiseAnd         = VBCPPOP_L2R | VBCPPOP_PRECEDENCE(10) | 16,
-    kVBCppBinary_BitwiseXor         = VBCPPOP_L2R | VBCPPOP_PRECEDENCE(11) | 17,
-    kVBCppBinary_BitwiseOr          = VBCPPOP_L2R | VBCPPOP_PRECEDENCE(12) | 18,
-    kVBCppBinary_LogicalAnd         = VBCPPOP_L2R | VBCPPOP_PRECEDENCE(13) | 19,
-    kVBCppBinary_LogicalOr          = VBCPPOP_L2R | VBCPPOP_PRECEDENCE(14) | 20,
-    kVBCppBinary_End
-} VBCPPBINARYOP;
-
-/** The precedence of the ternary operator (expr ? true : false). */
-#define VBCPPTERNAROP_PRECEDENCE   VBCPPOP_PRECEDENCE(16)
-
-
-typedef struct VBCPPEXPR *PVBCPPEXPR;
-
-/**
- * Expression parsing structure.
- */
-typedef struct VBCPPEXPR
-{
-    /** Parent expression. */
-    PVBCPPEXPR          pParent;
-    /** Whether the expression is complete or not. */
-    bool                fComplete;
-    /** The kind of expression. */
-    VBCPPEXPRKIND       enmKind;
-    /** Content specific. */
-    union
-    {
-        struct
-        {
-            VBCPPUNARYOP    enmOperator;
-            PVBCPPEXPR      pArg;
-        } Unary;
-
-        struct
-        {
-            VBCPPBINARYOP   enmOperator;
-            PVBCPPEXPR      pLeft;
-            PVBCPPEXPR      pRight;
-        } Binary;
-
-        struct
-        {
-            PVBCPPEXPR      pExpr;
-            PVBCPPEXPR      pTrue;
-            PVBCPPEXPR      pFalse;
-        } Ternary;
-
-        struct
-        {
-            int64_t         s64;
-        } SignedValue;
-
-        struct
-        {
-            uint64_t        u64;
-        } UnsignedValue;
-
-    } u;
-} VBCPPEXPR;
-
-
-
-/**
- * Operator return statuses.
- */
-typedef enum VBCPPEXPRRET
-{
-    kExprRet_Error = -1,
-    kExprRet_Ok = 0,
-    kExprRet_UnaryOperator,
-    kExprRet_Value,
-    kExprRet_EndOfExpr,
-    kExprRet_End
-} VBCPPEXPRRET;
-
-/**
- * Expression parser context.
- */
-typedef struct VBCPPEXPRPARSER
-{
-    /** The current expression posistion. */
-    const char         *pszCur;
-    /** The root node. */
-    PVBCPPEXPR          pRoot;
-    /** The current expression node. */
-    PVBCPPEXPR          pCur;
-    /** Where to insert the next expression. */
-    PVBCPPEXPR         *ppCur;
-    /** The expression. */
-    const char         *pszExpr;
-    /** The number of undefined macros we've encountered while parsing. */
-    size_t              cUndefined;
-    /** Pointer to the C preprocessor instance. */
-    PVBCPP              pThis;
-} VBCPPEXPRPARSER;
-/** Pointer to an expression parser context. */
-typedef VBCPPEXPRPARSER *PVBCPPEXPRPARSER;
-
-
 /**
  * Recursively destroys the expression tree.
@@ -3199,5 +3266,13 @@
 
 
-static VBCPPEXPRRET vbcppExprParserError(PVBCPPEXPRPARSER pParser, const char *pszMsg, ...)
+/**
+ * Report error during expression parsing.
+ *
+ * @returns kExprRet_Error
+ * @param   pParser             The parser instance.
+ * @param   pszMsg              The error message.
+ * @param   ...                 Format arguments.
+ */
+static VBCPPEXPRRET vbcppExprParseError(PVBCPPEXPRPARSER pParser, const char *pszMsg, ...)
 {
     va_list va;
@@ -3209,4 +3284,9 @@
 
 
+/**
+ * Skip white space.
+ *
+ * @param   pParser             The parser instance.
+ */
 static void vbcppExprParseSkipWhiteSpace(PVBCPPEXPRPARSER pParser)
 {
@@ -3216,23 +3296,35 @@
 
 
+/**
+ * Allocate a new
+ *
+ * @returns Pointer to the node. NULL+msg on failure.
+ * @param   pParser             The parser instance.
+ */
 static PVBCPPEXPR vbcppExprParseAllocNode(PVBCPPEXPRPARSER pParser)
 {
     PVBCPPEXPR pExpr = (PVBCPPEXPR)RTMemAllocZ(sizeof(*pExpr));
+    if (!pExpr)
+        vbcppExprParseError(pParser, "out of memory (expression node)");
     return pExpr;
 }
 
 
-static VBCPPEXPRRET vbcppExprParserBinaryOrEoeOrRparen(PVBCPPEXPRPARSER pParser)
+/**
+ * Looks for right parentheses and/or end of expression.
+ *
+ * @returns Expression status.
+ * @retval  kExprRet_Ok
+ * @retval  kExprRet_Error with msg.
+ * @retval  kExprRet_EndOfExpr
+ * @param   pParser             The parser instance.
+ */
+static VBCPPEXPRRET vbcppExprParseMaybeRParenOrEoe(PVBCPPEXPRPARSER pParser)
 {
     Assert(!pParser->ppCur);
-
-    /*
-     * Right parenthesis closes
-     */
-    char ch;
     for (;;)
     {
         vbcppExprParseSkipWhiteSpace(pParser);
-        ch = *pParser->pszCur;
+        char ch = *pParser->pszCur;
         if (ch == '\0')
             return kExprRet_EndOfExpr;
@@ -3253,31 +3345,31 @@
                     break;
                 case kVBCppExprKind_Unary:
-                    AssertReturn(pCur->u.Unary.pArg, vbcppExprParserError(pParser, "internal error"));
+                    AssertReturn(pCur->u.Unary.pArg, vbcppExprParseError(pParser, "internal error"));
                     pCur->fComplete = true;
                     break;
                 case kVBCppExprKind_Binary:
-                    AssertReturn(pCur->u.Binary.pLeft, vbcppExprParserError(pParser, "internal error"));
-                    AssertReturn(pCur->u.Binary.pRight, vbcppExprParserError(pParser, "internal error"));
+                    AssertReturn(pCur->u.Binary.pLeft, vbcppExprParseError(pParser, "internal error"));
+                    AssertReturn(pCur->u.Binary.pRight, vbcppExprParseError(pParser, "internal error"));
                     pCur->fComplete = true;
                     break;
                 case kVBCppExprKind_Ternary:
 #if 1 /** @todo Check out the ternary operator implementation. */
-                    return vbcppExprParserError(pParser, "The ternary operator is not implemented");
+                    return vbcppExprParseError(pParser, "The ternary operator is not implemented");
 #else
                     Assert(pCur->u.Ternary.pExpr);
                     if (!pCur->u.Ternary.pTrue)
-                        return vbcppExprParserError(pParser, "?!?!?");
+                        return vbcppExprParseError(pParser, "?!?!?");
                     if (!pCur->u.Ternary.pFalse)
-                        return vbcppExprParserError(pParser, "?!?!?!?");
+                        return vbcppExprParseError(pParser, "?!?!?!?");
                     pCur->fComplete = true;
 #endif
                     break;
                 default:
-                    return vbcppExprParserError(pParser, "Internal error (enmKind=%d)", pCur->enmKind);
+                    return vbcppExprParseError(pParser, "Internal error (enmKind=%d)", pCur->enmKind);
             }
             pCur = pCur->pParent;
         }
         if (!pCur)
-            return vbcppExprParserError(pParser, "Right parenthesis without a left one");
+            return vbcppExprParseError(pParser, "Right parenthesis without a left one");
         pCur->fComplete = true;
 
@@ -3286,5 +3378,5 @@
                && pCur->pParent)
         {
-            AssertReturn(pCur->u.Unary.pArg, vbcppExprParserError(pParser, "internal error"));
+            AssertReturn(pCur->u.Unary.pArg, vbcppExprParseError(pParser, "internal error"));
             pCur->fComplete = true;
             pCur = pCur->pParent;
@@ -3292,33 +3384,48 @@
     }
 
+    return kExprRet_Ok;
+}
+
+
+/**
+ * Parses an binary operator.
+ *
+ * @returns Expression status.
+ * @retval  kExprRet_Ok
+ * @retval  kExprRet_Error with msg.
+ * @param   pParser             The parser instance.
+ */
+static VBCPPEXPRRET vbcppExprParseBinaryOperator(PVBCPPEXPRPARSER pParser)
+{
     /*
      * Binary or ternary operator should follow now.
      */
     VBCPPBINARYOP enmOp;
+    char ch = *pParser->pszCur;
     switch (ch)
     {
         case '*':
             if (pParser->pszCur[1] == '=')
-                return vbcppExprParserError(pParser, "The assignment by product operator is not valid in a preprocessor expression");
+                return vbcppExprParseError(pParser, "The assignment by product operator is not valid in a preprocessor expression");
             enmOp = kVBCppBinary_Multiplication;
             break;
         case '/':
             if (pParser->pszCur[1] == '=')
-                return vbcppExprParserError(pParser, "The assignment by quotient operator is not valid in a preprocessor expression");
+                return vbcppExprParseError(pParser, "The assignment by quotient operator is not valid in a preprocessor expression");
             enmOp = kVBCppBinary_Division;
             break;
         case '%':
             if (pParser->pszCur[1] == '=')
-                return vbcppExprParserError(pParser, "The assignment by remainder operator is not valid in a preprocessor expression");
+                return vbcppExprParseError(pParser, "The assignment by remainder operator is not valid in a preprocessor expression");
             enmOp = kVBCppBinary_Modulo;
             break;
         case '+':
             if (pParser->pszCur[1] == '=')
-                return vbcppExprParserError(pParser, "The assignment by sum operator is not valid in a preprocessor expression");
+                return vbcppExprParseError(pParser, "The assignment by sum operator is not valid in a preprocessor expression");
             enmOp = kVBCppBinary_Addition;
             break;
         case '-':
             if (pParser->pszCur[1] == '=')
-                return vbcppExprParserError(pParser, "The assignment by difference operator is not valid in a preprocessor expression");
+                return vbcppExprParseError(pParser, "The assignment by difference operator is not valid in a preprocessor expression");
             enmOp = kVBCppBinary_Subtraction;
             break;
@@ -3334,5 +3441,5 @@
                 pParser->pszCur++;
                 if (pParser->pszCur[1] == '=')
-                    return vbcppExprParserError(pParser, "The assignment by bitwise left shift operator is not valid in a preprocessor expression");
+                    return vbcppExprParseError(pParser, "The assignment by bitwise left shift operator is not valid in a preprocessor expression");
                 enmOp = kVBCppBinary_LeftShift;
             }
@@ -3349,5 +3456,5 @@
                 pParser->pszCur++;
                 if (pParser->pszCur[1] == '=')
-                    return vbcppExprParserError(pParser, "The assignment by bitwise right shift operator is not valid in a preprocessor expression");
+                    return vbcppExprParseError(pParser, "The assignment by bitwise right shift operator is not valid in a preprocessor expression");
                 enmOp = kVBCppBinary_LeftShift;
             }
@@ -3355,5 +3462,5 @@
         case '=':
             if (pParser->pszCur[1] != '=')
-                return vbcppExprParserError(pParser, "The assignment operator is not valid in a preprocessor expression");
+                return vbcppExprParseError(pParser, "The assignment operator is not valid in a preprocessor expression");
             pParser->pszCur++;
             enmOp = kVBCppBinary_EqualTo;
@@ -3362,5 +3469,5 @@
         case '!':
             if (pParser->pszCur[1] != '=')
-                return vbcppExprParserError(pParser, "Expected binary operator, found the unary operator logical NOT");
+                return vbcppExprParseError(pParser, "Expected binary operator, found the unary operator logical NOT");
             pParser->pszCur++;
             enmOp = kVBCppBinary_NotEqualTo;
@@ -3369,5 +3476,5 @@
         case '&':
             if (pParser->pszCur[1] == '=')
-                return vbcppExprParserError(pParser, "The assignment by bitwise AND operator is not valid in a preprocessor expression");
+                return vbcppExprParseError(pParser, "The assignment by bitwise AND operator is not valid in a preprocessor expression");
             if (pParser->pszCur[1] == '&')
             {
@@ -3380,10 +3487,10 @@
         case '^':
             if (pParser->pszCur[1] == '=')
-                return vbcppExprParserError(pParser, "The assignment by bitwise XOR operator is not valid in a preprocessor expression");
+                return vbcppExprParseError(pParser, "The assignment by bitwise XOR operator is not valid in a preprocessor expression");
             enmOp = kVBCppBinary_BitwiseXor;
             break;
         case '|':
             if (pParser->pszCur[1] == '=')
-                return vbcppExprParserError(pParser, "The assignment by bitwise AND operator is not valid in a preprocessor expression");
+                return vbcppExprParseError(pParser, "The assignment by bitwise AND operator is not valid in a preprocessor expression");
             if (pParser->pszCur[1] == '|')
             {
@@ -3395,12 +3502,12 @@
             break;
         case '~':
-            return vbcppExprParserError(pParser, "Expected binary operator, found the unary operator bitwise NOT");
+            return vbcppExprParseError(pParser, "Expected binary operator, found the unary operator bitwise NOT");
 
         case ':':
         case '?':
-            return vbcppExprParserError(pParser, "The ternary operator is not yet implemented");
+            return vbcppExprParseError(pParser, "The ternary operator is not yet implemented");
 
         default:
-            return vbcppExprParserError(pParser, "Expected binary operator, found '%.20s'", pParser->pszCur);
+            return vbcppExprParseError(pParser, "Expected binary operator, found '%.20s'", pParser->pszCur);
     }
     pParser->pszCur++;
@@ -3433,14 +3540,14 @@
                 break;
             }
-            AssertReturn(pParent->u.Unary.pArg, vbcppExprParserError(pParser, "internal error"));
+            AssertReturn(pParent->u.Unary.pArg, vbcppExprParseError(pParser, "internal error"));
             pParent->fComplete = true;
         }
         else if (pParent->enmKind == kVBCppExprKind_Binary)
         {
-            AssertReturn(pParent->u.Binary.pLeft, vbcppExprParserError(pParser, "internal error"));
-            AssertReturn(pParent->u.Binary.pRight, vbcppExprParserError(pParser, "internal error"));
+            AssertReturn(pParent->u.Binary.pLeft, vbcppExprParseError(pParser, "internal error"));
+            AssertReturn(pParent->u.Binary.pRight, vbcppExprParseError(pParser, "internal error"));
             if ((pParent->u.Binary.enmOperator & VBCPPOP_PRECEDENCE_MASK) >= (enmOp & VBCPPOP_PRECEDENCE_MASK))
             {
-                AssertReturn(pChild, vbcppExprParserError(pParser, "internal error"));
+                AssertReturn(pChild, vbcppExprParseError(pParser, "internal error"));
 
                 if (pParent->u.Binary.pRight == pChild)
@@ -3448,5 +3555,5 @@
                 else
                     ppPlace = &pParent->u.Binary.pLeft;
-                AssertReturn(*ppPlace == pChild, vbcppExprParserError(pParser, "internal error"));
+                AssertReturn(*ppPlace == pChild, vbcppExprParseError(pParser, "internal error"));
                 break;
             }
@@ -3455,10 +3562,10 @@
         else if (pParent->enmKind == kVBCppExprKind_Ternary)
         {
-            return vbcppExprParserError(pParser, "The ternary operator is not implemented");
+            return vbcppExprParseError(pParser, "The ternary operator is not implemented");
         }
         else
             AssertReturn(   pParent->enmKind == kVBCppExprKind_SignedValue
                          || pParent->enmKind == kVBCppExprKind_UnsignedValue,
-                         vbcppExprParserError(pParser, "internal error"));
+                         vbcppExprParseError(pParser, "internal error"));
 
         /* Up on level */
@@ -3489,6 +3596,38 @@
 
 
+/**
+ * Deals with right paretheses or/and end of expression, looks for binary
+ * operators.
+ *
+ * @returns Expression status.
+ * @retval  kExprRet_Ok if binary operator was found processed.
+ * @retval  kExprRet_Error with msg.
+ * @retval  kExprRet_EndOfExpr
+ * @param   pParser             The parser instance.
+ */
+static VBCPPEXPRRET vbcppExprParseBinaryOrEoeOrRparen(PVBCPPEXPRPARSER pParser)
+{
+    VBCPPEXPRRET enmRet = vbcppExprParseMaybeRParenOrEoe(pParser);
+    if (enmRet != kExprRet_Ok)
+        return enmRet;
+    return vbcppExprParseBinaryOperator(pParser);
+}
+
+
+/**
+ * Parses an identifier in the expression, replacing it by 0.
+ *
+ * All known identifiers has already been replaced by their macro values, so
+ * what's left are unknown macros.  These are replaced by 0.
+ *
+ * @returns Expression status.
+ * @retval  kExprRet_Value
+ * @retval  kExprRet_Error with msg.
+ * @param   pParser             The parser instance.
+ */
 static VBCPPEXPRRET vbcppExprParseIdentifier(PVBCPPEXPRPARSER pParser)
 {
+/** @todo don't increment if it's an actively undefined macro. Need to revise
+ *        the expression related code wrt selective preprocessing. */
     pParser->cUndefined++;
 
@@ -3518,12 +3657,18 @@
     vbcppExprParseSkipWhiteSpace(pParser);
     if (*pParser->pszCur == '(')
-        return vbcppExprParserError(pParser, "Unknown unary operator '%.*s'", cchMacro, pszMacro);
-
+        return vbcppExprParseError(pParser, "Unknown unary operator '%.*s'", cchMacro, pszMacro);
 
     return kExprRet_Value;
-
-}
-
-
+}
+
+
+/**
+ * Parses an numeric constant in the expression.
+ *
+ * @returns Expression status.
+ * @retval  kExprRet_Value
+ * @retval  kExprRet_Error with msg.
+ * @param   pParser             The parser instance.
+ */
 static VBCPPEXPRRET vbcppExprParseNumber(PVBCPPEXPRPARSER pParser)
 {
@@ -3538,9 +3683,9 @@
         ch2 = *++pParser->pszCur;
         if (!RT_C_IS_XDIGIT(ch2))
-            return vbcppExprParserError(pParser, "Expected hex digit following '0x'");
+            return vbcppExprParseError(pParser, "Expected hex digit following '0x'");
         int rc = RTStrToUInt64Ex(pParser->pszCur, &pszNext, 16, &u64);
         if (   RT_FAILURE(rc)
             || rc == VWRN_NUMBER_TOO_BIG)
-            return vbcppExprParserError(pParser, "Invalid hex value '%.20s...' (%Rrc)", pParser->pszCur, rc);
+            return vbcppExprParseError(pParser, "Invalid hex value '%.20s...' (%Rrc)", pParser->pszCur, rc);
         fSigned = false;
     }
@@ -3550,5 +3695,5 @@
         if (   RT_FAILURE(rc)
             || rc == VWRN_NUMBER_TOO_BIG)
-            return vbcppExprParserError(pParser, "Invalid octal value '%.20s...' (%Rrc)", pParser->pszCur, rc);
+            return vbcppExprParseError(pParser, "Invalid octal value '%.20s...' (%Rrc)", pParser->pszCur, rc);
         fSigned = u64 > (uint64_t)INT64_MAX ? false : true;
     }
@@ -3558,5 +3703,5 @@
         if (   RT_FAILURE(rc)
             || rc == VWRN_NUMBER_TOO_BIG)
-            return vbcppExprParserError(pParser, "Invalid decimal value '%.20s...' (%Rrc)", pParser->pszCur, rc);
+            return vbcppExprParseError(pParser, "Invalid decimal value '%.20s...' (%Rrc)", pParser->pszCur, rc);
         fSigned = u64 > (uint64_t)INT64_MAX ? false : true;
     }
@@ -3584,5 +3729,5 @@
             fSigned = false;
         else
-            return vbcppExprParserError(pParser, "Invalid number suffix '%.*s'", cchSuffix, pszNext);
+            return vbcppExprParseError(pParser, "Invalid number suffix '%.*s'", cchSuffix, pszNext);
 
         pszNext += cchSuffix;
@@ -3616,4 +3761,12 @@
 
 
+/**
+ * Parses an character constant in the expression.
+ *
+ * @returns Expression status.
+ * @retval  kExprRet_Value
+ * @retval  kExprRet_Error with msg.
+ * @param   pParser             The parser instance.
+ */
 static VBCPPEXPRRET vbcppExprParseCharacterConstant(PVBCPPEXPRPARSER pParser)
 {
@@ -3621,5 +3774,5 @@
     char ch2 = *pParser->pszCur++;
     if (ch2 == '\'')
-        return vbcppExprParserError(pParser, "Empty character constant");
+        return vbcppExprParseError(pParser, "Empty character constant");
     int64_t s64;
     if (ch2 == '\\')
@@ -3633,5 +3786,5 @@
             case 't': s64 = 0x09; break;
             default:
-                return vbcppExprParserError(pParser, "Escape character '%c' is not implemented", ch2);
+                return vbcppExprParseError(pParser, "Escape character '%c' is not implemented", ch2);
         }
     }
@@ -3639,5 +3792,5 @@
         s64 = ch2;
     if (*pParser->pszCur != '\'')
-        return vbcppExprParserError(pParser, "Character constant contains more than one character");
+        return vbcppExprParseError(pParser, "Character constant contains more than one character");
 
     /* Create a signed value node. */
@@ -3659,10 +3812,19 @@
 
 
-static VBCPPEXPRRET vbcppExprParseUnaryOrValueOrEoe(PVBCPPEXPRPARSER pParser)
+/**
+ * Parses a unary operator or a value.
+ *
+ * @returns Expression status.
+ * @retval  kExprRet_Value if value was found and processed.
+ * @retval  kExprRet_UnaryOperator if an unary operator was found and processed.
+ * @retval  kExprRet_Error with msg.
+ * @param   pParser             The parser instance.
+ */
+static VBCPPEXPRRET vbcppExprParseUnaryOrValue(PVBCPPEXPRPARSER pParser)
 {
     vbcppExprParseSkipWhiteSpace(pParser);
     char ch = *pParser->pszCur;
     if (ch == '\0')
-        return vbcppExprParserError(pParser, "Premature end of expression");
+        return vbcppExprParseError(pParser, "Premature end of expression");
 
     /*
@@ -3674,5 +3836,5 @@
         return vbcppExprParseNumber(pParser);
     if (ch == '"')
-        return vbcppExprParserError(pParser, "String litteral");
+        return vbcppExprParseError(pParser, "String litteral");
     if (vbcppIsCIdentifierLeadChar(ch))
         return vbcppExprParseIdentifier(pParser);
@@ -3686,5 +3848,5 @@
         enmOperator = kVBCppUnaryOp_Pluss;
         if (pParser->pszCur[1] == '+')
-            return vbcppExprParserError(pParser, "The prefix increment operator is not valid in a preprocessor expression");
+            return vbcppExprParseError(pParser, "The prefix increment operator is not valid in a preprocessor expression");
     }
     else if (ch == '-')
@@ -3692,5 +3854,5 @@
         enmOperator = kVBCppUnaryOp_Minus;
         if (pParser->pszCur[1] == '-')
-            return vbcppExprParserError(pParser, "The prefix decrement operator is not valid in a preprocessor expression");
+            return vbcppExprParseError(pParser, "The prefix decrement operator is not valid in a preprocessor expression");
     }
     else if (ch == '!')
@@ -3701,5 +3863,5 @@
         enmOperator = kVBCppUnaryOp_Parenthesis;
     else
-        return vbcppExprParserError(pParser, "Unknown token '%.*s'", 32, pParser->pszCur - 1);
+        return vbcppExprParseError(pParser, "Unknown token '%.*s'", 32, pParser->pszCur - 1);
     pParser->pszCur++;
 
@@ -3723,8 +3885,19 @@
 
 
-
+/**
+ * Parses an expanded preprocessor expression.
+ *
+ * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
+ * @param   pThis               The C preprocessor instance.
+ * @param   pszExpr             The expression to parse.
+ * @param   cchExpr             The length of the expression in case we need it.
+ * @param   ppExprTree          Where to return the parse tree.
+ * @param   pcUndefined         Where to return the number of unknown undefined
+ *                              macros.  Optional.
+ */
 static RTEXITCODE vbcppExprParse(PVBCPP pThis, char *pszExpr, size_t cchExpr, PVBCPPEXPR *ppExprTree, size_t *pcUndefined)
 {
     RTEXITCODE rcExit = RTEXITCODE_FAILURE;
+    NOREF(cchExpr);
 
     /*
@@ -3750,14 +3923,14 @@
          */
         do
-            enmRet = vbcppExprParseUnaryOrValueOrEoe(&Parser);
+            enmRet = vbcppExprParseUnaryOrValue(&Parser);
         while (enmRet == kExprRet_UnaryOperator);
         if (enmRet == kExprRet_Error)
             break;
-        AssertBreakStmt(enmRet == kExprRet_Value, enmRet = vbcppExprParserError(&Parser, "Expected value (enmRet=%d)", enmRet));
+        AssertBreakStmt(enmRet == kExprRet_Value, enmRet = vbcppExprParseError(&Parser, "Expected value (enmRet=%d)", enmRet));
 
         /*
          * Non-unary operator, right parenthesis or end of expression is up next.
          */
-        enmRet = vbcppExprParserBinaryOrEoeOrRparen(&Parser);
+        enmRet = vbcppExprParseBinaryOrEoeOrRparen(&Parser);
         if (enmRet == kExprRet_Error)
             break;
@@ -3768,5 +3941,5 @@
             break;
         }
-        AssertBreakStmt(enmRet == kExprRet_Ok, enmRet = vbcppExprParserError(&Parser, "Expected value (enmRet=%d)", enmRet));
+        AssertBreakStmt(enmRet == kExprRet_Ok, enmRet = vbcppExprParseError(&Parser, "Expected value (enmRet=%d)", enmRet));
     }
 
@@ -3784,7 +3957,14 @@
 
 
+/**
+ * Checks if an expression value value is evaluates to @c true or @c false.
+ *
+ * @returns @c true or @c false.
+ * @param   pExpr               The value expression.
+ */
 static bool vbcppExprIsExprTrue(PVBCPPEXPR pExpr)
 {
     Assert(pExpr->enmKind == kVBCppExprKind_SignedValue || pExpr->enmKind == kVBCppExprKind_UnsignedValue);
+
     return pExpr->enmKind == kVBCppExprKind_SignedValue
          ? pExpr->u.SignedValue.s64   != 0
@@ -3793,4 +3973,12 @@
 
 
+/**
+ * Evalutes a parse (sub-)tree.
+ *
+ * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
+ * @param   pThis               The C preprocessor instance.
+ * @param   pRoot               The root of the parse (sub-)tree.
+ * @param   pResult             Where to store the result value.
+ */
 static RTEXITCODE vbcppExprEvaluteTree(PVBCPP pThis, PVBCPPEXPR pRoot, PVBCPPEXPR pResult)
 {
@@ -3865,5 +4053,5 @@
             /* Evalute the right side. */
             VBCPPEXPR Result2;
-            rcExit = vbcppExprEvaluteTree(pThis, pRoot->u.Binary.pLeft, &Result2);
+            rcExit = vbcppExprEvaluteTree(pThis, pRoot->u.Binary.pRight, &Result2);
             if (rcExit != RTEXITCODE_SUCCESS)
                 return rcExit;
@@ -4044,5 +4232,5 @@
 static RTEXITCODE vbcppExprEval(PVBCPP pThis, char *pszExpr, size_t cchExpr, size_t cReplacements, VBCPPEVAL *penmResult)
 {
-    //Assert(strlen(pszExpr) == cchExpr);
+    Assert(strlen(pszExpr) == cchExpr);
     size_t      cUndefined;
     PVBCPPEXPR  pExprTree;
@@ -4199,11 +4387,12 @@
         }
         else if (ch == '\r' || ch == '\n')
-        {
             break; /* done */
-        }
-        else if (RT_C_IS_SPACE(ch) && RT_C_IS_SPACE(vbcppStrBufLastCh(pStrBuf)))
+        else if (   RT_C_IS_SPACE(ch)
+                 && (   RT_C_IS_SPACE(vbcppStrBufLastCh(pStrBuf))
+                     || vbcppStrBufLastCh(pStrBuf) == '\0') )
         {
             unsigned ch2 = ScmStreamGetCh(pStrmInput);
             Assert(ch == ch2);
+            rcExit = RTEXITCODE_SUCCESS;
         }
         else
@@ -4217,4 +4406,5 @@
             {
                 ScmStreamSeekByLine(pStrmInput, ScmStreamTellLine(pStrmInput) + 1);
+                rcExit = RTEXITCODE_SUCCESS;
             }
             else
