Index: trunk/include/VBox/dbg.h
===================================================================
--- trunk/include/VBox/dbg.h	(revision 41557)
+++ trunk/include/VBox/dbg.h	(revision 41558)
@@ -388,6 +388,6 @@
      * @param   pCmdHlp     Pointer to the command callback structure.
      * @param   pcb         Where to store the number of bytes written.
-     * @param   pszFormat   The format string.
-     *                      This is using the log formatter, so it's format extensions can be used.
+     * @param   pszFormat   The format string.  This may use all IPRT extensions as
+     *                      well as the debugger ones.
      * @param   ...         Arguments specified in the format string.
      */
@@ -400,9 +400,36 @@
      * @param   pCmdHlp     Pointer to the command callback structure.
      * @param   pcb         Where to store the number of bytes written.
-     * @param   pszFormat   The format string.
-     *                      This is using the log formatter, so it's format extensions can be used.
+     * @param   pszFormat   The format string.  This may use all IPRT extensions as
+     *                      well as the debugger ones.
      * @param   args        Arguments specified in the format string.
      */
     DECLCALLBACKMEMBER(int, pfnPrintfV)(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten, const char *pszFormat, va_list args);
+
+    /**
+     * Command helper for formatting a string with debugger format specifiers.
+     *
+     * @returns The number of bytes written.
+     * @param   pCmdHlp     Pointer to the command callback structure.
+     * @param   pszBuf      The output buffer.
+     * @param   cbBuf       The size of the output buffer.
+     * @param   pszFormat   The format string.  This may use all IPRT extensions as
+     *                      well as the debugger ones.
+     * @param   ...         Arguments specified in the format string.
+     */
+    DECLCALLBACKMEMBER(size_t, pfnStrPrintf)(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf, const char *pszFormat, ...);
+
+    /**
+     * Command helper for formatting a string with debugger format specifiers.
+     *
+     * @returns The number of bytes written.
+     * @param   pCmdHlp     Pointer to the command callback structure.
+     * @param   pszBuf      The output buffer.
+     * @param   cbBuf       The size of the output buffer.
+     * @param   pszFormat   The format string.  This may use all IPRT extensions as
+     *                      well as the debugger ones.
+     * @param   va          Arguments specified in the format string.
+     */
+    DECLCALLBACKMEMBER(size_t, pfnStrPrintfV)(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf,
+                                              const char *pszFormat, va_list va);
 
     /**
@@ -613,11 +640,5 @@
 
 /**
- * Command helper for writing formatted text to the debug console.
- *
- * @returns VBox status.
- * @param   pCmdHlp     Pointer to the command callback structure.
- * @param   pszFormat   The format string.
- *                      This is using the log formatter, so it's format extensions can be used.
- * @param   ...         Arguments specified in the format string.
+ * @copydoc DBGCCMDHLP::pfnPrintf
  */
 DECLINLINE(int) DBGCCmdHlpPrintf(PDBGCCMDHLP pCmdHlp, const char *pszFormat, ...)
@@ -631,4 +652,20 @@
 
     return rc;
+}
+
+
+/**
+ * @copydoc DBGCCMDHLP::pfnStrPrintf
+ */
+DECLINLINE(size_t) DBGCCmdHlpStrPrintf(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf, const char *pszFormat, ...)
+{
+    va_list va;
+    size_t  cch;
+
+    va_start(va, pszFormat);
+    cch = pCmdHlp->pfnStrPrintfV(pCmdHlp, pszBuf, cbBuf, pszFormat, va);
+    va_end(va);
+
+    return cch;
 }
 
Index: trunk/include/VBox/err.h
===================================================================
--- trunk/include/VBox/err.h	(revision 41557)
+++ trunk/include/VBox/err.h	(revision 41558)
@@ -2122,6 +2122,5 @@
 /** Syntax error - too many arguments for static storage. */
 #define VERR_DBGC_PARSE_ARGUMENT_OVERFLOW           (VERR_DBGC_PARSE_LOWEST + 2)
-/** Syntax error - argument didn't match description. */
-#define VERR_DBGC_PARSE_NO_ARGUMENT_MATCH           (VERR_DBGC_PARSE_LOWEST + 3)
+
 /** Syntax error - the argument does not allow a range to be specified. */
 #define VERR_DBGC_PARSE_NO_RANGE_ALLOWED            (VERR_DBGC_PARSE_LOWEST + 5)
@@ -2144,26 +2143,25 @@
 /** Syntax error - the specified function is not a function. */
 #define VERR_DBGC_PARSE_NOT_A_FUNCTION              (VERR_DBGC_PARSE_LOWEST + 14)
+/** Syntax error - out of scratch memory. */
+#define VERR_DBGC_PARSE_NO_SCRATCH                  (VERR_DBGC_PARSE_LOWEST + 15)
 /** Syntax error - out of regular heap memory. */
-#define VERR_DBGC_PARSE_NO_MEMORY                   (VERR_DBGC_PARSE_LOWEST + 15)
+#define VERR_DBGC_PARSE_NO_MEMORY                   (VERR_DBGC_PARSE_LOWEST + 16)
 /** Syntax error - incorrect argument type. */
-#define VERR_DBGC_PARSE_INCORRECT_ARG_TYPE          (VERR_DBGC_PARSE_LOWEST + 16)
+#define VERR_DBGC_PARSE_INCORRECT_ARG_TYPE          (VERR_DBGC_PARSE_LOWEST + 17)
 /** Syntax error - an undefined variable was referenced. */
-#define VERR_DBGC_PARSE_VARIABLE_NOT_FOUND          (VERR_DBGC_PARSE_LOWEST + 17)
+#define VERR_DBGC_PARSE_VARIABLE_NOT_FOUND          (VERR_DBGC_PARSE_LOWEST + 18)
 /** Syntax error - a type conversion failed. */
-#define VERR_DBGC_PARSE_CONVERSION_FAILED           (VERR_DBGC_PARSE_LOWEST + 18)
+#define VERR_DBGC_PARSE_CONVERSION_FAILED           (VERR_DBGC_PARSE_LOWEST + 19)
 /** Syntax error - you hit a debugger feature which isn't implemented yet.
  * (Feel free to help implement it.) */
-#define VERR_DBGC_PARSE_NOT_IMPLEMENTED             (VERR_DBGC_PARSE_LOWEST + 19)
+#define VERR_DBGC_PARSE_NOT_IMPLEMENTED             (VERR_DBGC_PARSE_LOWEST + 20)
 /** Syntax error - Couldn't staisfy a request for a sepcific result type. */
-#define VERR_DBGC_PARSE_BAD_RESULT_TYPE             (VERR_DBGC_PARSE_LOWEST + 20)
+#define VERR_DBGC_PARSE_BAD_RESULT_TYPE             (VERR_DBGC_PARSE_LOWEST + 21)
 /** Syntax error - Cannot read symbol value, it is a set-only symbol. */
-#define VERR_DBGC_PARSE_WRITEONLY_SYMBOL            (VERR_DBGC_PARSE_LOWEST + 21)
+#define VERR_DBGC_PARSE_WRITEONLY_SYMBOL            (VERR_DBGC_PARSE_LOWEST + 22)
 /** Syntax error - Invalid command name. */
-#define VERR_DBGC_PARSE_INVALD_COMMAND_NAME         (VERR_DBGC_PARSE_LOWEST + 22)
+#define VERR_DBGC_PARSE_INVALD_COMMAND_NAME         (VERR_DBGC_PARSE_LOWEST + 23)
 /** Syntax error - Command not found. */
-#define VERR_DBGC_PARSE_COMMAND_NOT_FOUND           (VERR_DBGC_PARSE_LOWEST + 23)
-
-/** Syntax error - Obsolete. */
-#define VERR_DBGC_PARSE_ARGUMENT_TYPE_MISMATCH      (VERR_DBGC_PARSE_LOWEST + 4)
+#define VERR_DBGC_PARSE_COMMAND_NOT_FOUND           (VERR_DBGC_PARSE_LOWEST + 24)
 
 
Index: trunk/src/VBox/Debugger/DBGCCmdHlp.cpp
===================================================================
--- trunk/src/VBox/Debugger/DBGCCmdHlp.cpp	(revision 41557)
+++ trunk/src/VBox/Debugger/DBGCCmdHlp.cpp	(revision 41558)
@@ -51,4 +51,5 @@
     return rc;
 }
+
 
 /**
@@ -211,4 +212,29 @@
 
     return pDbgc->rcOutput;
+}
+
+
+/**
+ * @interface_method_impl{DBGCCMDHLP,pfnStrPrintf}
+ */
+static DECLCALLBACK(size_t) dbgcHlpStrPrintfV(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf,
+                                              const char *pszFormat, va_list va)
+{
+    PDBGC   pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
+    return RTStrPrintfExV(dbgcStringFormatter, pDbgc, pszBuf, cbBuf, pszFormat, va);
+}
+
+
+/**
+ * @interface_method_impl{DBGCCMDHLP,pfnStrPrintf}
+ */
+static DECLCALLBACK(size_t) dbgcHlpStrPrintf(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf, const char *pszFormat, ...)
+{
+    PDBGC   pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
+    va_list va;
+    va_start(va, pszFormat);
+    size_t cch = RTStrPrintfExV(dbgcStringFormatter, pDbgc, pszBuf, cbBuf, pszFormat, va);
+    va_end(va);
+    return cch;
 }
 
@@ -1255,4 +1281,6 @@
     pDbgc->CmdHlp.pfnPrintfV            = dbgcHlpPrintfV;
     pDbgc->CmdHlp.pfnPrintf             = dbgcHlpPrintf;
+    pDbgc->CmdHlp.pfnStrPrintf          = dbgcHlpStrPrintf;
+    pDbgc->CmdHlp.pfnStrPrintfV         = dbgcHlpStrPrintfV;
     pDbgc->CmdHlp.pfnVBoxErrorV         = dbgcHlpVBoxErrorV;
     pDbgc->CmdHlp.pfnVBoxError          = dbgcHlpVBoxError;
Index: trunk/src/VBox/Debugger/DBGCEval.cpp
===================================================================
--- trunk/src/VBox/Debugger/DBGCEval.cpp	(revision 41557)
+++ trunk/src/VBox/Debugger/DBGCEval.cpp	(revision 41558)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -31,4 +31,7 @@
 
 #include "DBGCInternal.h"
+
+/** Rewrite in progress.  */
+#define BETTER_ARGUMENT_MATCHING
 
 
@@ -64,4 +67,5 @@
 
 
+
 static int dbgcEvalSubString(PDBGC pDbgc, char *pszExpr, size_t cchExpr, PDBGCVAR pArg)
 {
@@ -72,5 +76,5 @@
      */
     char ch = *pszExpr;
-    if (ch == '"' || ch == '\'' || ch == '`')
+    if (ch == '"' || ch == '\'')
     {
         if (pszExpr[--cchExpr] != ch)
@@ -142,300 +146,167 @@
 
 /**
- * Match variable and variable descriptor, promoting the variable if necessary.
- *
- * @returns VBox status code.
- * @param   pDbgc       Debug console instanace.
- * @param   pVar        Variable.
- * @param   pVarDesc    Variable descriptor.
+ * dbgcEvalSubUnary worker that handles simple numeric or pointer expressions.
+ *
+ * @returns VBox status code. pResult contains the result on success.
+ * @param   pDbgc       Debugger console instance data.
+ * @param   pszExpr     The expression string.
+ * @param   cchExpr     The length of the expression.
+ * @param   enmCategory The desired type category (for range / no range).
+ * @param   pResult     Where to store the result of the expression evaluation.
  */
-static int dbgcEvalSubMatchVar(PDBGC pDbgc, PDBGCVAR pVar, PCDBGCVARDESC pVarDesc)
+static int dbgcEvalSubNumericOrPointer(PDBGC pDbgc, char *pszExpr, size_t cchExpr, DBGCVARCAT enmCategory,
+                                       PDBGCVAR pResult)
 {
-    /*
-     * (If match or promoted to match, return, else break.)
-     */
-    switch (pVarDesc->enmCategory)
-    {
-        /*
-         * Anything goes
-         */
-        case DBGCVAR_CAT_ANY:
-            return VINF_SUCCESS;
-
-        /*
-         * Pointer with and without range.
-         * We can try resolve strings and symbols as symbols and promote
-         * numbers to flat GC pointers.
-         */
-        case DBGCVAR_CAT_POINTER_NO_RANGE:
-        case DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE:
-            if (pVar->enmRangeType != DBGCVAR_RANGE_NONE)
-                return VERR_DBGC_PARSE_NO_RANGE_ALLOWED;
-            /* fallthru */
-        case DBGCVAR_CAT_POINTER:
-        case DBGCVAR_CAT_POINTER_NUMBER:
-            switch (pVar->enmType)
-            {
-                case DBGCVAR_TYPE_GC_FLAT:
-                case DBGCVAR_TYPE_GC_FAR:
-                case DBGCVAR_TYPE_GC_PHYS:
-                case DBGCVAR_TYPE_HC_FLAT:
-                case DBGCVAR_TYPE_HC_PHYS:
-                    return VINF_SUCCESS;
-
-                case DBGCVAR_TYPE_SYMBOL:
-                case DBGCVAR_TYPE_STRING:
-                {
-                    DBGCVAR Var;
-                    int rc = dbgcSymbolGet(pDbgc, pVar->u.pszString, DBGCVAR_TYPE_GC_FLAT, &Var);
-                    if (RT_SUCCESS(rc))
-                    {
-                        /* deal with range */
-                        if (pVar->enmRangeType != DBGCVAR_RANGE_NONE)
-                        {
-                            Var.enmRangeType = pVar->enmRangeType;
-                            Var.u64Range = pVar->u64Range;
-                        }
-                        else if (pVarDesc->enmCategory == DBGCVAR_CAT_POINTER_NO_RANGE)
-                            Var.enmRangeType = DBGCVAR_RANGE_NONE;
-                        *pVar = Var;
-                        return rc;
-                    }
-                    break;
-                }
-
-                case DBGCVAR_TYPE_NUMBER:
-                    if (   pVarDesc->enmCategory != DBGCVAR_CAT_POINTER_NUMBER
-                        && pVarDesc->enmCategory != DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE)
-                    {
-                        RTGCPTR GCPtr = (RTGCPTR)pVar->u.u64Number;
-                        pVar->enmType = DBGCVAR_TYPE_GC_FLAT;
-                        pVar->u.GCFlat = GCPtr;
-                    }
-                    return VINF_SUCCESS;
-
-                default:
-                    break;
-            }
-            break;
-
-        /*
-         * GC pointer with and without range.
-         * We can try resolve strings and symbols as symbols and
-         * promote numbers to flat GC pointers.
-         */
-        case DBGCVAR_CAT_GC_POINTER_NO_RANGE:
-            if (pVar->enmRangeType != DBGCVAR_RANGE_NONE)
-                return VERR_DBGC_PARSE_NO_RANGE_ALLOWED;
-            /* fallthru */
-        case DBGCVAR_CAT_GC_POINTER:
-            switch (pVar->enmType)
-            {
-                case DBGCVAR_TYPE_GC_FLAT:
-                case DBGCVAR_TYPE_GC_FAR:
-                case DBGCVAR_TYPE_GC_PHYS:
-                    return VINF_SUCCESS;
-
-                case DBGCVAR_TYPE_HC_FLAT:
-                case DBGCVAR_TYPE_HC_PHYS:
-                    return VERR_DBGC_PARSE_CONVERSION_FAILED;
-
-                case DBGCVAR_TYPE_SYMBOL:
-                case DBGCVAR_TYPE_STRING:
-                {
-                    DBGCVAR Var;
-                    int rc = dbgcSymbolGet(pDbgc, pVar->u.pszString, DBGCVAR_TYPE_GC_FLAT, &Var);
-                    if (RT_SUCCESS(rc))
-                    {
-                        /* deal with range */
-                        if (pVar->enmRangeType != DBGCVAR_RANGE_NONE)
-                        {
-                            Var.enmRangeType = pVar->enmRangeType;
-                            Var.u64Range = pVar->u64Range;
-                        }
-                        else if (pVarDesc->enmCategory == DBGCVAR_CAT_POINTER_NO_RANGE)
-                            Var.enmRangeType = DBGCVAR_RANGE_NONE;
-                        *pVar = Var;
-                        return rc;
-                    }
-                    break;
-                }
-
-                case DBGCVAR_TYPE_NUMBER:
-                {
-                    RTGCPTR GCPtr = (RTGCPTR)pVar->u.u64Number;
-                    pVar->enmType = DBGCVAR_TYPE_GC_FLAT;
-                    pVar->u.GCFlat = GCPtr;
-                    return VINF_SUCCESS;
-                }
-
-                default:
-                    break;
-            }
-            break;
-
-        /*
-         * Number with or without a range.
-         * Numbers can be resolved from symbols, but we cannot demote a pointer
-         * to a number.
-         */
-        case DBGCVAR_CAT_NUMBER_NO_RANGE:
-            if (pVar->enmRangeType != DBGCVAR_RANGE_NONE)
-                return VERR_DBGC_PARSE_NO_RANGE_ALLOWED;
-            /* fallthru */
-        case DBGCVAR_CAT_NUMBER:
-            switch (pVar->enmType)
-            {
-                case DBGCVAR_TYPE_NUMBER:
-                    return VINF_SUCCESS;
-
-                case DBGCVAR_TYPE_SYMBOL:
-                case DBGCVAR_TYPE_STRING:
-                {
-                    DBGCVAR Var;
-                    int rc = dbgcSymbolGet(pDbgc, pVar->u.pszString, DBGCVAR_TYPE_NUMBER, &Var);
-                    if (RT_SUCCESS(rc))
-                    {
-                        *pVar = Var;
-                        return rc;
-                    }
-                    break;
-                }
-                default:
-                    break;
-            }
-            break;
-
-        /*
-         * Strings can easily be made from symbols (and of course strings).
-         * We could consider reformatting the addresses and numbers into strings later...
-         */
-        case DBGCVAR_CAT_STRING:
-            switch (pVar->enmType)
-            {
-                case DBGCVAR_TYPE_SYMBOL:
-                    pVar->enmType = DBGCVAR_TYPE_STRING;
-                    /* fallthru */
-                case DBGCVAR_TYPE_STRING:
-                    return VINF_SUCCESS;
-                default:
-                    break;
-            }
-            break;
-
-        /*
-         * Symol is pretty much the same thing as a string (at least until we actually implement it).
-         */
-        case DBGCVAR_CAT_SYMBOL:
-            switch (pVar->enmType)
-            {
-                case DBGCVAR_TYPE_STRING:
-                    pVar->enmType = DBGCVAR_TYPE_SYMBOL;
-                    /* fallthru */
-                case DBGCVAR_TYPE_SYMBOL:
-                    return VINF_SUCCESS;
-                default:
-                    break;
-            }
-            break;
-
-        /*
-         * Anything else is illegal.
-         */
+    char const  ch  = pszExpr[0];
+    char const  ch2 = pszExpr[1];
+
+    /* 0x<hex digits> */
+    if (ch == '0' && (ch2 == 'x' || ch2 == 'X'))
+        return dbgcEvalSubNum(pszExpr + 2, 16, pResult);
+
+    /* <hex digits>h */
+    if (RT_C_IS_XDIGIT(*pszExpr) && (pszExpr[cchExpr - 1] == 'h' || pszExpr[cchExpr - 1] == 'H'))
+    {
+        pszExpr[cchExpr] = '\0';
+        return dbgcEvalSubNum(pszExpr, 16, pResult);
+    }
+
+    /* 0i<decimal digits> */
+    if (ch == '0' && ch2 == 'i')
+        return dbgcEvalSubNum(pszExpr + 2, 10, pResult);
+
+    /* 0t<octal digits> */
+    if (ch == '0' && ch2 == 't')
+        return dbgcEvalSubNum(pszExpr + 2, 8, pResult);
+
+    /* 0y<binary digits> */
+    if (ch == '0' && ch2 == 'y')
+        return dbgcEvalSubNum(pszExpr + 2, 10, pResult);
+
+    /* Hex number? */
+    unsigned off = 0;
+    while (RT_C_IS_XDIGIT(pszExpr[off]) || pszExpr[off] == '`')
+        off++;
+    if (off == cchExpr)
+        return dbgcEvalSubNum(pszExpr, 16, pResult);
+
+    /*
+     * Some kind of symbol?
+     */
+    DBGCVARTYPE enmType;
+    bool        fStripRange = false;
+    switch (enmCategory)
+    {
+        case DBGCVAR_CAT_POINTER_NUMBER:            enmType = DBGCVAR_TYPE_NUMBER; break;
+        case DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE:   enmType = DBGCVAR_TYPE_NUMBER; fStripRange = true; break;
+        case DBGCVAR_CAT_POINTER:                   enmType = DBGCVAR_TYPE_NUMBER; break;
+        case DBGCVAR_CAT_POINTER_NO_RANGE:          enmType = DBGCVAR_TYPE_NUMBER; fStripRange = true; break;
+        case DBGCVAR_CAT_GC_POINTER:                enmType = DBGCVAR_TYPE_GC_FLAT; break;
+        case DBGCVAR_CAT_GC_POINTER_NO_RANGE:       enmType = DBGCVAR_TYPE_GC_FLAT; fStripRange = true; break;
+        case DBGCVAR_CAT_NUMBER:                    enmType = DBGCVAR_TYPE_NUMBER; break;
+        case DBGCVAR_CAT_NUMBER_NO_RANGE:           enmType = DBGCVAR_TYPE_NUMBER; fStripRange = true; break;
         default:
-            AssertMsgFailed(("enmCategory=%d\n", pVar->enmType));
-            break;
-    }
-
-    return VERR_DBGC_PARSE_NO_ARGUMENT_MATCH;
+            AssertFailedReturn(VERR_DBGC_PARSE_NOT_IMPLEMENTED);
+    }
+
+    if (   (*pszExpr == '"' || *pszExpr == '\'')
+        && pszExpr[cchExpr - 1] == *pszExpr)
+    {
+        pszExpr[cchExpr - 1] = '\0';
+        pszExpr++;
+    }
+
+    int rc = dbgcSymbolGet(pDbgc, pszExpr, enmType, pResult);
+    if (RT_SUCCESS(rc))
+    {
+        if (fStripRange)
+        {
+            pResult->enmRangeType = DBGCVAR_RANGE_NONE;
+            pResult->u64Range     = 0;
+        }
+    }
+    else if (rc == VERR_DBGC_PARSE_NOT_IMPLEMENTED)
+        rc = VERR_DBGC_PARSE_INVALID_NUMBER;
+    return rc;
 }
 
 
 /**
- * Matches a set of variables with a description set.
- *
- * This is typically used for routine arguments before a call. The effects in
- * addition to the validation, is that some variables might be propagated to
- * other types in order to match the description. The following transformations
- * are supported:
- *      - String reinterpreted as a symbol and resolved to a number or pointer.
- *      - Number to a pointer.
- *      - Pointer to a number.
- *
- * @returns VBox status code. Modified @a paVars on success.
+ * dbgcEvalSubUnary worker that handles simple DBGCVAR_CAT_ANY expressions.
+ *
+ * @returns VBox status code. pResult contains the result on success.
+ * @param   pDbgc       Debugger console instance data.
+ * @param   pszExpr     The expression string.
+ * @param   cchExpr     The length of the expression.
+ * @param   pResult     Where to store the result of the expression evaluation.
  */
-static int dbgcEvalSubMatchVars(PDBGC pDbgc, unsigned cVarsMin, unsigned cVarsMax,
-                                PCDBGCVARDESC paVarDescs, unsigned cVarDescs,
-                                PDBGCVAR paVars, unsigned cVars)
+static int dbgcEvalSubUnaryAny(PDBGC pDbgc, char *pszExpr, size_t cchExpr, PDBGCVAR pResult)
 {
-    /*
-     * Just do basic min / max checks first.
-     */
-    if (cVars < cVarsMin)
-        return VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS;
-    if (cVars > cVarsMax)
-        return VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS;
-
-    /*
-     * Match the descriptors and actual variables.
-     */
-    PCDBGCVARDESC   pPrevDesc = NULL;
-    unsigned        cCurDesc = 0;
-    unsigned        iVar = 0;
-    unsigned        iVarDesc = 0;
-    while (iVar < cVars)
-    {
-        /* walk the descriptors */
-        if (iVarDesc >= cVarDescs)
-            return VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS;
-        if (    (    paVarDescs[iVarDesc].fFlags & DBGCVD_FLAGS_DEP_PREV
-                &&  &paVarDescs[iVarDesc - 1] != pPrevDesc)
-            ||  cCurDesc >= paVarDescs[iVarDesc].cTimesMax)
-        {
-            iVarDesc++;
-            if (iVarDesc >= cVarDescs)
-                return VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS;
-            cCurDesc = 0;
-        }
-
-        /*
-         * Skip thru optional arguments until we find something which matches
-         * or can easily be promoted to what the descriptor want.
-         */
-        for (;;)
-        {
-            int rc = dbgcEvalSubMatchVar(pDbgc, &paVars[iVar], &paVarDescs[iVarDesc]);
-            if (RT_SUCCESS(rc))
-            {
-                paVars[iVar].pDesc = &paVarDescs[iVarDesc];
-                cCurDesc++;
-                break;
-            }
-
-            /* can we advance? */
-            if (paVarDescs[iVarDesc].cTimesMin > cCurDesc)
-                return VERR_DBGC_PARSE_ARGUMENT_TYPE_MISMATCH;
-            if (++iVarDesc >= cVarDescs)
-                return VERR_DBGC_PARSE_ARGUMENT_TYPE_MISMATCH;
-            cCurDesc = 0;
-        }
-
-        /* next var */
-        iVar++;
-    }
-
-    /*
-     * Check that the rest of the descriptors are optional.
-     */
-    while (iVarDesc < cVarDescs)
-    {
-        if (paVarDescs[iVarDesc].cTimesMin > cCurDesc)
-            return VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS;
-        cCurDesc = 0;
-
-        /* next */
-        iVarDesc++;
-    }
-
-    return VINF_SUCCESS;
+    char const  ch  = pszExpr[0];
+    char const  ch2 = pszExpr[1];
+    unsigned    off = 2;
+
+    /* 0x<hex digits> */
+    if (ch == '0' && (ch2 == 'x' || ch2 == 'X'))
+    {
+        while (RT_C_IS_XDIGIT(pszExpr[off]) || pszExpr[off] == '`')
+            off++;
+        if (off == cchExpr)
+            return dbgcEvalSubNum(pszExpr + 2, 16, pResult);
+        return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
+    }
+
+    /* <hex digits>h */
+    if (RT_C_IS_XDIGIT(*pszExpr) && (pszExpr[cchExpr - 1] == 'h' || pszExpr[cchExpr - 1] == 'H'))
+    {
+        cchExpr--;
+        while (off < cchExpr && (RT_C_IS_XDIGIT(pszExpr[off]) || pszExpr[off] == '`'))
+            off++;
+        if (off == cchExpr)
+        {
+            pszExpr[cchExpr] = '\0';
+            return dbgcEvalSubNum(pszExpr, 16, pResult);
+        }
+        return dbgcEvalSubString(pDbgc, pszExpr, cchExpr + 1, pResult);
+    }
+
+    /* 0i<decimal digits> */
+    if (ch == '0' && ch2 == 'i')
+    {
+        while (RT_C_IS_DIGIT(pszExpr[off]) || pszExpr[off] == '`')
+            off++;
+        if (off == cchExpr)
+            return dbgcEvalSubNum(pszExpr + 2, 10, pResult);
+        return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
+    }
+
+    /* 0t<octal digits> */
+    if (ch == '0' && ch2 == 't')
+    {
+        while (RT_C_IS_ODIGIT(pszExpr[off]) || pszExpr[off] == '`')
+            off++;
+        if (off == cchExpr)
+            return dbgcEvalSubNum(pszExpr + 2, 8, pResult);
+        return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
+    }
+
+    /* 0y<binary digits> */
+    if (ch == '0' && ch2 == 'y')
+    {
+        while (pszExpr[off] == '0' || pszExpr[off] == '1' || pszExpr[off] == '`')
+            off++;
+        if (off == cchExpr)
+            return dbgcEvalSubNum(pszExpr + 2, 10, pResult);
+        return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
+    }
+
+    /* Ok, no prefix of suffix. Is it a hex number after all? If not it must
+       be a string. */
+    off = 0;
+    while (RT_C_IS_XDIGIT(pszExpr[off]) || pszExpr[off] == '`')
+        off++;
+    if (off == cchExpr)
+        return dbgcEvalSubNum(pszExpr, 16, pResult);
+    return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
 }
 
@@ -481,7 +352,5 @@
             pszExpr2++;
 
-        if (!*pszExpr2)
-            rc = VERR_DBGC_PARSE_EMPTY_ARGUMENT;
-        else
+        if (*pszExpr2)
         {
             DBGCVAR Arg;
@@ -493,103 +362,99 @@
                 rc = pOp->pfnHandlerUnary(pDbgc, &Arg, enmCategory, pResult);
         }
-    }
-    else
-    {
-        /*
-         * Didn't find any operators, so it we have to check if this can be an
-         * function call before assuming numeric or string expression.
-         *
-         * (ASSUMPTIONS:)
-         * A function name only contains alphanumerical chars and it can not start
-         * with a numerical character.
-         * Immediately following the name is a parenthesis which must over
-         * the remaining part of the expression.
-         */
-        bool    fExternal = *pszExpr == '.';
-        char   *pszFun    = fExternal ? pszExpr + 1 : pszExpr;
-        char   *pszFunEnd = NULL;
-        if (pszExpr[cchExpr - 1] == ')' && RT_C_IS_ALPHA(*pszFun))
-        {
-            pszFunEnd = pszExpr + 1;
-            while (*pszFunEnd != '(' && RT_C_IS_ALNUM(*pszFunEnd))
-                pszFunEnd++;
-            if (*pszFunEnd != '(')
-                pszFunEnd = NULL;
-        }
-
-        if (pszFunEnd)
-        {
-            /*
-             * Ok, it's a function call.
-             */
-            if (fExternal)
-                pszExpr++, cchExpr--;
-            PCDBGCCMD pFun = dbgcRoutineLookup(pDbgc, pszExpr, pszFunEnd - pszExpr, fExternal);
-            if (!pFun)
-                return VERR_DBGC_PARSE_FUNCTION_NOT_FOUND;
+        else
+            rc = VERR_DBGC_PARSE_EMPTY_ARGUMENT;
+        return rc;
+    }
+
+    /*
+     * Could this be a function call?
+     *
+     * ASSUMPTIONS:
+     *    - A function name only contains alphanumerical chars and it can not
+     *      start with a numerical character.
+     *    - Immediately following the name is a parenthesis which must cover
+     *      the remaining part of the expression.
+     */
+    bool    fExternal = *pszExpr == '.';
+    char   *pszFun    = fExternal ? pszExpr + 1 : pszExpr;
+    char   *pszFunEnd = NULL;
+    if (pszExpr[cchExpr - 1] == ')' && RT_C_IS_ALPHA(*pszFun))
+    {
+        pszFunEnd = pszExpr + 1;
+        while (*pszFunEnd != '(' && RT_C_IS_ALNUM(*pszFunEnd))
+            pszFunEnd++;
+        if (*pszFunEnd != '(')
+            pszFunEnd = NULL;
+    }
+    if (pszFunEnd)
+    {
+        /*
+         * Ok, it's a function call.
+         */
+        if (fExternal)
+            pszExpr++, cchExpr--;
+        PCDBGCCMD pFun = dbgcRoutineLookup(pDbgc, pszExpr, pszFunEnd - pszExpr, fExternal);
+        if (!pFun)
+            return VERR_DBGC_PARSE_FUNCTION_NOT_FOUND;
 #if 0
-            if (!pFun->pResultDesc)
-                return VERR_DBGC_PARSE_NOT_A_FUNCTION;
-
-            /*
-             * Parse the expression in parenthesis.
-             */
-            cchExpr -= pszFunEnd - pszExpr;
-            pszExpr = pszFunEnd;
-            /** @todo implement multiple arguments. */
-            DBGCVAR     Arg;
-            rc = dbgcEvalSub(pDbgc, pszExpr, cchExpr, enmCategory, &Arg);
+        if (!pFun->pResultDesc)
+            return VERR_DBGC_PARSE_NOT_A_FUNCTION;
+
+        /*
+         * Parse the expression in parenthesis.
+         */
+        cchExpr -= pszFunEnd - pszExpr;
+        pszExpr = pszFunEnd;
+        /** @todo implement multiple arguments. */
+        DBGCVAR     Arg;
+        rc = dbgcEvalSub(pDbgc, pszExpr, cchExpr, enmCategory, &Arg);
+        if (!rc)
+        {
+            rc = dbgcEvalSubMatchVars(pDbgc, pFun->cArgsMin, pFun->cArgsMax, pFun->paArgDescs, pFun->cArgDescs, &Arg, 1);
             if (!rc)
-            {
-                rc = dbgcEvalSubMatchVars(pDbgc, pFun->cArgsMin, pFun->cArgsMax, pFun->paArgDescs, pFun->cArgDescs, &Arg, 1);
-                if (!rc)
-                    rc = pFun->pfnHandler(pFun, &pDbgc->CmdHlp, pDbgc->pVM, &Arg, 1, pResult);
-            }
-            else if (rc == VERR_DBGC_PARSE_EMPTY_ARGUMENT && pFun->cArgsMin == 0)
-                rc = pFun->pfnHandler(pFun, &pDbgc->CmdHlp, pDbgc->pVM, NULL, 0, pResult);
+                rc = pFun->pfnHandler(pFun, &pDbgc->CmdHlp, pDbgc->pVM, &Arg, 1, pResult);
+        }
+        else if (rc == VERR_DBGC_PARSE_EMPTY_ARGUMENT && pFun->cArgsMin == 0)
+            rc = pFun->pfnHandler(pFun, &pDbgc->CmdHlp, pDbgc->pVM, NULL, 0, pResult);
 #else
-            rc = VERR_NOT_IMPLEMENTED;
+        rc = VERR_NOT_IMPLEMENTED;
 #endif
-        }
-        else if (   enmCategory == DBGCVAR_CAT_STRING
-                 || enmCategory == DBGCVAR_CAT_SYMBOL)
-            rc = dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
-        else
-        {
-            /*
-             * Didn't find any operators, so it must be a plain expression.
-             * This might be numeric or a string expression.
-             */
-            char ch  = pszExpr[0];
-            char ch2 = pszExpr[1];
-            if (ch == '0' && (ch2 == 'x' || ch2 == 'X'))
-                rc = dbgcEvalSubNum(pszExpr + 2, 16, pResult);
-            else if (ch == '0' && (ch2 == 'i' || ch2 == 'i'))
-                rc = dbgcEvalSubNum(pszExpr + 2, 10, pResult);
-            else if (ch == '0' && (ch2 == 't' || ch2 == 'T'))
-                rc = dbgcEvalSubNum(pszExpr + 2, 8, pResult);
-            /// @todo 0b doesn't work as a binary prefix, we confuse it with 0bf8:0123 and stuff.
-            //else if (ch == '0' && (ch2 == 'b' || ch2 == 'b'))
-            //    rc = dbgcEvalSubNum(pszExpr + 2, 2, pResult);
-            else
-            {
-                /*
-                 * Hexadecimal number or a string?
-                 */
-                char *psz = pszExpr;
-                while (RT_C_IS_XDIGIT(*psz))
-                    psz++;
-                if (!*psz)
-                    rc = dbgcEvalSubNum(pszExpr, 16, pResult);
-                else if ((*psz == 'h' || *psz == 'H') && !psz[1])
-                {
-                    *psz = '\0';
-                    rc = dbgcEvalSubNum(pszExpr, 16, pResult);
-                }
-                else
-                    rc = dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
-            }
-        }
-    }
+        return rc;
+    }
+
+    /*
+     * Assuming plain expression.
+     * Didn't find any operators, so it must be a plain expression.
+     * Go by desired category first, then if anythings go, try guess.
+     */
+    switch (enmCategory)
+    {
+        case DBGCVAR_CAT_ANY:
+            return dbgcEvalSubUnaryAny(pDbgc, pszExpr, cchExpr, pResult);
+
+        case DBGCVAR_CAT_POINTER_NUMBER:
+        case DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE:
+        case DBGCVAR_CAT_POINTER:
+        case DBGCVAR_CAT_POINTER_NO_RANGE:
+        case DBGCVAR_CAT_GC_POINTER:
+        case DBGCVAR_CAT_GC_POINTER_NO_RANGE:
+        case DBGCVAR_CAT_NUMBER:
+        case DBGCVAR_CAT_NUMBER_NO_RANGE:
+            /* Pointers will be promoted later. */
+            return dbgcEvalSubNumericOrPointer(pDbgc, pszExpr, cchExpr, enmCategory, pResult);
+
+        case DBGCVAR_CAT_STRING:
+        case DBGCVAR_CAT_SYMBOL:
+            /* Symbols will be promoted later. */
+            return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
+
+        case DBGCVAR_CAT_OPTION:
+        case DBGCVAR_CAT_OPTION_STRING:
+        case DBGCVAR_CAT_OPTION_NUMBER:
+            return VERR_DBGC_PARSE_NOT_IMPLEMENTED;
+    }
+
+    AssertMsgFailed(("enmCategory=%d\n", enmCategory));
+    rc = VERR_NOT_IMPLEMENTED;
 
     return rc;
@@ -623,8 +488,4 @@
     if (!*pszExpr)
         return VERR_DBGC_PARSE_EMPTY_ARGUMENT;
-
-    /* it there is any kind of quoting in the expression, it's string meat. */
-    if (strpbrk(pszExpr, "\"'`"))
-        return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
 
     /*
@@ -671,8 +532,10 @@
     }
 
-    /* tabs to spaces. */
+#if 0  /* why was this needed? It'll screw up strings. */
+    /* tabs to spaces */
     char *psz = pszExpr;
     while ((psz = strchr(psz, '\t')) != NULL)
         *psz = ' ';
+#endif
 
     /*
@@ -682,12 +545,13 @@
      * evaluate with respect to unary operators
      */
-    char       *pszOpSplit = NULL;
-    PCDBGCOP    pOpSplit = NULL;
-    unsigned    cBinaryOps = 0;
-    unsigned    cPar = 0;
+    char       *pszOpSplit  = NULL;
+    PCDBGCOP    pOpSplit    = NULL;
+    unsigned    cBinaryOps  = 0;
+    unsigned    cPar        = 0;
+    char        chQuote     = '\0';
+    char        chPrev      = ' ';
+    bool        fBinary     = false;
+    char       *psz         = pszExpr;
     char        ch;
-    char        chPrev = ' ';
-    bool        fBinary = false;
-    psz = pszExpr;
 
     while ((ch = *psz) != '\0')
@@ -695,7 +559,21 @@
         //Log2(("ch=%c cPar=%d fBinary=%d\n", ch, cPar, fBinary));
         /*
-         * Parenthesis.
-         */
-        if (ch == '(')
+         * String quoting.
+         */
+        if (chQuote)
+        {
+            if (   ch == chQuote
+                && psz[1] != chQuote)
+            {
+                chQuote = '\0';
+                fBinary = true;
+            }
+        }
+        else if (ch == '"' || ch == '\'')
+            chQuote = ch;
+        /*
+         * Parentheses.
+         */
+        else if (ch == '(')
         {
             cPar++;
@@ -754,4 +632,6 @@
     } /* parse loop. */
 
+    if (chQuote)
+        return VERR_DBGC_PARSE_UNBALANCED_QUOTE;
 
     /*
@@ -791,8 +671,234 @@
     }
     else
-        /* plain expression or using unary operators perhaps with parentheses. */
+        /* plain expression, qutoed string, or using unary operators perhaps with parentheses. */
         rc = dbgcEvalSubUnary(pDbgc, pszExpr, cchExpr, enmCategory, pResult);
 
     return rc;
+}
+
+
+/**
+ * Worker for dbgcProcessArguments that performs type checking and promoptions.
+ *
+ * @returns VBox status code.
+ *
+ * @param   pDbgc       Debugger console instance data.
+ * @param   enmCategory The target category for the result.
+ * @param   pArg        The argument to check and promote.
+ */
+static int dbgcCheckAndTypePromoteArgument(PDBGC pDbgc, DBGCVARCAT enmCategory, PDBGCVAR pArg)
+{
+    switch (enmCategory)
+    {
+        /*
+         * Anything goes
+         */
+        case DBGCVAR_CAT_ANY:
+            return VINF_SUCCESS;
+
+        /*
+         * Pointer with and without range.
+         * We can try resolve strings and symbols as symbols and promote
+         * numbers to flat GC pointers.
+         */
+        case DBGCVAR_CAT_POINTER_NO_RANGE:
+        case DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE:
+            if (pArg->enmRangeType != DBGCVAR_RANGE_NONE)
+                return VERR_DBGC_PARSE_NO_RANGE_ALLOWED;
+            /* fallthru */
+        case DBGCVAR_CAT_POINTER:
+        case DBGCVAR_CAT_POINTER_NUMBER:
+            switch (pArg->enmType)
+            {
+                case DBGCVAR_TYPE_GC_FLAT:
+                case DBGCVAR_TYPE_GC_FAR:
+                case DBGCVAR_TYPE_GC_PHYS:
+                case DBGCVAR_TYPE_HC_FLAT:
+                case DBGCVAR_TYPE_HC_PHYS:
+                    return VINF_SUCCESS;
+
+                case DBGCVAR_TYPE_SYMBOL:
+                case DBGCVAR_TYPE_STRING:
+                {
+                    DBGCVAR Var;
+                    int rc = dbgcSymbolGet(pDbgc, pArg->u.pszString, DBGCVAR_TYPE_GC_FLAT, &Var);
+                    if (RT_SUCCESS(rc))
+                    {
+                        /* deal with range */
+                        if (pArg->enmRangeType != DBGCVAR_RANGE_NONE)
+                        {
+                            Var.enmRangeType = pArg->enmRangeType;
+                            Var.u64Range = pArg->u64Range;
+                        }
+                        else if (enmCategory == DBGCVAR_CAT_POINTER_NO_RANGE)
+                            Var.enmRangeType = DBGCVAR_RANGE_NONE;
+                        *pArg = Var;
+                    }
+                    return rc;
+                }
+
+                case DBGCVAR_TYPE_NUMBER:
+                    if (   enmCategory != DBGCVAR_CAT_POINTER_NUMBER
+                        && enmCategory != DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE)
+                    {
+                        RTGCPTR GCPtr = (RTGCPTR)pArg->u.u64Number;
+                        pArg->enmType = DBGCVAR_TYPE_GC_FLAT;
+                        pArg->u.GCFlat = GCPtr;
+                    }
+                    return VINF_SUCCESS;
+
+                default:
+                    AssertMsgFailedReturn(("Invalid type %d\n"), VERR_DBGC_PARSE_INCORRECT_ARG_TYPE);
+            }
+            break;                      /* (not reached) */
+
+        /*
+         * GC pointer with and without range.
+         * We can try resolve strings and symbols as symbols and
+         * promote numbers to flat GC pointers.
+         */
+        case DBGCVAR_CAT_GC_POINTER_NO_RANGE:
+            if (pArg->enmRangeType != DBGCVAR_RANGE_NONE)
+                return VERR_DBGC_PARSE_NO_RANGE_ALLOWED;
+            /* fallthru */
+        case DBGCVAR_CAT_GC_POINTER:
+            switch (pArg->enmType)
+            {
+                case DBGCVAR_TYPE_GC_FLAT:
+                case DBGCVAR_TYPE_GC_FAR:
+                case DBGCVAR_TYPE_GC_PHYS:
+                    return VINF_SUCCESS;
+
+                case DBGCVAR_TYPE_HC_FLAT:
+                case DBGCVAR_TYPE_HC_PHYS:
+                    return VERR_DBGC_PARSE_CONVERSION_FAILED;
+
+                case DBGCVAR_TYPE_SYMBOL:
+                case DBGCVAR_TYPE_STRING:
+                {
+                    DBGCVAR Var;
+                    int rc = dbgcSymbolGet(pDbgc, pArg->u.pszString, DBGCVAR_TYPE_GC_FLAT, &Var);
+                    if (RT_SUCCESS(rc))
+                    {
+                        /* deal with range */
+                        if (pArg->enmRangeType != DBGCVAR_RANGE_NONE)
+                        {
+                            Var.enmRangeType = pArg->enmRangeType;
+                            Var.u64Range = pArg->u64Range;
+                        }
+                        else if (enmCategory == DBGCVAR_CAT_POINTER_NO_RANGE)
+                            Var.enmRangeType = DBGCVAR_RANGE_NONE;
+                        *pArg = Var;
+                    }
+                    return rc;
+                }
+
+                case DBGCVAR_TYPE_NUMBER:
+                {
+                    RTGCPTR GCPtr = (RTGCPTR)pArg->u.u64Number;
+                    pArg->enmType = DBGCVAR_TYPE_GC_FLAT;
+                    pArg->u.GCFlat = GCPtr;
+                    return VINF_SUCCESS;
+                }
+
+                default:
+                    AssertMsgFailedReturn(("Invalid type %d\n"), VERR_DBGC_PARSE_INCORRECT_ARG_TYPE);
+            }
+            break;                      /* (not reached) */
+
+        /*
+         * Number with or without a range.
+         * Numbers can be resolved from symbols, but we cannot demote a pointer
+         * to a number.
+         */
+        case DBGCVAR_CAT_NUMBER_NO_RANGE:
+            if (pArg->enmRangeType != DBGCVAR_RANGE_NONE)
+                return VERR_DBGC_PARSE_NO_RANGE_ALLOWED;
+            /* fallthru */
+        case DBGCVAR_CAT_NUMBER:
+            switch (pArg->enmType)
+            {
+                case DBGCVAR_TYPE_GC_FLAT:
+                case DBGCVAR_TYPE_GC_FAR:
+                case DBGCVAR_TYPE_GC_PHYS:
+                case DBGCVAR_TYPE_HC_FLAT:
+                case DBGCVAR_TYPE_HC_PHYS:
+                    return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE;
+
+                case DBGCVAR_TYPE_NUMBER:
+                    return VINF_SUCCESS;
+
+                case DBGCVAR_TYPE_SYMBOL:
+                case DBGCVAR_TYPE_STRING:
+                {
+                    DBGCVAR Var;
+                    int rc = dbgcSymbolGet(pDbgc, pArg->u.pszString, DBGCVAR_TYPE_NUMBER, &Var);
+                    if (RT_SUCCESS(rc))
+                    {
+                        /* deal with range */
+                        if (pArg->enmRangeType != DBGCVAR_RANGE_NONE)
+                        {
+                            Var.enmRangeType = pArg->enmRangeType;
+                            Var.u64Range = pArg->u64Range;
+                        }
+                        else if (enmCategory == DBGCVAR_CAT_POINTER_NO_RANGE)
+                            Var.enmRangeType = DBGCVAR_RANGE_NONE;
+                        *pArg = Var;
+                    }
+                    return rc;
+                }
+
+                default:
+                    AssertMsgFailedReturn(("Invalid type %d\n"), VERR_DBGC_PARSE_INCORRECT_ARG_TYPE);
+            }
+            break;                      /* (not reached) */
+
+        /*
+         * Symbols and strings are basically the same thing for the time being.
+         */
+        case DBGCVAR_CAT_STRING:
+        case DBGCVAR_CAT_SYMBOL:
+        {
+            switch (pArg->enmType)
+            {
+                case DBGCVAR_TYPE_STRING:
+                    if (enmCategory == DBGCVAR_CAT_SYMBOL)
+                        pArg->enmType = DBGCVAR_TYPE_SYMBOL;
+                    return VINF_SUCCESS;
+
+                case DBGCVAR_TYPE_SYMBOL:
+                    if (enmCategory == DBGCVAR_CAT_STRING)
+                        pArg->enmType = DBGCVAR_TYPE_STRING;
+                    return VINF_SUCCESS;
+                default:
+                    break;
+            }
+
+            /* Stringify numeric and poitner values. */
+            size_t cbScratch = sizeof(pDbgc->achScratch) - (pDbgc->pszScratch - &pDbgc->achScratch[0]);
+            size_t cch = pDbgc->CmdHlp.pfnStrPrintf(&pDbgc->CmdHlp, pDbgc->pszScratch, cbScratch, "%Dv", pArg);
+            if (cch + 1 >= cbScratch)
+                return VERR_DBGC_PARSE_NO_SCRATCH;
+
+            pArg->enmType      = enmCategory == DBGCVAR_CAT_STRING ? DBGCVAR_TYPE_STRING : DBGCVAR_TYPE_SYMBOL;
+            pArg->u.pszString  = pDbgc->pszScratch;
+            pArg->enmRangeType = DBGCVAR_RANGE_BYTES;
+            pArg->u64Range     = cch;
+
+            pDbgc->pszScratch += cch + 1;
+            return VINF_SUCCESS;
+        }
+
+        /*
+         * These are not yet implemented.
+         */
+        case DBGCVAR_CAT_OPTION:
+        case DBGCVAR_CAT_OPTION_STRING:
+        case DBGCVAR_CAT_OPTION_NUMBER:
+            AssertMsgFailedReturn(("Not implemented enmCategory=%d\n", enmCategory), VERR_DBGC_PARSE_NOT_IMPLEMENTED);
+
+        default:
+            AssertMsgFailedReturn(("Bad enmCategory=%d\n", enmCategory), VERR_DBGC_PARSE_NOT_IMPLEMENTED);
+    }
 }
 
@@ -835,20 +941,4 @@
 
     /*
-     * This is a hack, it's "temporary" and should go away "when" the parser is
-     * modified to match arguments while parsing.
-     */
-    if (    pCmd->cArgsMax == 1
-        &&  pCmd->cArgsMin == 1
-        &&  pCmd->cArgDescs == 1
-        &&  (   pCmd->paArgDescs[0].enmCategory == DBGCVAR_CAT_STRING
-             || pCmd->paArgDescs[0].enmCategory == DBGCVAR_CAT_SYMBOL)
-        &&  cArgs >= 1)
-    {
-        *pcArgs = 1;
-        RTStrStripR(pszArgs);
-        return dbgcEvalSubString(pDbgc, pszArgs, strlen(pszArgs), &paArgs[0]);
-    }
-
-    /*
      * The parse loop.
      */
@@ -871,12 +961,9 @@
         if (pArg >= &paArgs[cArgs])
             return VERR_DBGC_PARSE_ARGUMENT_OVERFLOW;
-#ifdef DEBUG_bird /* work in progress. */
         if (iVarDesc >= cVarDescs)
             return VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS;
 
         /* Walk argument descriptors. */
-        if (    (    paVarDescs[iVarDesc].fFlags & DBGCVD_FLAGS_DEP_PREV
-                &&  &paVarDescs[iVarDesc - 1] != pPrevDesc)
-            ||  cCurDesc >= paVarDescs[iVarDesc].cTimesMax)
+        if (cCurDesc >= paVarDescs[iVarDesc].cTimesMax)
         {
             iVarDesc++;
@@ -885,5 +972,4 @@
             cCurDesc = 0;
         }
-#endif
 
         /*
@@ -914,5 +1000,5 @@
              * We use the REXX way of escaping the quotation char, i.e. double occurrence.
              */
-            else if (ch == '\'' || ch == '"' || ch == '`')
+            else if (ch == '\'' || ch == '"')
             {
                 if (chQuote)
@@ -933,10 +1019,10 @@
              * Parenthesis can of course be nested.
              */
-            else if (ch == '(')
+            else if (!chQuote && ch == '(')
             {
                 cPar++;
                 fBinary = false;
             }
-            else if (ch == ')')
+            else if (!chQuote && ch == ')')
             {
                 if (!cPar)
@@ -997,6 +1083,4 @@
         size_t cchArgs = strlen(pszArgs);
 
-
-#ifdef DEBUG_bird /* work in progress. */
         /*
          * Try optional arguments until we find something which matches
@@ -1007,7 +1091,9 @@
             char *pszArgsCopy = (char *)RTMemDup(pszArgs, cchArgs + 1);
             if (!pszArgsCopy)
-                return VERR_NO_MEMORY;
-
-            int rc = dbgcEvalSub(pDbgc, pszArgs, strlen(pszArgs), paVarDescs[iVarDesc].enmCategory, pArg);
+                return VERR_DBGC_PARSE_NO_MEMORY;
+
+            int rc = dbgcEvalSub(pDbgc, pszArgs, cchArgs, paVarDescs[iVarDesc].enmCategory, pArg);
+            if (RT_SUCCESS(rc))
+                rc = dbgcCheckAndTypePromoteArgument(pDbgc, paVarDescs[iVarDesc].enmCategory, pArg);
             if (RT_SUCCESS(rc))
             {
@@ -1021,23 +1107,26 @@
             RTMemFree(pszArgsCopy);
 
-            /* can we advance? */
+            /* Continue searching optional descriptors? */
+            if (   rc != VERR_DBGC_PARSE_INCORRECT_ARG_TYPE
+                && rc != VERR_DBGC_PARSE_INVALID_NUMBER
+                && rc != VERR_DBGC_PARSE_NO_RANGE_ALLOWED
+               )
+                   return rc;
+
+            /* Try advance to the next descriptor. */
             if (paVarDescs[iVarDesc].cTimesMin > cCurDesc)
                 return rc;
-            if (++iVarDesc >= cVarDescs)
+            iVarDesc++;
+            if (!cCurDesc)
+                while (   iVarDesc < cVarDescs
+                       && (paVarDescs[iVarDesc].fFlags & DBGCVD_FLAGS_DEP_PREV))
+                    iVarDesc++;
+            if (iVarDesc >= cVarDescs)
                 return rc;
             cCurDesc = 0;
         }
 
-#else
-        /*
-         * Parse and evaluate the argument.
-         */
-        int rc = dbgcEvalSub(pDbgc, pszArgs, cchArgs, DBGCVAR_CAT_ANY, pArg);
-        if (RT_FAILURE(rc))
-            return rc;
-#endif
-
-        /*
-         * Next.
+        /*
+         * Next argument.
          */
         iVar++;
@@ -1050,7 +1139,20 @@
 
     /*
-     * Match the arguments.
-     */
-    return dbgcEvalSubMatchVars(pDbgc, pCmd->cArgsMin, pCmd->cArgsMax, pCmd->paArgDescs, pCmd->cArgDescs, pArg0, pArg - pArg0);
+     * Check that the rest of the argument descriptors indicate optional args.
+     */
+    if (iVarDesc < cVarDescs)
+    {
+        if (cCurDesc < paVarDescs[iVarDesc].cTimesMin)
+            return VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS;
+        iVarDesc++;
+        while (iVarDesc < cVarDescs)
+        {
+            if (paVarDescs[iVarDesc].cTimesMin)
+                return VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS;
+            iVarDesc++;
+        }
+    }
+
+    return VINF_SUCCESS;
 }
 
Index: trunk/src/VBox/Debugger/testcase/tstDBGCParser.cpp
===================================================================
--- trunk/src/VBox/Debugger/testcase/tstDBGCParser.cpp	(revision 41557)
+++ trunk/src/VBox/Debugger/testcase/tstDBGCParser.cpp	(revision 41558)
@@ -406,4 +406,12 @@
 
 
+/*
+ *
+ * CodeView emulation commands.
+ * CodeView emulation commands.
+ * CodeView emulation commands.
+ *
+ */
+
 
 static void testCodeView_ba(PDBGC pDbgc)
@@ -447,8 +455,677 @@
              DBGCVAR_TYPE_STRING, "command",                    DBGCVAR_RANGE_BYTES, UINT64_C(7));
 
-    tstTry(pDbgc, "ba x 1 0f000:1234 qnx 1000 \"command\"\n",   VERR_DBGC_PARSE_ARGUMENT_TYPE_MISMATCH);
-    tstTry(pDbgc, "ba x 1 0f000:1234 5 qnx \"command\"\n",      VERR_DBGC_PARSE_ARGUMENT_TYPE_MISMATCH);
-    tstTry(pDbgc, "ba x qnx 0f000:1234 5 1000 \"command\"\n",   VERR_DBGC_PARSE_ARGUMENT_TYPE_MISMATCH);
-    tstTry(pDbgc, "ba x 1 qnx 5 1000 \"command\"\n",            VERR_DBGC_PARSE_ARGUMENT_TYPE_MISMATCH);
+    tstTry(pDbgc, "ba x 1 0f000:1234 qnx 1000 \"command\"\n",   VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
+    tstTry(pDbgc, "ba x 1 0f000:1234 5 qnx \"command\"\n",      VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
+    tstTry(pDbgc, "ba x qnx 0f000:1234 5 1000 \"command\"\n",   VERR_DBGC_PARSE_INVALID_NUMBER);
+    tstTry(pDbgc, "ba x 1 qnx 5 1000 \"command\"\n",            VERR_DBGC_PARSE_INVALID_NUMBER);
+}
+
+
+static void testCodeView_bc(PDBGC pDbgc)
+{
+    RTTestISub("codeview - bc");
+}
+
+
+static void testCodeView_bd(PDBGC pDbgc)
+{
+    RTTestISub("codeview - bc");
+}
+
+
+static void testCodeView_be(PDBGC pDbgc)
+{
+    RTTestISub("codeview - be");
+}
+
+
+static void testCodeView_bl(PDBGC pDbgc)
+{
+    RTTestISub("codeview - bl");
+}
+
+
+static void testCodeView_bp(PDBGC pDbgc)
+{
+    RTTestISub("codeview - bp");
+}
+
+
+static void testCodeView_br(PDBGC pDbgc)
+{
+    RTTestISub("codeview - br");
+}
+
+
+static void testCodeView_d(PDBGC pDbgc)
+{
+    RTTestISub("codeview - d");
+}
+
+
+static void testCodeView_da(PDBGC pDbgc)
+{
+    RTTestISub("codeview - da");
+}
+
+
+static void testCodeView_db(PDBGC pDbgc)
+{
+    RTTestISub("codeview - db");
+}
+
+
+static void testCodeView_dd(PDBGC pDbgc)
+{
+    RTTestISub("codeview - dd");
+}
+
+
+static void testCodeView_dg(PDBGC pDbgc)
+{
+    RTTestISub("codeview - dg");
+}
+
+
+static void testCodeView_dga(PDBGC pDbgc)
+{
+    RTTestISub("codeview - dga");
+}
+
+
+static void testCodeView_di(PDBGC pDbgc)
+{
+    RTTestISub("codeview - di");
+}
+
+
+static void testCodeView_dia(PDBGC pDbgc)
+{
+    RTTestISub("codeview - dia");
+}
+
+
+static void testCodeView_dl(PDBGC pDbgc)
+{
+    RTTestISub("codeview - dl");
+}
+
+
+static void testCodeView_dla(PDBGC pDbgc)
+{
+    RTTestISub("codeview - dla");
+}
+
+
+static void testCodeView_dpd(PDBGC pDbgc)
+{
+    RTTestISub("codeview - dpd");
+}
+
+
+static void testCodeView_dpda(PDBGC pDbgc)
+{
+    RTTestISub("codeview - dpda");
+}
+
+
+static void testCodeView_dpdb(PDBGC pDbgc)
+{
+    RTTestISub("codeview - dpdb");
+}
+
+
+static void testCodeView_dpdg(PDBGC pDbgc)
+{
+    RTTestISub("codeview - dpdg");
+}
+
+
+static void testCodeView_dpdh(PDBGC pDbgc)
+{
+    RTTestISub("codeview - dpdh");
+}
+
+
+static void testCodeView_dph(PDBGC pDbgc)
+{
+    RTTestISub("codeview - dph");
+}
+
+
+static void testCodeView_dphg(PDBGC pDbgc)
+{
+    RTTestISub("codeview - dphg");
+}
+
+
+static void testCodeView_dphh(PDBGC pDbgc)
+{
+    RTTestISub("codeview - dphh");
+}
+
+
+static void testCodeView_dq(PDBGC pDbgc)
+{
+    RTTestISub("codeview - dq");
+}
+
+
+static void testCodeView_dt(PDBGC pDbgc)
+{
+    RTTestISub("codeview - dt");
+}
+
+
+static void testCodeView_dt16(PDBGC pDbgc)
+{
+    RTTestISub("codeview - dt16");
+}
+
+
+static void testCodeView_dt32(PDBGC pDbgc)
+{
+    RTTestISub("codeview - dt32");
+}
+
+
+static void testCodeView_dt64(PDBGC pDbgc)
+{
+    RTTestISub("codeview - dt64");
+}
+
+
+static void testCodeView_dw(PDBGC pDbgc)
+{
+    RTTestISub("codeview - dw");
+}
+
+
+static void testCodeView_eb(PDBGC pDbgc)
+{
+    RTTestISub("codeview - eb");
+}
+
+
+static void testCodeView_ew(PDBGC pDbgc)
+{
+    RTTestISub("codeview - ew");
+}
+
+
+static void testCodeView_ed(PDBGC pDbgc)
+{
+    RTTestISub("codeview - ed");
+}
+
+
+static void testCodeView_eq(PDBGC pDbgc)
+{
+    RTTestISub("codeview - eq");
+}
+
+
+static void testCodeView_g(PDBGC pDbgc)
+{
+    RTTestISub("codeview - g");
+}
+
+
+static void testCodeView_k(PDBGC pDbgc)
+{
+    RTTestISub("codeview - k");
+}
+
+
+static void testCodeView_kg(PDBGC pDbgc)
+{
+    RTTestISub("codeview - kg");
+}
+
+
+static void testCodeView_kh(PDBGC pDbgc)
+{
+    RTTestISub("codeview - kh");
+}
+
+
+static void testCodeView_lm(PDBGC pDbgc)
+{
+    RTTestISub("codeview - lm");
+}
+
+
+static void testCodeView_lmo(PDBGC pDbgc)
+{
+    RTTestISub("codeview - lmo");
+}
+
+
+static void testCodeView_ln(PDBGC pDbgc)
+{
+    RTTestISub("codeview - ln");
+}
+
+
+static void testCodeView_ls(PDBGC pDbgc)
+{
+    RTTestISub("codeview - ls");
+}
+
+
+static void testCodeView_m(PDBGC pDbgc)
+{
+    RTTestISub("codeview - m");
+}
+
+
+static void testCodeView_r(PDBGC pDbgc)
+{
+    RTTestISub("codeview - r");
+}
+
+
+static void testCodeView_rg(PDBGC pDbgc)
+{
+    RTTestISub("codeview - rg");
+}
+
+
+static void testCodeView_rg32(PDBGC pDbgc)
+{
+    RTTestISub("codeview - rg32");
+}
+
+
+static void testCodeView_rg64(PDBGC pDbgc)
+{
+    RTTestISub("codeview - rg64");
+}
+
+
+static void testCodeView_rh(PDBGC pDbgc)
+{
+    RTTestISub("codeview - rh");
+}
+
+
+static void testCodeView_rt(PDBGC pDbgc)
+{
+    RTTestISub("codeview - rt");
+}
+
+
+static void testCodeView_s(PDBGC pDbgc)
+{
+    RTTestISub("codeview - s");
+}
+
+
+static void testCodeView_sa(PDBGC pDbgc)
+{
+    RTTestISub("codeview - sa");
+}
+
+
+static void testCodeView_sb(PDBGC pDbgc)
+{
+    RTTestISub("codeview - sb");
+}
+
+
+static void testCodeView_sd(PDBGC pDbgc)
+{
+    RTTestISub("codeview - sd");
+}
+
+
+static void testCodeView_sq(PDBGC pDbgc)
+{
+    RTTestISub("codeview - sq");
+}
+
+
+static void testCodeView_su(PDBGC pDbgc)
+{
+    RTTestISub("codeview - su");
+}
+
+
+static void testCodeView_sw(PDBGC pDbgc)
+{
+    RTTestISub("codeview - sw");
+}
+
+
+static void testCodeView_t(PDBGC pDbgc)
+{
+    RTTestISub("codeview - t");
+}
+
+
+static void testCodeView_y(PDBGC pDbgc)
+{
+    RTTestISub("codeview - y");
+}
+
+
+static void testCodeView_u64(PDBGC pDbgc)
+{
+    RTTestISub("codeview - u64");
+}
+
+
+static void testCodeView_u32(PDBGC pDbgc)
+{
+    RTTestISub("codeview - u32");
+}
+
+
+static void testCodeView_u16(PDBGC pDbgc)
+{
+    RTTestISub("codeview - u16");
+}
+
+
+static void testCodeView_uv86(PDBGC pDbgc)
+{
+    RTTestISub("codeview - uv86");
+}
+
+
+/*
+ * Common commands.
+ */
+
+static void testCommon_bye_exit_quit(PDBGC pDbgc)
+{
+    RTTestISub("common - bye/exit/quit");
+    /* These have the same parameter descriptor and handler, the command really
+       just has a couple of aliases.*/
+    tstTry(pDbgc, "bye\n", VINF_SUCCESS);
+    tstTry(pDbgc, "bye x\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
+    tstTry(pDbgc, "bye 1\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
+    tstTry(pDbgc, "bye %bad:bad\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
+    tstTry(pDbgc, "exit\n", VINF_SUCCESS);
+    tstTry(pDbgc, "quit\n", VINF_SUCCESS);
+}
+
+
+static void testCommon_cpu(PDBGC pDbgc)
+{
+    RTTestISub("common - cpu");
+    tstTry(pDbgc, "cpu\n", VINF_SUCCESS);
+    tstTry(pDbgc, "cpu 1\n", VINF_SUCCESS);
+    tstTry(pDbgc, "cpu 1 1\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
+    tstTry(pDbgc, "cpu emt\n", VERR_DBGC_PARSE_INVALID_NUMBER);
+    tstTry(pDbgc, "cpu @eax\n", VINF_SUCCESS);
+    tstTry(pDbgc, "cpu %bad:bad\n", VERR_DBGC_PARSE_CONVERSION_FAILED);
+}
+
+
+static void testCommon_echo(PDBGC pDbgc)
+{
+    RTTestISub("common - echo");
+    tstTry(pDbgc, "echo\n", VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS);
+    tstTry(pDbgc, "echo 1\n", VINF_SUCCESS);
+    tstTryEx(pDbgc, "echo 1 2 3  4 5   6\n", VINF_SUCCESS, false, "1 2 3 4 5 6", -1);
+
+    /* The idea here is that since the prefered input is a string, we
+       definitely won't be mistaking number like beginnings as numbers. */
+    tstTryEx(pDbgc, "echo 1234567890abcdefghijklmn\n", VINF_SUCCESS, false, "1234567890abcdefghijklmn", -1);
+
+    /* The idea here is that we'll perform the + operation and then convert the
+       result to a string (hex). */
+    tstTryEx(pDbgc, "echo 1 + 1\n", VINF_SUCCESS, false, "2", -1);
+    tstTryEx(pDbgc, "echo \"1 + 1\"\n", VINF_SUCCESS, false, "1 + 1", -1);
+
+    tstTryEx(pDbgc, "echo 0i10 + 6\n", VINF_SUCCESS, false, "10", -1);
+    tstTryEx(pDbgc, "echo \"0i10 + 6\"\n", VINF_SUCCESS, false, "0i10 + 6", -1);
+
+    tstTryEx(pDbgc, "echo %f000:0010\n", VINF_SUCCESS, false, "%00000000000f0010", -1);
+    tstTryEx(pDbgc, "echo \"%f000:0010\"\n", VINF_SUCCESS, false, "%f000:0010", -1);
+
+    tstTry(pDbgc, "echo %bad:bad\n", VERR_DBGC_PARSE_CONVERSION_FAILED);
+}
+
+
+static void testCommon_format(PDBGC pDbgc)
+{
+    RTTestISub("common - format");
+}
+
+
+static void testCommon_detect(PDBGC pDbgc)
+{
+    RTTestISub("common - detect");
+}
+
+
+static void testCommon_harakiri(PDBGC pDbgc)
+{
+    RTTestISub("common - harakiri");
+}
+
+
+static void testCommon_help(PDBGC pDbgc)
+{
+    RTTestISub("common - help");
+}
+
+
+static void testCommon_info(PDBGC pDbgc)
+{
+    RTTestISub("common - info");
+    tstTry(pDbgc, "info 12fg\n", VINF_SUCCESS);
+    tstTry(pDbgc, "info fflags argument\n", VINF_SUCCESS);
+}
+
+
+static void testCommon_loadimage(PDBGC pDbgc)
+{
+    RTTestISub("common - loadimage");
+}
+
+
+static void testCommon_loadmap(PDBGC pDbgc)
+{
+    RTTestISub("common - loadmap");
+}
+
+
+static void testCommon_loadplugin(PDBGC pDbgc)
+{
+    RTTestISub("common - loadplugin");
+}
+
+
+static void testCommon_loadseg(PDBGC pDbgc)
+{
+    RTTestISub("common - loadseg");
+}
+
+
+static void testCommon_loadsyms(PDBGC pDbgc)
+{
+    RTTestISub("common - loadsyms");
+}
+
+
+static void testCommon_loadvars(PDBGC pDbgc)
+{
+    RTTestISub("common - loadvars");
+}
+
+
+static void testCommon_log(PDBGC pDbgc)
+{
+    RTTestISub("common - log");
+}
+
+
+static void testCommon_logdest(PDBGC pDbgc)
+{
+    RTTestISub("common - logdest");
+}
+
+
+static void testCommon_logflags(PDBGC pDbgc)
+{
+    RTTestISub("common - logflags");
+}
+
+
+static void testCommon_runscript(PDBGC pDbgc)
+{
+    RTTestISub("common - runscript");
+}
+
+
+static void testCommon_set(PDBGC pDbgc)
+{
+    RTTestISub("common - set");
+}
+
+
+static void testCommon_showplugins(PDBGC pDbgc)
+{
+    RTTestISub("common - showplugins");
+}
+
+
+static void testCommon_showvars(PDBGC pDbgc)
+{
+    RTTestISub("common - showvars");
+}
+
+
+static void testCommon_stop(PDBGC pDbgc)
+{
+    RTTestISub("common - stop");
+}
+
+
+static void testCommon_unloadplugin(PDBGC pDbgc)
+{
+    RTTestISub("common - unloadplugin");
+}
+
+
+static void testCommon_unset(PDBGC pDbgc)
+{
+    RTTestISub("common - unset");
+}
+
+
+static void testCommon_writecore(PDBGC pDbgc)
+{
+    RTTestISub("common - writecore");
+}
+
+
+
+/*
+ * Basic tests.
+ */
+
+static void testBasicsOddCases(PDBGC pDbgc)
+{
+    RTTestISub("Odd cases");
+    tstTry(pDbgc, "r @rax\n", VINF_SUCCESS);
+    tstTry(pDbgc, "r @eax\n", VINF_SUCCESS);
+    tstTry(pDbgc, "r @ah\n", VINF_SUCCESS);
+    tstTry(pDbgc, "r @notavalidregister\n", VERR_DBGF_REGISTER_NOT_FOUND);
+}
+
+
+static void testBasicsOperators(PDBGC pDbgc)
+{
+    RTTestISub("Operators");
+    tstNumOp(pDbgc, "1",                                        1);
+    tstNumOp(pDbgc, "1",                                        1);
+    tstNumOp(pDbgc, "1",                                        1);
+
+    tstNumOp(pDbgc, "+1",                                       1);
+    tstNumOp(pDbgc, "++++++1",                                  1);
+
+    tstNumOp(pDbgc, "-1",                                       UINT64_MAX);
+    tstNumOp(pDbgc, "--1",                                      1);
+    tstNumOp(pDbgc, "---1",                                     UINT64_MAX);
+    tstNumOp(pDbgc, "----1",                                    1);
+
+    tstNumOp(pDbgc, "~0",                                       UINT64_MAX);
+    tstNumOp(pDbgc, "~1",                                       UINT64_MAX-1);
+    tstNumOp(pDbgc, "~~0",                                      0);
+    tstNumOp(pDbgc, "~~1",                                      1);
+
+    tstNumOp(pDbgc, "!1",                                       0);
+    tstNumOp(pDbgc, "!0",                                       1);
+    tstNumOp(pDbgc, "!42",                                      0);
+    tstNumOp(pDbgc, "!!42",                                     1);
+    tstNumOp(pDbgc, "!!!42",                                    0);
+    tstNumOp(pDbgc, "!!!!42",                                   1);
+
+    tstNumOp(pDbgc, "1 +1",                                     2);
+    tstNumOp(pDbgc, "1 + 1",                                    2);
+    tstNumOp(pDbgc, "1+1",                                      2);
+    tstNumOp(pDbgc, "1+ 1",                                     2);
+
+    tstNumOp(pDbgc, "1 - 1",                                    0);
+    tstNumOp(pDbgc, "99 - 90",                                  9);
+
+    tstNumOp(pDbgc, "2 * 2",                                    4);
+
+    tstNumOp(pDbgc, "2 / 2",                                    1);
+    tstNumOp(pDbgc, "2 / 0",                                    UINT64_MAX);
+    tstNumOp(pDbgc, "0i1024 / 0i4",                             256);
+
+    tstNumOp(pDbgc, "8 mod 7",                                  1);
+
+    tstNumOp(pDbgc, "1<<1",                                     2);
+    tstNumOp(pDbgc, "1<<0i32",                                  UINT64_C(0x0000000100000000));
+    tstNumOp(pDbgc, "1<<0i48",                                  UINT64_C(0x0001000000000000));
+    tstNumOp(pDbgc, "1<<0i63",                                  UINT64_C(0x8000000000000000));
+
+    tstNumOp(pDbgc, "fedcba0987654321>>0i04",                   UINT64_C(0x0fedcba098765432));
+    tstNumOp(pDbgc, "fedcba0987654321>>0i32",                   UINT64_C(0xfedcba09));
+    tstNumOp(pDbgc, "fedcba0987654321>>0i48",                   UINT64_C(0x0000fedc));
+
+    tstNumOp(pDbgc, "0ef & 4",                                  4);
+    tstNumOp(pDbgc, "01234567891 & fff",                        UINT64_C(0x00000000891));
+    tstNumOp(pDbgc, "01234567891 & ~fff",                       UINT64_C(0x01234567000));
+
+    tstNumOp(pDbgc, "1 | 1",                                    1);
+    tstNumOp(pDbgc, "0 | 4",                                    4);
+    tstNumOp(pDbgc, "4 | 0",                                    4);
+    tstNumOp(pDbgc, "4 | 4",                                    4);
+    tstNumOp(pDbgc, "1 | 4 | 2",                                7);
+
+    tstNumOp(pDbgc, "1 ^ 1",                                    0);
+    tstNumOp(pDbgc, "1 ^ 0",                                    1);
+    tstNumOp(pDbgc, "0 ^ 1",                                    1);
+    tstNumOp(pDbgc, "3 ^ 1",                                    2);
+    tstNumOp(pDbgc, "7 ^ 3",                                    4);
+
+    tstNumOp(pDbgc, "7 || 3",                                   1);
+    tstNumOp(pDbgc, "1 || 0",                                   1);
+    tstNumOp(pDbgc, "0 || 1",                                   1);
+    tstNumOp(pDbgc, "0 || 0",                                   0);
+
+    tstNumOp(pDbgc, "0 && 0",                                   0);
+    tstNumOp(pDbgc, "1 && 0",                                   0);
+    tstNumOp(pDbgc, "0 && 1",                                   0);
+    tstNumOp(pDbgc, "1 && 1",                                   1);
+    tstNumOp(pDbgc, "4 && 1",                                   1);
+}
+
+
+static void testBasicsFundametalParsing(PDBGC pDbgc)
+{
+    RTTestISub("Fundamental parsing");
+    tstTry(pDbgc, "stop\n", VINF_SUCCESS);
+    tstTry(pDbgc, "format 1\n", VINF_SUCCESS);
+    tstTry(pDbgc, "format \n", VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS);
+    tstTry(pDbgc, "format 0 1 23 4\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
+    tstTry(pDbgc, "sa 3 23 4 'q' \"21123123\" 'b' \n", VINF_SUCCESS);
 }
 
@@ -477,110 +1154,108 @@
         if (RT_SUCCESS(rc))
         {
-            RTTestSub(g_hTest, "basic parsing");
-            tstTry(pDbgc, "stop\n", VINF_SUCCESS);
-            tstTry(pDbgc, "format 1\n", VINF_SUCCESS);
-            tstTry(pDbgc, "format \n", VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS);
-            tstTry(pDbgc, "format 0 1 23 4\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
-            tstTry(pDbgc, "sa 3 23 4 'q' \"21123123\" 'b' \n", VINF_SUCCESS);
-
+            /*
+             * Perform basic tests first.
+             */
+            testBasicsFundametalParsing(pDbgc);
             if (RTTestErrorCount(g_hTest) == 0)
-            {
-                RTTestSub(g_hTest, "Operators");
-                tstNumOp(pDbgc, "1",                                        1);
-                tstNumOp(pDbgc, "1",                                        1);
-                tstNumOp(pDbgc, "1",                                        1);
-
-                tstNumOp(pDbgc, "+1",                                       1);
-                tstNumOp(pDbgc, "++++++1",                                  1);
-
-                tstNumOp(pDbgc, "-1",                                       UINT64_MAX);
-                tstNumOp(pDbgc, "--1",                                      1);
-                tstNumOp(pDbgc, "---1",                                     UINT64_MAX);
-                tstNumOp(pDbgc, "----1",                                    1);
-
-                tstNumOp(pDbgc, "~0",                                       UINT64_MAX);
-                tstNumOp(pDbgc, "~1",                                       UINT64_MAX-1);
-                tstNumOp(pDbgc, "~~0",                                      0);
-                tstNumOp(pDbgc, "~~1",                                      1);
-
-                tstNumOp(pDbgc, "!1",                                       0);
-                tstNumOp(pDbgc, "!0",                                       1);
-                tstNumOp(pDbgc, "!42",                                      0);
-                tstNumOp(pDbgc, "!!42",                                     1);
-                tstNumOp(pDbgc, "!!!42",                                    0);
-                tstNumOp(pDbgc, "!!!!42",                                   1);
-
-                tstNumOp(pDbgc, "1 +1",                                     2);
-                tstNumOp(pDbgc, "1 + 1",                                    2);
-                tstNumOp(pDbgc, "1+1",                                      2);
-                tstNumOp(pDbgc, "1+ 1",                                     2);
-
-                tstNumOp(pDbgc, "1 - 1",                                    0);
-                tstNumOp(pDbgc, "99 - 90",                                  9);
-
-                tstNumOp(pDbgc, "2 * 2",                                    4);
-
-                tstNumOp(pDbgc, "2 / 2",                                    1);
-                tstNumOp(pDbgc, "2 / 0",                                    UINT64_MAX);
-                tstNumOp(pDbgc, "0i1024 / 0i4",                             256);
-
-                tstNumOp(pDbgc, "8 mod 7",                                  1);
-
-                tstNumOp(pDbgc, "1<<1",                                     2);
-                tstNumOp(pDbgc, "1<<0i32",                                  UINT64_C(0x0000000100000000));
-                tstNumOp(pDbgc, "1<<0i48",                                  UINT64_C(0x0001000000000000));
-                tstNumOp(pDbgc, "1<<0i63",                                  UINT64_C(0x8000000000000000));
-
-                tstNumOp(pDbgc, "fedcba0987654321>>0i04",                   UINT64_C(0x0fedcba098765432));
-                tstNumOp(pDbgc, "fedcba0987654321>>0i32",                   UINT64_C(0xfedcba09));
-                tstNumOp(pDbgc, "fedcba0987654321>>0i48",                   UINT64_C(0x0000fedc));
-
-                tstNumOp(pDbgc, "0ef & 4",                                  4);
-                tstNumOp(pDbgc, "01234567891 & fff",                        UINT64_C(0x00000000891));
-                tstNumOp(pDbgc, "01234567891 & ~fff",                       UINT64_C(0x01234567000));
-
-                tstNumOp(pDbgc, "1 | 1",                                    1);
-                tstNumOp(pDbgc, "0 | 4",                                    4);
-                tstNumOp(pDbgc, "4 | 0",                                    4);
-                tstNumOp(pDbgc, "4 | 4",                                    4);
-                tstNumOp(pDbgc, "1 | 4 | 2",                                7);
-
-                tstNumOp(pDbgc, "1 ^ 1",                                    0);
-                tstNumOp(pDbgc, "1 ^ 0",                                    1);
-                tstNumOp(pDbgc, "0 ^ 1",                                    1);
-                tstNumOp(pDbgc, "3 ^ 1",                                    2);
-                tstNumOp(pDbgc, "7 ^ 3",                                    4);
-
-                tstNumOp(pDbgc, "7 || 3",                                   1);
-                tstNumOp(pDbgc, "1 || 0",                                   1);
-                tstNumOp(pDbgc, "0 || 1",                                   1);
-                tstNumOp(pDbgc, "0 || 0",                                   0);
-
-                tstNumOp(pDbgc, "0 && 0",                                   0);
-                tstNumOp(pDbgc, "1 && 0",                                   0);
-                tstNumOp(pDbgc, "0 && 1",                                   0);
-                tstNumOp(pDbgc, "1 && 1",                                   1);
-                tstNumOp(pDbgc, "4 && 1",                                   1);
-            }
-
+                testBasicsOperators(pDbgc);
             if (RTTestErrorCount(g_hTest) == 0)
-            {
-                RTTestSub(g_hTest, "Odd cases");
-                tstTry(pDbgc, "r @rax\n", VINF_SUCCESS);
-                tstTry(pDbgc, "r @eax\n", VINF_SUCCESS);
-                tstTry(pDbgc, "r @ah\n", VINF_SUCCESS);
-                tstTry(pDbgc, "r @notavalidregister\n", VERR_DBGF_REGISTER_NOT_FOUND);
-            }
+                testBasicsOddCases(pDbgc);
 
             /*
-             * Test codeview commands.
+             * Test commands.
              */
-#ifdef DEBUG_bird /* This will fail for a while */
             if (RTTestErrorCount(g_hTest) == 0)
             {
                 testCodeView_ba(pDbgc);
-
+                testCodeView_bc(pDbgc);
+                testCodeView_bd(pDbgc);
+                testCodeView_be(pDbgc);
+                testCodeView_bl(pDbgc);
+                testCodeView_bp(pDbgc);
+                testCodeView_br(pDbgc);
+                testCodeView_d(pDbgc);
+                testCodeView_da(pDbgc);
+                testCodeView_db(pDbgc);
+                testCodeView_dd(pDbgc);
+                testCodeView_dg(pDbgc);
+                testCodeView_dga(pDbgc);
+                testCodeView_di(pDbgc);
+                testCodeView_dia(pDbgc);
+                testCodeView_dl(pDbgc);
+                testCodeView_dla(pDbgc);
+                testCodeView_dpd(pDbgc);
+                testCodeView_dpda(pDbgc);
+                testCodeView_dpdb(pDbgc);
+                testCodeView_dpdg(pDbgc);
+                testCodeView_dpdh(pDbgc);
+                testCodeView_dph(pDbgc);
+                testCodeView_dphg(pDbgc);
+                testCodeView_dphh(pDbgc);
+                testCodeView_dq(pDbgc);
+                testCodeView_dt(pDbgc);
+                testCodeView_dt16(pDbgc);
+                testCodeView_dt32(pDbgc);
+                testCodeView_dt64(pDbgc);
+                testCodeView_dw(pDbgc);
+                testCodeView_eb(pDbgc);
+                testCodeView_ew(pDbgc);
+                testCodeView_ed(pDbgc);
+                testCodeView_eq(pDbgc);
+                testCodeView_g(pDbgc);
+                testCodeView_k(pDbgc);
+                testCodeView_kg(pDbgc);
+                testCodeView_kh(pDbgc);
+                testCodeView_lm(pDbgc);
+                testCodeView_lmo(pDbgc);
+                testCodeView_ln(pDbgc);
+                testCodeView_ls(pDbgc);
+                testCodeView_m(pDbgc);
+                testCodeView_r(pDbgc);
+                testCodeView_rg(pDbgc);
+                testCodeView_rg32(pDbgc);
+                testCodeView_rg64(pDbgc);
+                testCodeView_rh(pDbgc);
+                testCodeView_rt(pDbgc);
+                testCodeView_s(pDbgc);
+                testCodeView_sa(pDbgc);
+                testCodeView_sb(pDbgc);
+                testCodeView_sd(pDbgc);
+                testCodeView_sq(pDbgc);
+                testCodeView_su(pDbgc);
+                testCodeView_sw(pDbgc);
+                testCodeView_t(pDbgc);
+                testCodeView_y(pDbgc);
+                testCodeView_u64(pDbgc);
+                testCodeView_u32(pDbgc);
+                testCodeView_u16(pDbgc);
+                testCodeView_uv86(pDbgc);
+
+                testCommon_bye_exit_quit(pDbgc);
+                testCommon_cpu(pDbgc);
+                testCommon_echo(pDbgc);
+                testCommon_format(pDbgc);
+                testCommon_detect(pDbgc);
+                testCommon_harakiri(pDbgc);
+                testCommon_help(pDbgc);
+                testCommon_info(pDbgc);
+                testCommon_loadimage(pDbgc);
+                testCommon_loadmap(pDbgc);
+                testCommon_loadplugin(pDbgc);
+                testCommon_loadseg(pDbgc);
+                testCommon_loadsyms(pDbgc);
+                testCommon_loadvars(pDbgc);
+                testCommon_log(pDbgc);
+                testCommon_logdest(pDbgc);
+                testCommon_logflags(pDbgc);
+                testCommon_runscript(pDbgc);
+                testCommon_set(pDbgc);
+                testCommon_showplugins(pDbgc);
+                testCommon_showvars(pDbgc);
+                testCommon_stop(pDbgc);
+                testCommon_unloadplugin(pDbgc);
+                testCommon_unset(pDbgc);
+                testCommon_writecore(pDbgc);
             }
-#endif
         }
 
