VirtualBox

Changeset 41558 in vbox for trunk


Ignore:
Timestamp:
Jun 3, 2012 10:46:46 PM (13 years ago)
Author:
vboxsync
Message:

DBGC: Hacking the command parsing code.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/dbg.h

    r39154 r41558  
    388388     * @param   pCmdHlp     Pointer to the command callback structure.
    389389     * @param   pcb         Where to store the number of bytes written.
    390      * @param   pszFormat   The format string.
    391      *                      This is using the log formatter, so it's format extensions can be used.
     390     * @param   pszFormat   The format string.  This may use all IPRT extensions as
     391     *                      well as the debugger ones.
    392392     * @param   ...         Arguments specified in the format string.
    393393     */
     
    400400     * @param   pCmdHlp     Pointer to the command callback structure.
    401401     * @param   pcb         Where to store the number of bytes written.
    402      * @param   pszFormat   The format string.
    403      *                      This is using the log formatter, so it's format extensions can be used.
     402     * @param   pszFormat   The format string.  This may use all IPRT extensions as
     403     *                      well as the debugger ones.
    404404     * @param   args        Arguments specified in the format string.
    405405     */
    406406    DECLCALLBACKMEMBER(int, pfnPrintfV)(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten, const char *pszFormat, va_list args);
     407
     408    /**
     409     * Command helper for formatting a string with debugger format specifiers.
     410     *
     411     * @returns The number of bytes written.
     412     * @param   pCmdHlp     Pointer to the command callback structure.
     413     * @param   pszBuf      The output buffer.
     414     * @param   cbBuf       The size of the output buffer.
     415     * @param   pszFormat   The format string.  This may use all IPRT extensions as
     416     *                      well as the debugger ones.
     417     * @param   ...         Arguments specified in the format string.
     418     */
     419    DECLCALLBACKMEMBER(size_t, pfnStrPrintf)(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf, const char *pszFormat, ...);
     420
     421    /**
     422     * Command helper for formatting a string with debugger format specifiers.
     423     *
     424     * @returns The number of bytes written.
     425     * @param   pCmdHlp     Pointer to the command callback structure.
     426     * @param   pszBuf      The output buffer.
     427     * @param   cbBuf       The size of the output buffer.
     428     * @param   pszFormat   The format string.  This may use all IPRT extensions as
     429     *                      well as the debugger ones.
     430     * @param   va          Arguments specified in the format string.
     431     */
     432    DECLCALLBACKMEMBER(size_t, pfnStrPrintfV)(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf,
     433                                              const char *pszFormat, va_list va);
    407434
    408435    /**
     
    613640
    614641/**
    615  * Command helper for writing formatted text to the debug console.
    616  *
    617  * @returns VBox status.
    618  * @param   pCmdHlp     Pointer to the command callback structure.
    619  * @param   pszFormat   The format string.
    620  *                      This is using the log formatter, so it's format extensions can be used.
    621  * @param   ...         Arguments specified in the format string.
     642 * @copydoc DBGCCMDHLP::pfnPrintf
    622643 */
    623644DECLINLINE(int) DBGCCmdHlpPrintf(PDBGCCMDHLP pCmdHlp, const char *pszFormat, ...)
     
    631652
    632653    return rc;
     654}
     655
     656
     657/**
     658 * @copydoc DBGCCMDHLP::pfnStrPrintf
     659 */
     660DECLINLINE(size_t) DBGCCmdHlpStrPrintf(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf, const char *pszFormat, ...)
     661{
     662    va_list va;
     663    size_t  cch;
     664
     665    va_start(va, pszFormat);
     666    cch = pCmdHlp->pfnStrPrintfV(pCmdHlp, pszBuf, cbBuf, pszFormat, va);
     667    va_end(va);
     668
     669    return cch;
    633670}
    634671
  • trunk/include/VBox/err.h

    r41553 r41558  
    21222122/** Syntax error - too many arguments for static storage. */
    21232123#define VERR_DBGC_PARSE_ARGUMENT_OVERFLOW           (VERR_DBGC_PARSE_LOWEST + 2)
    2124 /** Syntax error - argument didn't match description. */
    2125 #define VERR_DBGC_PARSE_NO_ARGUMENT_MATCH           (VERR_DBGC_PARSE_LOWEST + 3)
     2124
    21262125/** Syntax error - the argument does not allow a range to be specified. */
    21272126#define VERR_DBGC_PARSE_NO_RANGE_ALLOWED            (VERR_DBGC_PARSE_LOWEST + 5)
     
    21442143/** Syntax error - the specified function is not a function. */
    21452144#define VERR_DBGC_PARSE_NOT_A_FUNCTION              (VERR_DBGC_PARSE_LOWEST + 14)
     2145/** Syntax error - out of scratch memory. */
     2146#define VERR_DBGC_PARSE_NO_SCRATCH                  (VERR_DBGC_PARSE_LOWEST + 15)
    21462147/** Syntax error - out of regular heap memory. */
    2147 #define VERR_DBGC_PARSE_NO_MEMORY                   (VERR_DBGC_PARSE_LOWEST + 15)
     2148#define VERR_DBGC_PARSE_NO_MEMORY                   (VERR_DBGC_PARSE_LOWEST + 16)
    21482149/** Syntax error - incorrect argument type. */
    2149 #define VERR_DBGC_PARSE_INCORRECT_ARG_TYPE          (VERR_DBGC_PARSE_LOWEST + 16)
     2150#define VERR_DBGC_PARSE_INCORRECT_ARG_TYPE          (VERR_DBGC_PARSE_LOWEST + 17)
    21502151/** Syntax error - an undefined variable was referenced. */
    2151 #define VERR_DBGC_PARSE_VARIABLE_NOT_FOUND          (VERR_DBGC_PARSE_LOWEST + 17)
     2152#define VERR_DBGC_PARSE_VARIABLE_NOT_FOUND          (VERR_DBGC_PARSE_LOWEST + 18)
    21522153/** Syntax error - a type conversion failed. */
    2153 #define VERR_DBGC_PARSE_CONVERSION_FAILED           (VERR_DBGC_PARSE_LOWEST + 18)
     2154#define VERR_DBGC_PARSE_CONVERSION_FAILED           (VERR_DBGC_PARSE_LOWEST + 19)
    21542155/** Syntax error - you hit a debugger feature which isn't implemented yet.
    21552156 * (Feel free to help implement it.) */
    2156 #define VERR_DBGC_PARSE_NOT_IMPLEMENTED             (VERR_DBGC_PARSE_LOWEST + 19)
     2157#define VERR_DBGC_PARSE_NOT_IMPLEMENTED             (VERR_DBGC_PARSE_LOWEST + 20)
    21572158/** Syntax error - Couldn't staisfy a request for a sepcific result type. */
    2158 #define VERR_DBGC_PARSE_BAD_RESULT_TYPE             (VERR_DBGC_PARSE_LOWEST + 20)
     2159#define VERR_DBGC_PARSE_BAD_RESULT_TYPE             (VERR_DBGC_PARSE_LOWEST + 21)
    21592160/** Syntax error - Cannot read symbol value, it is a set-only symbol. */
    2160 #define VERR_DBGC_PARSE_WRITEONLY_SYMBOL            (VERR_DBGC_PARSE_LOWEST + 21)
     2161#define VERR_DBGC_PARSE_WRITEONLY_SYMBOL            (VERR_DBGC_PARSE_LOWEST + 22)
    21612162/** Syntax error - Invalid command name. */
    2162 #define VERR_DBGC_PARSE_INVALD_COMMAND_NAME         (VERR_DBGC_PARSE_LOWEST + 22)
     2163#define VERR_DBGC_PARSE_INVALD_COMMAND_NAME         (VERR_DBGC_PARSE_LOWEST + 23)
    21632164/** Syntax error - Command not found. */
    2164 #define VERR_DBGC_PARSE_COMMAND_NOT_FOUND           (VERR_DBGC_PARSE_LOWEST + 23)
    2165 
    2166 /** Syntax error - Obsolete. */
    2167 #define VERR_DBGC_PARSE_ARGUMENT_TYPE_MISMATCH      (VERR_DBGC_PARSE_LOWEST + 4)
     2165#define VERR_DBGC_PARSE_COMMAND_NOT_FOUND           (VERR_DBGC_PARSE_LOWEST + 24)
    21682166
    21692167
  • trunk/src/VBox/Debugger/DBGCCmdHlp.cpp

    r41553 r41558  
    5151    return rc;
    5252}
     53
    5354
    5455/**
     
    211212
    212213    return pDbgc->rcOutput;
     214}
     215
     216
     217/**
     218 * @interface_method_impl{DBGCCMDHLP,pfnStrPrintf}
     219 */
     220static DECLCALLBACK(size_t) dbgcHlpStrPrintfV(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf,
     221                                              const char *pszFormat, va_list va)
     222{
     223    PDBGC   pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
     224    return RTStrPrintfExV(dbgcStringFormatter, pDbgc, pszBuf, cbBuf, pszFormat, va);
     225}
     226
     227
     228/**
     229 * @interface_method_impl{DBGCCMDHLP,pfnStrPrintf}
     230 */
     231static DECLCALLBACK(size_t) dbgcHlpStrPrintf(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf, const char *pszFormat, ...)
     232{
     233    PDBGC   pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
     234    va_list va;
     235    va_start(va, pszFormat);
     236    size_t cch = RTStrPrintfExV(dbgcStringFormatter, pDbgc, pszBuf, cbBuf, pszFormat, va);
     237    va_end(va);
     238    return cch;
    213239}
    214240
     
    12551281    pDbgc->CmdHlp.pfnPrintfV            = dbgcHlpPrintfV;
    12561282    pDbgc->CmdHlp.pfnPrintf             = dbgcHlpPrintf;
     1283    pDbgc->CmdHlp.pfnStrPrintf          = dbgcHlpStrPrintf;
     1284    pDbgc->CmdHlp.pfnStrPrintfV         = dbgcHlpStrPrintfV;
    12571285    pDbgc->CmdHlp.pfnVBoxErrorV         = dbgcHlpVBoxErrorV;
    12581286    pDbgc->CmdHlp.pfnVBoxError          = dbgcHlpVBoxError;
  • trunk/src/VBox/Debugger/DBGCEval.cpp

    r41553 r41558  
    55
    66/*
    7  * Copyright (C) 2006-2011 Oracle Corporation
     7 * Copyright (C) 2006-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3131
    3232#include "DBGCInternal.h"
     33
     34/** Rewrite in progress.  */
     35#define BETTER_ARGUMENT_MATCHING
    3336
    3437
     
    6467
    6568
     69
    6670static int dbgcEvalSubString(PDBGC pDbgc, char *pszExpr, size_t cchExpr, PDBGCVAR pArg)
    6771{
     
    7276     */
    7377    char ch = *pszExpr;
    74     if (ch == '"' || ch == '\'' || ch == '`')
     78    if (ch == '"' || ch == '\'')
    7579    {
    7680        if (pszExpr[--cchExpr] != ch)
     
    142146
    143147/**
    144  * Match variable and variable descriptor, promoting the variable if necessary.
    145  *
    146  * @returns VBox status code.
    147  * @param   pDbgc       Debug console instanace.
    148  * @param   pVar        Variable.
    149  * @param   pVarDesc    Variable descriptor.
     148 * dbgcEvalSubUnary worker that handles simple numeric or pointer expressions.
     149 *
     150 * @returns VBox status code. pResult contains the result on success.
     151 * @param   pDbgc       Debugger console instance data.
     152 * @param   pszExpr     The expression string.
     153 * @param   cchExpr     The length of the expression.
     154 * @param   enmCategory The desired type category (for range / no range).
     155 * @param   pResult     Where to store the result of the expression evaluation.
    150156 */
    151 static int dbgcEvalSubMatchVar(PDBGC pDbgc, PDBGCVAR pVar, PCDBGCVARDESC pVarDesc)
     157static int dbgcEvalSubNumericOrPointer(PDBGC pDbgc, char *pszExpr, size_t cchExpr, DBGCVARCAT enmCategory,
     158                                       PDBGCVAR pResult)
    152159{
    153     /*
    154      * (If match or promoted to match, return, else break.)
    155      */
    156     switch (pVarDesc->enmCategory)
    157     {
    158         /*
    159          * Anything goes
    160          */
    161         case DBGCVAR_CAT_ANY:
    162             return VINF_SUCCESS;
    163 
    164         /*
    165          * Pointer with and without range.
    166          * We can try resolve strings and symbols as symbols and promote
    167          * numbers to flat GC pointers.
    168          */
    169         case DBGCVAR_CAT_POINTER_NO_RANGE:
    170         case DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE:
    171             if (pVar->enmRangeType != DBGCVAR_RANGE_NONE)
    172                 return VERR_DBGC_PARSE_NO_RANGE_ALLOWED;
    173             /* fallthru */
    174         case DBGCVAR_CAT_POINTER:
    175         case DBGCVAR_CAT_POINTER_NUMBER:
    176             switch (pVar->enmType)
    177             {
    178                 case DBGCVAR_TYPE_GC_FLAT:
    179                 case DBGCVAR_TYPE_GC_FAR:
    180                 case DBGCVAR_TYPE_GC_PHYS:
    181                 case DBGCVAR_TYPE_HC_FLAT:
    182                 case DBGCVAR_TYPE_HC_PHYS:
    183                     return VINF_SUCCESS;
    184 
    185                 case DBGCVAR_TYPE_SYMBOL:
    186                 case DBGCVAR_TYPE_STRING:
    187                 {
    188                     DBGCVAR Var;
    189                     int rc = dbgcSymbolGet(pDbgc, pVar->u.pszString, DBGCVAR_TYPE_GC_FLAT, &Var);
    190                     if (RT_SUCCESS(rc))
    191                     {
    192                         /* deal with range */
    193                         if (pVar->enmRangeType != DBGCVAR_RANGE_NONE)
    194                         {
    195                             Var.enmRangeType = pVar->enmRangeType;
    196                             Var.u64Range = pVar->u64Range;
    197                         }
    198                         else if (pVarDesc->enmCategory == DBGCVAR_CAT_POINTER_NO_RANGE)
    199                             Var.enmRangeType = DBGCVAR_RANGE_NONE;
    200                         *pVar = Var;
    201                         return rc;
    202                     }
    203                     break;
    204                 }
    205 
    206                 case DBGCVAR_TYPE_NUMBER:
    207                     if (   pVarDesc->enmCategory != DBGCVAR_CAT_POINTER_NUMBER
    208                         && pVarDesc->enmCategory != DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE)
    209                     {
    210                         RTGCPTR GCPtr = (RTGCPTR)pVar->u.u64Number;
    211                         pVar->enmType = DBGCVAR_TYPE_GC_FLAT;
    212                         pVar->u.GCFlat = GCPtr;
    213                     }
    214                     return VINF_SUCCESS;
    215 
    216                 default:
    217                     break;
    218             }
    219             break;
    220 
    221         /*
    222          * GC pointer with and without range.
    223          * We can try resolve strings and symbols as symbols and
    224          * promote numbers to flat GC pointers.
    225          */
    226         case DBGCVAR_CAT_GC_POINTER_NO_RANGE:
    227             if (pVar->enmRangeType != DBGCVAR_RANGE_NONE)
    228                 return VERR_DBGC_PARSE_NO_RANGE_ALLOWED;
    229             /* fallthru */
    230         case DBGCVAR_CAT_GC_POINTER:
    231             switch (pVar->enmType)
    232             {
    233                 case DBGCVAR_TYPE_GC_FLAT:
    234                 case DBGCVAR_TYPE_GC_FAR:
    235                 case DBGCVAR_TYPE_GC_PHYS:
    236                     return VINF_SUCCESS;
    237 
    238                 case DBGCVAR_TYPE_HC_FLAT:
    239                 case DBGCVAR_TYPE_HC_PHYS:
    240                     return VERR_DBGC_PARSE_CONVERSION_FAILED;
    241 
    242                 case DBGCVAR_TYPE_SYMBOL:
    243                 case DBGCVAR_TYPE_STRING:
    244                 {
    245                     DBGCVAR Var;
    246                     int rc = dbgcSymbolGet(pDbgc, pVar->u.pszString, DBGCVAR_TYPE_GC_FLAT, &Var);
    247                     if (RT_SUCCESS(rc))
    248                     {
    249                         /* deal with range */
    250                         if (pVar->enmRangeType != DBGCVAR_RANGE_NONE)
    251                         {
    252                             Var.enmRangeType = pVar->enmRangeType;
    253                             Var.u64Range = pVar->u64Range;
    254                         }
    255                         else if (pVarDesc->enmCategory == DBGCVAR_CAT_POINTER_NO_RANGE)
    256                             Var.enmRangeType = DBGCVAR_RANGE_NONE;
    257                         *pVar = Var;
    258                         return rc;
    259                     }
    260                     break;
    261                 }
    262 
    263                 case DBGCVAR_TYPE_NUMBER:
    264                 {
    265                     RTGCPTR GCPtr = (RTGCPTR)pVar->u.u64Number;
    266                     pVar->enmType = DBGCVAR_TYPE_GC_FLAT;
    267                     pVar->u.GCFlat = GCPtr;
    268                     return VINF_SUCCESS;
    269                 }
    270 
    271                 default:
    272                     break;
    273             }
    274             break;
    275 
    276         /*
    277          * Number with or without a range.
    278          * Numbers can be resolved from symbols, but we cannot demote a pointer
    279          * to a number.
    280          */
    281         case DBGCVAR_CAT_NUMBER_NO_RANGE:
    282             if (pVar->enmRangeType != DBGCVAR_RANGE_NONE)
    283                 return VERR_DBGC_PARSE_NO_RANGE_ALLOWED;
    284             /* fallthru */
    285         case DBGCVAR_CAT_NUMBER:
    286             switch (pVar->enmType)
    287             {
    288                 case DBGCVAR_TYPE_NUMBER:
    289                     return VINF_SUCCESS;
    290 
    291                 case DBGCVAR_TYPE_SYMBOL:
    292                 case DBGCVAR_TYPE_STRING:
    293                 {
    294                     DBGCVAR Var;
    295                     int rc = dbgcSymbolGet(pDbgc, pVar->u.pszString, DBGCVAR_TYPE_NUMBER, &Var);
    296                     if (RT_SUCCESS(rc))
    297                     {
    298                         *pVar = Var;
    299                         return rc;
    300                     }
    301                     break;
    302                 }
    303                 default:
    304                     break;
    305             }
    306             break;
    307 
    308         /*
    309          * Strings can easily be made from symbols (and of course strings).
    310          * We could consider reformatting the addresses and numbers into strings later...
    311          */
    312         case DBGCVAR_CAT_STRING:
    313             switch (pVar->enmType)
    314             {
    315                 case DBGCVAR_TYPE_SYMBOL:
    316                     pVar->enmType = DBGCVAR_TYPE_STRING;
    317                     /* fallthru */
    318                 case DBGCVAR_TYPE_STRING:
    319                     return VINF_SUCCESS;
    320                 default:
    321                     break;
    322             }
    323             break;
    324 
    325         /*
    326          * Symol is pretty much the same thing as a string (at least until we actually implement it).
    327          */
    328         case DBGCVAR_CAT_SYMBOL:
    329             switch (pVar->enmType)
    330             {
    331                 case DBGCVAR_TYPE_STRING:
    332                     pVar->enmType = DBGCVAR_TYPE_SYMBOL;
    333                     /* fallthru */
    334                 case DBGCVAR_TYPE_SYMBOL:
    335                     return VINF_SUCCESS;
    336                 default:
    337                     break;
    338             }
    339             break;
    340 
    341         /*
    342          * Anything else is illegal.
    343          */
     160    char const  ch  = pszExpr[0];
     161    char const  ch2 = pszExpr[1];
     162
     163    /* 0x<hex digits> */
     164    if (ch == '0' && (ch2 == 'x' || ch2 == 'X'))
     165        return dbgcEvalSubNum(pszExpr + 2, 16, pResult);
     166
     167    /* <hex digits>h */
     168    if (RT_C_IS_XDIGIT(*pszExpr) && (pszExpr[cchExpr - 1] == 'h' || pszExpr[cchExpr - 1] == 'H'))
     169    {
     170        pszExpr[cchExpr] = '\0';
     171        return dbgcEvalSubNum(pszExpr, 16, pResult);
     172    }
     173
     174    /* 0i<decimal digits> */
     175    if (ch == '0' && ch2 == 'i')
     176        return dbgcEvalSubNum(pszExpr + 2, 10, pResult);
     177
     178    /* 0t<octal digits> */
     179    if (ch == '0' && ch2 == 't')
     180        return dbgcEvalSubNum(pszExpr + 2, 8, pResult);
     181
     182    /* 0y<binary digits> */
     183    if (ch == '0' && ch2 == 'y')
     184        return dbgcEvalSubNum(pszExpr + 2, 10, pResult);
     185
     186    /* Hex number? */
     187    unsigned off = 0;
     188    while (RT_C_IS_XDIGIT(pszExpr[off]) || pszExpr[off] == '`')
     189        off++;
     190    if (off == cchExpr)
     191        return dbgcEvalSubNum(pszExpr, 16, pResult);
     192
     193    /*
     194     * Some kind of symbol?
     195     */
     196    DBGCVARTYPE enmType;
     197    bool        fStripRange = false;
     198    switch (enmCategory)
     199    {
     200        case DBGCVAR_CAT_POINTER_NUMBER:            enmType = DBGCVAR_TYPE_NUMBER; break;
     201        case DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE:   enmType = DBGCVAR_TYPE_NUMBER; fStripRange = true; break;
     202        case DBGCVAR_CAT_POINTER:                   enmType = DBGCVAR_TYPE_NUMBER; break;
     203        case DBGCVAR_CAT_POINTER_NO_RANGE:          enmType = DBGCVAR_TYPE_NUMBER; fStripRange = true; break;
     204        case DBGCVAR_CAT_GC_POINTER:                enmType = DBGCVAR_TYPE_GC_FLAT; break;
     205        case DBGCVAR_CAT_GC_POINTER_NO_RANGE:       enmType = DBGCVAR_TYPE_GC_FLAT; fStripRange = true; break;
     206        case DBGCVAR_CAT_NUMBER:                    enmType = DBGCVAR_TYPE_NUMBER; break;
     207        case DBGCVAR_CAT_NUMBER_NO_RANGE:           enmType = DBGCVAR_TYPE_NUMBER; fStripRange = true; break;
    344208        default:
    345             AssertMsgFailed(("enmCategory=%d\n", pVar->enmType));
    346             break;
    347     }
    348 
    349     return VERR_DBGC_PARSE_NO_ARGUMENT_MATCH;
     209            AssertFailedReturn(VERR_DBGC_PARSE_NOT_IMPLEMENTED);
     210    }
     211
     212    if (   (*pszExpr == '"' || *pszExpr == '\'')
     213        && pszExpr[cchExpr - 1] == *pszExpr)
     214    {
     215        pszExpr[cchExpr - 1] = '\0';
     216        pszExpr++;
     217    }
     218
     219    int rc = dbgcSymbolGet(pDbgc, pszExpr, enmType, pResult);
     220    if (RT_SUCCESS(rc))
     221    {
     222        if (fStripRange)
     223        {
     224            pResult->enmRangeType = DBGCVAR_RANGE_NONE;
     225            pResult->u64Range     = 0;
     226        }
     227    }
     228    else if (rc == VERR_DBGC_PARSE_NOT_IMPLEMENTED)
     229        rc = VERR_DBGC_PARSE_INVALID_NUMBER;
     230    return rc;
    350231}
    351232
    352233
    353234/**
    354  * Matches a set of variables with a description set.
    355  *
    356  * This is typically used for routine arguments before a call. The effects in
    357  * addition to the validation, is that some variables might be propagated to
    358  * other types in order to match the description. The following transformations
    359  * are supported:
    360  *      - String reinterpreted as a symbol and resolved to a number or pointer.
    361  *      - Number to a pointer.
    362  *      - Pointer to a number.
    363  *
    364  * @returns VBox status code. Modified @a paVars on success.
     235 * dbgcEvalSubUnary worker that handles simple DBGCVAR_CAT_ANY expressions.
     236 *
     237 * @returns VBox status code. pResult contains the result on success.
     238 * @param   pDbgc       Debugger console instance data.
     239 * @param   pszExpr     The expression string.
     240 * @param   cchExpr     The length of the expression.
     241 * @param   pResult     Where to store the result of the expression evaluation.
    365242 */
    366 static int dbgcEvalSubMatchVars(PDBGC pDbgc, unsigned cVarsMin, unsigned cVarsMax,
    367                                 PCDBGCVARDESC paVarDescs, unsigned cVarDescs,
    368                                 PDBGCVAR paVars, unsigned cVars)
     243static int dbgcEvalSubUnaryAny(PDBGC pDbgc, char *pszExpr, size_t cchExpr, PDBGCVAR pResult)
    369244{
    370     /*
    371      * Just do basic min / max checks first.
    372      */
    373     if (cVars < cVarsMin)
    374         return VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS;
    375     if (cVars > cVarsMax)
    376         return VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS;
    377 
    378     /*
    379      * Match the descriptors and actual variables.
    380      */
    381     PCDBGCVARDESC   pPrevDesc = NULL;
    382     unsigned        cCurDesc = 0;
    383     unsigned        iVar = 0;
    384     unsigned        iVarDesc = 0;
    385     while (iVar < cVars)
    386     {
    387         /* walk the descriptors */
    388         if (iVarDesc >= cVarDescs)
    389             return VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS;
    390         if (    (    paVarDescs[iVarDesc].fFlags & DBGCVD_FLAGS_DEP_PREV
    391                 &&  &paVarDescs[iVarDesc - 1] != pPrevDesc)
    392             ||  cCurDesc >= paVarDescs[iVarDesc].cTimesMax)
    393         {
    394             iVarDesc++;
    395             if (iVarDesc >= cVarDescs)
    396                 return VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS;
    397             cCurDesc = 0;
    398         }
    399 
    400         /*
    401          * Skip thru optional arguments until we find something which matches
    402          * or can easily be promoted to what the descriptor want.
    403          */
    404         for (;;)
    405         {
    406             int rc = dbgcEvalSubMatchVar(pDbgc, &paVars[iVar], &paVarDescs[iVarDesc]);
    407             if (RT_SUCCESS(rc))
    408             {
    409                 paVars[iVar].pDesc = &paVarDescs[iVarDesc];
    410                 cCurDesc++;
    411                 break;
    412             }
    413 
    414             /* can we advance? */
    415             if (paVarDescs[iVarDesc].cTimesMin > cCurDesc)
    416                 return VERR_DBGC_PARSE_ARGUMENT_TYPE_MISMATCH;
    417             if (++iVarDesc >= cVarDescs)
    418                 return VERR_DBGC_PARSE_ARGUMENT_TYPE_MISMATCH;
    419             cCurDesc = 0;
    420         }
    421 
    422         /* next var */
    423         iVar++;
    424     }
    425 
    426     /*
    427      * Check that the rest of the descriptors are optional.
    428      */
    429     while (iVarDesc < cVarDescs)
    430     {
    431         if (paVarDescs[iVarDesc].cTimesMin > cCurDesc)
    432             return VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS;
    433         cCurDesc = 0;
    434 
    435         /* next */
    436         iVarDesc++;
    437     }
    438 
    439     return VINF_SUCCESS;
     245    char const  ch  = pszExpr[0];
     246    char const  ch2 = pszExpr[1];
     247    unsigned    off = 2;
     248
     249    /* 0x<hex digits> */
     250    if (ch == '0' && (ch2 == 'x' || ch2 == 'X'))
     251    {
     252        while (RT_C_IS_XDIGIT(pszExpr[off]) || pszExpr[off] == '`')
     253            off++;
     254        if (off == cchExpr)
     255            return dbgcEvalSubNum(pszExpr + 2, 16, pResult);
     256        return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
     257    }
     258
     259    /* <hex digits>h */
     260    if (RT_C_IS_XDIGIT(*pszExpr) && (pszExpr[cchExpr - 1] == 'h' || pszExpr[cchExpr - 1] == 'H'))
     261    {
     262        cchExpr--;
     263        while (off < cchExpr && (RT_C_IS_XDIGIT(pszExpr[off]) || pszExpr[off] == '`'))
     264            off++;
     265        if (off == cchExpr)
     266        {
     267            pszExpr[cchExpr] = '\0';
     268            return dbgcEvalSubNum(pszExpr, 16, pResult);
     269        }
     270        return dbgcEvalSubString(pDbgc, pszExpr, cchExpr + 1, pResult);
     271    }
     272
     273    /* 0i<decimal digits> */
     274    if (ch == '0' && ch2 == 'i')
     275    {
     276        while (RT_C_IS_DIGIT(pszExpr[off]) || pszExpr[off] == '`')
     277            off++;
     278        if (off == cchExpr)
     279            return dbgcEvalSubNum(pszExpr + 2, 10, pResult);
     280        return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
     281    }
     282
     283    /* 0t<octal digits> */
     284    if (ch == '0' && ch2 == 't')
     285    {
     286        while (RT_C_IS_ODIGIT(pszExpr[off]) || pszExpr[off] == '`')
     287            off++;
     288        if (off == cchExpr)
     289            return dbgcEvalSubNum(pszExpr + 2, 8, pResult);
     290        return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
     291    }
     292
     293    /* 0y<binary digits> */
     294    if (ch == '0' && ch2 == 'y')
     295    {
     296        while (pszExpr[off] == '0' || pszExpr[off] == '1' || pszExpr[off] == '`')
     297            off++;
     298        if (off == cchExpr)
     299            return dbgcEvalSubNum(pszExpr + 2, 10, pResult);
     300        return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
     301    }
     302
     303    /* Ok, no prefix of suffix. Is it a hex number after all? If not it must
     304       be a string. */
     305    off = 0;
     306    while (RT_C_IS_XDIGIT(pszExpr[off]) || pszExpr[off] == '`')
     307        off++;
     308    if (off == cchExpr)
     309        return dbgcEvalSubNum(pszExpr, 16, pResult);
     310    return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
    440311}
    441312
     
    481352            pszExpr2++;
    482353
    483         if (!*pszExpr2)
    484             rc = VERR_DBGC_PARSE_EMPTY_ARGUMENT;
    485         else
     354        if (*pszExpr2)
    486355        {
    487356            DBGCVAR Arg;
     
    493362                rc = pOp->pfnHandlerUnary(pDbgc, &Arg, enmCategory, pResult);
    494363        }
    495     }
    496     else
    497     {
    498         /*
    499          * Didn't find any operators, so it we have to check if this can be an
    500          * function call before assuming numeric or string expression.
    501          *
    502          * (ASSUMPTIONS:)
    503          * A function name only contains alphanumerical chars and it can not start
    504          * with a numerical character.
    505          * Immediately following the name is a parenthesis which must over
    506          * the remaining part of the expression.
    507          */
    508         bool    fExternal = *pszExpr == '.';
    509         char   *pszFun    = fExternal ? pszExpr + 1 : pszExpr;
    510         char   *pszFunEnd = NULL;
    511         if (pszExpr[cchExpr - 1] == ')' && RT_C_IS_ALPHA(*pszFun))
    512         {
    513             pszFunEnd = pszExpr + 1;
    514             while (*pszFunEnd != '(' && RT_C_IS_ALNUM(*pszFunEnd))
    515                 pszFunEnd++;
    516             if (*pszFunEnd != '(')
    517                 pszFunEnd = NULL;
    518         }
    519 
    520         if (pszFunEnd)
    521         {
    522             /*
    523              * Ok, it's a function call.
    524              */
    525             if (fExternal)
    526                 pszExpr++, cchExpr--;
    527             PCDBGCCMD pFun = dbgcRoutineLookup(pDbgc, pszExpr, pszFunEnd - pszExpr, fExternal);
    528             if (!pFun)
    529                 return VERR_DBGC_PARSE_FUNCTION_NOT_FOUND;
     364        else
     365            rc = VERR_DBGC_PARSE_EMPTY_ARGUMENT;
     366        return rc;
     367    }
     368
     369    /*
     370     * Could this be a function call?
     371     *
     372     * ASSUMPTIONS:
     373     *    - A function name only contains alphanumerical chars and it can not
     374     *      start with a numerical character.
     375     *    - Immediately following the name is a parenthesis which must cover
     376     *      the remaining part of the expression.
     377     */
     378    bool    fExternal = *pszExpr == '.';
     379    char   *pszFun    = fExternal ? pszExpr + 1 : pszExpr;
     380    char   *pszFunEnd = NULL;
     381    if (pszExpr[cchExpr - 1] == ')' && RT_C_IS_ALPHA(*pszFun))
     382    {
     383        pszFunEnd = pszExpr + 1;
     384        while (*pszFunEnd != '(' && RT_C_IS_ALNUM(*pszFunEnd))
     385            pszFunEnd++;
     386        if (*pszFunEnd != '(')
     387            pszFunEnd = NULL;
     388    }
     389    if (pszFunEnd)
     390    {
     391        /*
     392         * Ok, it's a function call.
     393         */
     394        if (fExternal)
     395            pszExpr++, cchExpr--;
     396        PCDBGCCMD pFun = dbgcRoutineLookup(pDbgc, pszExpr, pszFunEnd - pszExpr, fExternal);
     397        if (!pFun)
     398            return VERR_DBGC_PARSE_FUNCTION_NOT_FOUND;
    530399#if 0
    531             if (!pFun->pResultDesc)
    532                 return VERR_DBGC_PARSE_NOT_A_FUNCTION;
    533 
    534             /*
    535              * Parse the expression in parenthesis.
    536              */
    537             cchExpr -= pszFunEnd - pszExpr;
    538             pszExpr = pszFunEnd;
    539             /** @todo implement multiple arguments. */
    540             DBGCVAR     Arg;
    541             rc = dbgcEvalSub(pDbgc, pszExpr, cchExpr, enmCategory, &Arg);
     400        if (!pFun->pResultDesc)
     401            return VERR_DBGC_PARSE_NOT_A_FUNCTION;
     402
     403        /*
     404         * Parse the expression in parenthesis.
     405         */
     406        cchExpr -= pszFunEnd - pszExpr;
     407        pszExpr = pszFunEnd;
     408        /** @todo implement multiple arguments. */
     409        DBGCVAR     Arg;
     410        rc = dbgcEvalSub(pDbgc, pszExpr, cchExpr, enmCategory, &Arg);
     411        if (!rc)
     412        {
     413            rc = dbgcEvalSubMatchVars(pDbgc, pFun->cArgsMin, pFun->cArgsMax, pFun->paArgDescs, pFun->cArgDescs, &Arg, 1);
    542414            if (!rc)
    543             {
    544                 rc = dbgcEvalSubMatchVars(pDbgc, pFun->cArgsMin, pFun->cArgsMax, pFun->paArgDescs, pFun->cArgDescs, &Arg, 1);
    545                 if (!rc)
    546                     rc = pFun->pfnHandler(pFun, &pDbgc->CmdHlp, pDbgc->pVM, &Arg, 1, pResult);
    547             }
    548             else if (rc == VERR_DBGC_PARSE_EMPTY_ARGUMENT && pFun->cArgsMin == 0)
    549                 rc = pFun->pfnHandler(pFun, &pDbgc->CmdHlp, pDbgc->pVM, NULL, 0, pResult);
     415                rc = pFun->pfnHandler(pFun, &pDbgc->CmdHlp, pDbgc->pVM, &Arg, 1, pResult);
     416        }
     417        else if (rc == VERR_DBGC_PARSE_EMPTY_ARGUMENT && pFun->cArgsMin == 0)
     418            rc = pFun->pfnHandler(pFun, &pDbgc->CmdHlp, pDbgc->pVM, NULL, 0, pResult);
    550419#else
    551             rc = VERR_NOT_IMPLEMENTED;
     420        rc = VERR_NOT_IMPLEMENTED;
    552421#endif
    553         }
    554         else if (   enmCategory == DBGCVAR_CAT_STRING
    555                  || enmCategory == DBGCVAR_CAT_SYMBOL)
    556             rc = dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
    557         else
    558         {
    559             /*
    560              * Didn't find any operators, so it must be a plain expression.
    561              * This might be numeric or a string expression.
    562              */
    563             char ch  = pszExpr[0];
    564             char ch2 = pszExpr[1];
    565             if (ch == '0' && (ch2 == 'x' || ch2 == 'X'))
    566                 rc = dbgcEvalSubNum(pszExpr + 2, 16, pResult);
    567             else if (ch == '0' && (ch2 == 'i' || ch2 == 'i'))
    568                 rc = dbgcEvalSubNum(pszExpr + 2, 10, pResult);
    569             else if (ch == '0' && (ch2 == 't' || ch2 == 'T'))
    570                 rc = dbgcEvalSubNum(pszExpr + 2, 8, pResult);
    571             /// @todo 0b doesn't work as a binary prefix, we confuse it with 0bf8:0123 and stuff.
    572             //else if (ch == '0' && (ch2 == 'b' || ch2 == 'b'))
    573             //    rc = dbgcEvalSubNum(pszExpr + 2, 2, pResult);
    574             else
    575             {
    576                 /*
    577                  * Hexadecimal number or a string?
    578                  */
    579                 char *psz = pszExpr;
    580                 while (RT_C_IS_XDIGIT(*psz))
    581                     psz++;
    582                 if (!*psz)
    583                     rc = dbgcEvalSubNum(pszExpr, 16, pResult);
    584                 else if ((*psz == 'h' || *psz == 'H') && !psz[1])
    585                 {
    586                     *psz = '\0';
    587                     rc = dbgcEvalSubNum(pszExpr, 16, pResult);
    588                 }
    589                 else
    590                     rc = dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
    591             }
    592         }
    593     }
     422        return rc;
     423    }
     424
     425    /*
     426     * Assuming plain expression.
     427     * Didn't find any operators, so it must be a plain expression.
     428     * Go by desired category first, then if anythings go, try guess.
     429     */
     430    switch (enmCategory)
     431    {
     432        case DBGCVAR_CAT_ANY:
     433            return dbgcEvalSubUnaryAny(pDbgc, pszExpr, cchExpr, pResult);
     434
     435        case DBGCVAR_CAT_POINTER_NUMBER:
     436        case DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE:
     437        case DBGCVAR_CAT_POINTER:
     438        case DBGCVAR_CAT_POINTER_NO_RANGE:
     439        case DBGCVAR_CAT_GC_POINTER:
     440        case DBGCVAR_CAT_GC_POINTER_NO_RANGE:
     441        case DBGCVAR_CAT_NUMBER:
     442        case DBGCVAR_CAT_NUMBER_NO_RANGE:
     443            /* Pointers will be promoted later. */
     444            return dbgcEvalSubNumericOrPointer(pDbgc, pszExpr, cchExpr, enmCategory, pResult);
     445
     446        case DBGCVAR_CAT_STRING:
     447        case DBGCVAR_CAT_SYMBOL:
     448            /* Symbols will be promoted later. */
     449            return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
     450
     451        case DBGCVAR_CAT_OPTION:
     452        case DBGCVAR_CAT_OPTION_STRING:
     453        case DBGCVAR_CAT_OPTION_NUMBER:
     454            return VERR_DBGC_PARSE_NOT_IMPLEMENTED;
     455    }
     456
     457    AssertMsgFailed(("enmCategory=%d\n", enmCategory));
     458    rc = VERR_NOT_IMPLEMENTED;
    594459
    595460    return rc;
     
    623488    if (!*pszExpr)
    624489        return VERR_DBGC_PARSE_EMPTY_ARGUMENT;
    625 
    626     /* it there is any kind of quoting in the expression, it's string meat. */
    627     if (strpbrk(pszExpr, "\"'`"))
    628         return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);
    629490
    630491    /*
     
    671532    }
    672533
    673     /* tabs to spaces. */
     534#if 0  /* why was this needed? It'll screw up strings. */
     535    /* tabs to spaces */
    674536    char *psz = pszExpr;
    675537    while ((psz = strchr(psz, '\t')) != NULL)
    676538        *psz = ' ';
     539#endif
    677540
    678541    /*
     
    682545     * evaluate with respect to unary operators
    683546     */
    684     char       *pszOpSplit = NULL;
    685     PCDBGCOP    pOpSplit = NULL;
    686     unsigned    cBinaryOps = 0;
    687     unsigned    cPar = 0;
     547    char       *pszOpSplit  = NULL;
     548    PCDBGCOP    pOpSplit    = NULL;
     549    unsigned    cBinaryOps  = 0;
     550    unsigned    cPar        = 0;
     551    char        chQuote     = '\0';
     552    char        chPrev      = ' ';
     553    bool        fBinary     = false;
     554    char       *psz         = pszExpr;
    688555    char        ch;
    689     char        chPrev = ' ';
    690     bool        fBinary = false;
    691     psz = pszExpr;
    692556
    693557    while ((ch = *psz) != '\0')
     
    695559        //Log2(("ch=%c cPar=%d fBinary=%d\n", ch, cPar, fBinary));
    696560        /*
    697          * Parenthesis.
    698          */
    699         if (ch == '(')
     561         * String quoting.
     562         */
     563        if (chQuote)
     564        {
     565            if (   ch == chQuote
     566                && psz[1] != chQuote)
     567            {
     568                chQuote = '\0';
     569                fBinary = true;
     570            }
     571        }
     572        else if (ch == '"' || ch == '\'')
     573            chQuote = ch;
     574        /*
     575         * Parentheses.
     576         */
     577        else if (ch == '(')
    700578        {
    701579            cPar++;
     
    754632    } /* parse loop. */
    755633
     634    if (chQuote)
     635        return VERR_DBGC_PARSE_UNBALANCED_QUOTE;
    756636
    757637    /*
     
    791671    }
    792672    else
    793         /* plain expression or using unary operators perhaps with parentheses. */
     673        /* plain expression, qutoed string, or using unary operators perhaps with parentheses. */
    794674        rc = dbgcEvalSubUnary(pDbgc, pszExpr, cchExpr, enmCategory, pResult);
    795675
    796676    return rc;
     677}
     678
     679
     680/**
     681 * Worker for dbgcProcessArguments that performs type checking and promoptions.
     682 *
     683 * @returns VBox status code.
     684 *
     685 * @param   pDbgc       Debugger console instance data.
     686 * @param   enmCategory The target category for the result.
     687 * @param   pArg        The argument to check and promote.
     688 */
     689static int dbgcCheckAndTypePromoteArgument(PDBGC pDbgc, DBGCVARCAT enmCategory, PDBGCVAR pArg)
     690{
     691    switch (enmCategory)
     692    {
     693        /*
     694         * Anything goes
     695         */
     696        case DBGCVAR_CAT_ANY:
     697            return VINF_SUCCESS;
     698
     699        /*
     700         * Pointer with and without range.
     701         * We can try resolve strings and symbols as symbols and promote
     702         * numbers to flat GC pointers.
     703         */
     704        case DBGCVAR_CAT_POINTER_NO_RANGE:
     705        case DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE:
     706            if (pArg->enmRangeType != DBGCVAR_RANGE_NONE)
     707                return VERR_DBGC_PARSE_NO_RANGE_ALLOWED;
     708            /* fallthru */
     709        case DBGCVAR_CAT_POINTER:
     710        case DBGCVAR_CAT_POINTER_NUMBER:
     711            switch (pArg->enmType)
     712            {
     713                case DBGCVAR_TYPE_GC_FLAT:
     714                case DBGCVAR_TYPE_GC_FAR:
     715                case DBGCVAR_TYPE_GC_PHYS:
     716                case DBGCVAR_TYPE_HC_FLAT:
     717                case DBGCVAR_TYPE_HC_PHYS:
     718                    return VINF_SUCCESS;
     719
     720                case DBGCVAR_TYPE_SYMBOL:
     721                case DBGCVAR_TYPE_STRING:
     722                {
     723                    DBGCVAR Var;
     724                    int rc = dbgcSymbolGet(pDbgc, pArg->u.pszString, DBGCVAR_TYPE_GC_FLAT, &Var);
     725                    if (RT_SUCCESS(rc))
     726                    {
     727                        /* deal with range */
     728                        if (pArg->enmRangeType != DBGCVAR_RANGE_NONE)
     729                        {
     730                            Var.enmRangeType = pArg->enmRangeType;
     731                            Var.u64Range = pArg->u64Range;
     732                        }
     733                        else if (enmCategory == DBGCVAR_CAT_POINTER_NO_RANGE)
     734                            Var.enmRangeType = DBGCVAR_RANGE_NONE;
     735                        *pArg = Var;
     736                    }
     737                    return rc;
     738                }
     739
     740                case DBGCVAR_TYPE_NUMBER:
     741                    if (   enmCategory != DBGCVAR_CAT_POINTER_NUMBER
     742                        && enmCategory != DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE)
     743                    {
     744                        RTGCPTR GCPtr = (RTGCPTR)pArg->u.u64Number;
     745                        pArg->enmType = DBGCVAR_TYPE_GC_FLAT;
     746                        pArg->u.GCFlat = GCPtr;
     747                    }
     748                    return VINF_SUCCESS;
     749
     750                default:
     751                    AssertMsgFailedReturn(("Invalid type %d\n"), VERR_DBGC_PARSE_INCORRECT_ARG_TYPE);
     752            }
     753            break;                      /* (not reached) */
     754
     755        /*
     756         * GC pointer with and without range.
     757         * We can try resolve strings and symbols as symbols and
     758         * promote numbers to flat GC pointers.
     759         */
     760        case DBGCVAR_CAT_GC_POINTER_NO_RANGE:
     761            if (pArg->enmRangeType != DBGCVAR_RANGE_NONE)
     762                return VERR_DBGC_PARSE_NO_RANGE_ALLOWED;
     763            /* fallthru */
     764        case DBGCVAR_CAT_GC_POINTER:
     765            switch (pArg->enmType)
     766            {
     767                case DBGCVAR_TYPE_GC_FLAT:
     768                case DBGCVAR_TYPE_GC_FAR:
     769                case DBGCVAR_TYPE_GC_PHYS:
     770                    return VINF_SUCCESS;
     771
     772                case DBGCVAR_TYPE_HC_FLAT:
     773                case DBGCVAR_TYPE_HC_PHYS:
     774                    return VERR_DBGC_PARSE_CONVERSION_FAILED;
     775
     776                case DBGCVAR_TYPE_SYMBOL:
     777                case DBGCVAR_TYPE_STRING:
     778                {
     779                    DBGCVAR Var;
     780                    int rc = dbgcSymbolGet(pDbgc, pArg->u.pszString, DBGCVAR_TYPE_GC_FLAT, &Var);
     781                    if (RT_SUCCESS(rc))
     782                    {
     783                        /* deal with range */
     784                        if (pArg->enmRangeType != DBGCVAR_RANGE_NONE)
     785                        {
     786                            Var.enmRangeType = pArg->enmRangeType;
     787                            Var.u64Range = pArg->u64Range;
     788                        }
     789                        else if (enmCategory == DBGCVAR_CAT_POINTER_NO_RANGE)
     790                            Var.enmRangeType = DBGCVAR_RANGE_NONE;
     791                        *pArg = Var;
     792                    }
     793                    return rc;
     794                }
     795
     796                case DBGCVAR_TYPE_NUMBER:
     797                {
     798                    RTGCPTR GCPtr = (RTGCPTR)pArg->u.u64Number;
     799                    pArg->enmType = DBGCVAR_TYPE_GC_FLAT;
     800                    pArg->u.GCFlat = GCPtr;
     801                    return VINF_SUCCESS;
     802                }
     803
     804                default:
     805                    AssertMsgFailedReturn(("Invalid type %d\n"), VERR_DBGC_PARSE_INCORRECT_ARG_TYPE);
     806            }
     807            break;                      /* (not reached) */
     808
     809        /*
     810         * Number with or without a range.
     811         * Numbers can be resolved from symbols, but we cannot demote a pointer
     812         * to a number.
     813         */
     814        case DBGCVAR_CAT_NUMBER_NO_RANGE:
     815            if (pArg->enmRangeType != DBGCVAR_RANGE_NONE)
     816                return VERR_DBGC_PARSE_NO_RANGE_ALLOWED;
     817            /* fallthru */
     818        case DBGCVAR_CAT_NUMBER:
     819            switch (pArg->enmType)
     820            {
     821                case DBGCVAR_TYPE_GC_FLAT:
     822                case DBGCVAR_TYPE_GC_FAR:
     823                case DBGCVAR_TYPE_GC_PHYS:
     824                case DBGCVAR_TYPE_HC_FLAT:
     825                case DBGCVAR_TYPE_HC_PHYS:
     826                    return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE;
     827
     828                case DBGCVAR_TYPE_NUMBER:
     829                    return VINF_SUCCESS;
     830
     831                case DBGCVAR_TYPE_SYMBOL:
     832                case DBGCVAR_TYPE_STRING:
     833                {
     834                    DBGCVAR Var;
     835                    int rc = dbgcSymbolGet(pDbgc, pArg->u.pszString, DBGCVAR_TYPE_NUMBER, &Var);
     836                    if (RT_SUCCESS(rc))
     837                    {
     838                        /* deal with range */
     839                        if (pArg->enmRangeType != DBGCVAR_RANGE_NONE)
     840                        {
     841                            Var.enmRangeType = pArg->enmRangeType;
     842                            Var.u64Range = pArg->u64Range;
     843                        }
     844                        else if (enmCategory == DBGCVAR_CAT_POINTER_NO_RANGE)
     845                            Var.enmRangeType = DBGCVAR_RANGE_NONE;
     846                        *pArg = Var;
     847                    }
     848                    return rc;
     849                }
     850
     851                default:
     852                    AssertMsgFailedReturn(("Invalid type %d\n"), VERR_DBGC_PARSE_INCORRECT_ARG_TYPE);
     853            }
     854            break;                      /* (not reached) */
     855
     856        /*
     857         * Symbols and strings are basically the same thing for the time being.
     858         */
     859        case DBGCVAR_CAT_STRING:
     860        case DBGCVAR_CAT_SYMBOL:
     861        {
     862            switch (pArg->enmType)
     863            {
     864                case DBGCVAR_TYPE_STRING:
     865                    if (enmCategory == DBGCVAR_CAT_SYMBOL)
     866                        pArg->enmType = DBGCVAR_TYPE_SYMBOL;
     867                    return VINF_SUCCESS;
     868
     869                case DBGCVAR_TYPE_SYMBOL:
     870                    if (enmCategory == DBGCVAR_CAT_STRING)
     871                        pArg->enmType = DBGCVAR_TYPE_STRING;
     872                    return VINF_SUCCESS;
     873                default:
     874                    break;
     875            }
     876
     877            /* Stringify numeric and poitner values. */
     878            size_t cbScratch = sizeof(pDbgc->achScratch) - (pDbgc->pszScratch - &pDbgc->achScratch[0]);
     879            size_t cch = pDbgc->CmdHlp.pfnStrPrintf(&pDbgc->CmdHlp, pDbgc->pszScratch, cbScratch, "%Dv", pArg);
     880            if (cch + 1 >= cbScratch)
     881                return VERR_DBGC_PARSE_NO_SCRATCH;
     882
     883            pArg->enmType      = enmCategory == DBGCVAR_CAT_STRING ? DBGCVAR_TYPE_STRING : DBGCVAR_TYPE_SYMBOL;
     884            pArg->u.pszString  = pDbgc->pszScratch;
     885            pArg->enmRangeType = DBGCVAR_RANGE_BYTES;
     886            pArg->u64Range     = cch;
     887
     888            pDbgc->pszScratch += cch + 1;
     889            return VINF_SUCCESS;
     890        }
     891
     892        /*
     893         * These are not yet implemented.
     894         */
     895        case DBGCVAR_CAT_OPTION:
     896        case DBGCVAR_CAT_OPTION_STRING:
     897        case DBGCVAR_CAT_OPTION_NUMBER:
     898            AssertMsgFailedReturn(("Not implemented enmCategory=%d\n", enmCategory), VERR_DBGC_PARSE_NOT_IMPLEMENTED);
     899
     900        default:
     901            AssertMsgFailedReturn(("Bad enmCategory=%d\n", enmCategory), VERR_DBGC_PARSE_NOT_IMPLEMENTED);
     902    }
    797903}
    798904
     
    835941
    836942    /*
    837      * This is a hack, it's "temporary" and should go away "when" the parser is
    838      * modified to match arguments while parsing.
    839      */
    840     if (    pCmd->cArgsMax == 1
    841         &&  pCmd->cArgsMin == 1
    842         &&  pCmd->cArgDescs == 1
    843         &&  (   pCmd->paArgDescs[0].enmCategory == DBGCVAR_CAT_STRING
    844              || pCmd->paArgDescs[0].enmCategory == DBGCVAR_CAT_SYMBOL)
    845         &&  cArgs >= 1)
    846     {
    847         *pcArgs = 1;
    848         RTStrStripR(pszArgs);
    849         return dbgcEvalSubString(pDbgc, pszArgs, strlen(pszArgs), &paArgs[0]);
    850     }
    851 
    852     /*
    853943     * The parse loop.
    854944     */
     
    871961        if (pArg >= &paArgs[cArgs])
    872962            return VERR_DBGC_PARSE_ARGUMENT_OVERFLOW;
    873 #ifdef DEBUG_bird /* work in progress. */
    874963        if (iVarDesc >= cVarDescs)
    875964            return VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS;
    876965
    877966        /* Walk argument descriptors. */
    878         if (    (    paVarDescs[iVarDesc].fFlags & DBGCVD_FLAGS_DEP_PREV
    879                 &&  &paVarDescs[iVarDesc - 1] != pPrevDesc)
    880             ||  cCurDesc >= paVarDescs[iVarDesc].cTimesMax)
     967        if (cCurDesc >= paVarDescs[iVarDesc].cTimesMax)
    881968        {
    882969            iVarDesc++;
     
    885972            cCurDesc = 0;
    886973        }
    887 #endif
    888974
    889975        /*
     
    9141000             * We use the REXX way of escaping the quotation char, i.e. double occurrence.
    9151001             */
    916             else if (ch == '\'' || ch == '"' || ch == '`')
     1002            else if (ch == '\'' || ch == '"')
    9171003            {
    9181004                if (chQuote)
     
    9331019             * Parenthesis can of course be nested.
    9341020             */
    935             else if (ch == '(')
     1021            else if (!chQuote && ch == '(')
    9361022            {
    9371023                cPar++;
    9381024                fBinary = false;
    9391025            }
    940             else if (ch == ')')
     1026            else if (!chQuote && ch == ')')
    9411027            {
    9421028                if (!cPar)
     
    9971083        size_t cchArgs = strlen(pszArgs);
    9981084
    999 
    1000 #ifdef DEBUG_bird /* work in progress. */
    10011085        /*
    10021086         * Try optional arguments until we find something which matches
     
    10071091            char *pszArgsCopy = (char *)RTMemDup(pszArgs, cchArgs + 1);
    10081092            if (!pszArgsCopy)
    1009                 return VERR_NO_MEMORY;
    1010 
    1011             int rc = dbgcEvalSub(pDbgc, pszArgs, strlen(pszArgs), paVarDescs[iVarDesc].enmCategory, pArg);
     1093                return VERR_DBGC_PARSE_NO_MEMORY;
     1094
     1095            int rc = dbgcEvalSub(pDbgc, pszArgs, cchArgs, paVarDescs[iVarDesc].enmCategory, pArg);
     1096            if (RT_SUCCESS(rc))
     1097                rc = dbgcCheckAndTypePromoteArgument(pDbgc, paVarDescs[iVarDesc].enmCategory, pArg);
    10121098            if (RT_SUCCESS(rc))
    10131099            {
     
    10211107            RTMemFree(pszArgsCopy);
    10221108
    1023             /* can we advance? */
     1109            /* Continue searching optional descriptors? */
     1110            if (   rc != VERR_DBGC_PARSE_INCORRECT_ARG_TYPE
     1111                && rc != VERR_DBGC_PARSE_INVALID_NUMBER
     1112                && rc != VERR_DBGC_PARSE_NO_RANGE_ALLOWED
     1113               )
     1114                   return rc;
     1115
     1116            /* Try advance to the next descriptor. */
    10241117            if (paVarDescs[iVarDesc].cTimesMin > cCurDesc)
    10251118                return rc;
    1026             if (++iVarDesc >= cVarDescs)
     1119            iVarDesc++;
     1120            if (!cCurDesc)
     1121                while (   iVarDesc < cVarDescs
     1122                       && (paVarDescs[iVarDesc].fFlags & DBGCVD_FLAGS_DEP_PREV))
     1123                    iVarDesc++;
     1124            if (iVarDesc >= cVarDescs)
    10271125                return rc;
    10281126            cCurDesc = 0;
    10291127        }
    10301128
    1031 #else
    1032         /*
    1033          * Parse and evaluate the argument.
    1034          */
    1035         int rc = dbgcEvalSub(pDbgc, pszArgs, cchArgs, DBGCVAR_CAT_ANY, pArg);
    1036         if (RT_FAILURE(rc))
    1037             return rc;
    1038 #endif
    1039 
    1040         /*
    1041          * Next.
     1129        /*
     1130         * Next argument.
    10421131         */
    10431132        iVar++;
     
    10501139
    10511140    /*
    1052      * Match the arguments.
    1053      */
    1054     return dbgcEvalSubMatchVars(pDbgc, pCmd->cArgsMin, pCmd->cArgsMax, pCmd->paArgDescs, pCmd->cArgDescs, pArg0, pArg - pArg0);
     1141     * Check that the rest of the argument descriptors indicate optional args.
     1142     */
     1143    if (iVarDesc < cVarDescs)
     1144    {
     1145        if (cCurDesc < paVarDescs[iVarDesc].cTimesMin)
     1146            return VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS;
     1147        iVarDesc++;
     1148        while (iVarDesc < cVarDescs)
     1149        {
     1150            if (paVarDescs[iVarDesc].cTimesMin)
     1151                return VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS;
     1152            iVarDesc++;
     1153        }
     1154    }
     1155
     1156    return VINF_SUCCESS;
    10551157}
    10561158
  • trunk/src/VBox/Debugger/testcase/tstDBGCParser.cpp

    r41553 r41558  
    406406
    407407
     408/*
     409 *
     410 * CodeView emulation commands.
     411 * CodeView emulation commands.
     412 * CodeView emulation commands.
     413 *
     414 */
     415
    408416
    409417static void testCodeView_ba(PDBGC pDbgc)
     
    447455             DBGCVAR_TYPE_STRING, "command",                    DBGCVAR_RANGE_BYTES, UINT64_C(7));
    448456
    449     tstTry(pDbgc, "ba x 1 0f000:1234 qnx 1000 \"command\"\n",   VERR_DBGC_PARSE_ARGUMENT_TYPE_MISMATCH);
    450     tstTry(pDbgc, "ba x 1 0f000:1234 5 qnx \"command\"\n",      VERR_DBGC_PARSE_ARGUMENT_TYPE_MISMATCH);
    451     tstTry(pDbgc, "ba x qnx 0f000:1234 5 1000 \"command\"\n",   VERR_DBGC_PARSE_ARGUMENT_TYPE_MISMATCH);
    452     tstTry(pDbgc, "ba x 1 qnx 5 1000 \"command\"\n",            VERR_DBGC_PARSE_ARGUMENT_TYPE_MISMATCH);
     457    tstTry(pDbgc, "ba x 1 0f000:1234 qnx 1000 \"command\"\n",   VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
     458    tstTry(pDbgc, "ba x 1 0f000:1234 5 qnx \"command\"\n",      VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
     459    tstTry(pDbgc, "ba x qnx 0f000:1234 5 1000 \"command\"\n",   VERR_DBGC_PARSE_INVALID_NUMBER);
     460    tstTry(pDbgc, "ba x 1 qnx 5 1000 \"command\"\n",            VERR_DBGC_PARSE_INVALID_NUMBER);
     461}
     462
     463
     464static void testCodeView_bc(PDBGC pDbgc)
     465{
     466    RTTestISub("codeview - bc");
     467}
     468
     469
     470static void testCodeView_bd(PDBGC pDbgc)
     471{
     472    RTTestISub("codeview - bc");
     473}
     474
     475
     476static void testCodeView_be(PDBGC pDbgc)
     477{
     478    RTTestISub("codeview - be");
     479}
     480
     481
     482static void testCodeView_bl(PDBGC pDbgc)
     483{
     484    RTTestISub("codeview - bl");
     485}
     486
     487
     488static void testCodeView_bp(PDBGC pDbgc)
     489{
     490    RTTestISub("codeview - bp");
     491}
     492
     493
     494static void testCodeView_br(PDBGC pDbgc)
     495{
     496    RTTestISub("codeview - br");
     497}
     498
     499
     500static void testCodeView_d(PDBGC pDbgc)
     501{
     502    RTTestISub("codeview - d");
     503}
     504
     505
     506static void testCodeView_da(PDBGC pDbgc)
     507{
     508    RTTestISub("codeview - da");
     509}
     510
     511
     512static void testCodeView_db(PDBGC pDbgc)
     513{
     514    RTTestISub("codeview - db");
     515}
     516
     517
     518static void testCodeView_dd(PDBGC pDbgc)
     519{
     520    RTTestISub("codeview - dd");
     521}
     522
     523
     524static void testCodeView_dg(PDBGC pDbgc)
     525{
     526    RTTestISub("codeview - dg");
     527}
     528
     529
     530static void testCodeView_dga(PDBGC pDbgc)
     531{
     532    RTTestISub("codeview - dga");
     533}
     534
     535
     536static void testCodeView_di(PDBGC pDbgc)
     537{
     538    RTTestISub("codeview - di");
     539}
     540
     541
     542static void testCodeView_dia(PDBGC pDbgc)
     543{
     544    RTTestISub("codeview - dia");
     545}
     546
     547
     548static void testCodeView_dl(PDBGC pDbgc)
     549{
     550    RTTestISub("codeview - dl");
     551}
     552
     553
     554static void testCodeView_dla(PDBGC pDbgc)
     555{
     556    RTTestISub("codeview - dla");
     557}
     558
     559
     560static void testCodeView_dpd(PDBGC pDbgc)
     561{
     562    RTTestISub("codeview - dpd");
     563}
     564
     565
     566static void testCodeView_dpda(PDBGC pDbgc)
     567{
     568    RTTestISub("codeview - dpda");
     569}
     570
     571
     572static void testCodeView_dpdb(PDBGC pDbgc)
     573{
     574    RTTestISub("codeview - dpdb");
     575}
     576
     577
     578static void testCodeView_dpdg(PDBGC pDbgc)
     579{
     580    RTTestISub("codeview - dpdg");
     581}
     582
     583
     584static void testCodeView_dpdh(PDBGC pDbgc)
     585{
     586    RTTestISub("codeview - dpdh");
     587}
     588
     589
     590static void testCodeView_dph(PDBGC pDbgc)
     591{
     592    RTTestISub("codeview - dph");
     593}
     594
     595
     596static void testCodeView_dphg(PDBGC pDbgc)
     597{
     598    RTTestISub("codeview - dphg");
     599}
     600
     601
     602static void testCodeView_dphh(PDBGC pDbgc)
     603{
     604    RTTestISub("codeview - dphh");
     605}
     606
     607
     608static void testCodeView_dq(PDBGC pDbgc)
     609{
     610    RTTestISub("codeview - dq");
     611}
     612
     613
     614static void testCodeView_dt(PDBGC pDbgc)
     615{
     616    RTTestISub("codeview - dt");
     617}
     618
     619
     620static void testCodeView_dt16(PDBGC pDbgc)
     621{
     622    RTTestISub("codeview - dt16");
     623}
     624
     625
     626static void testCodeView_dt32(PDBGC pDbgc)
     627{
     628    RTTestISub("codeview - dt32");
     629}
     630
     631
     632static void testCodeView_dt64(PDBGC pDbgc)
     633{
     634    RTTestISub("codeview - dt64");
     635}
     636
     637
     638static void testCodeView_dw(PDBGC pDbgc)
     639{
     640    RTTestISub("codeview - dw");
     641}
     642
     643
     644static void testCodeView_eb(PDBGC pDbgc)
     645{
     646    RTTestISub("codeview - eb");
     647}
     648
     649
     650static void testCodeView_ew(PDBGC pDbgc)
     651{
     652    RTTestISub("codeview - ew");
     653}
     654
     655
     656static void testCodeView_ed(PDBGC pDbgc)
     657{
     658    RTTestISub("codeview - ed");
     659}
     660
     661
     662static void testCodeView_eq(PDBGC pDbgc)
     663{
     664    RTTestISub("codeview - eq");
     665}
     666
     667
     668static void testCodeView_g(PDBGC pDbgc)
     669{
     670    RTTestISub("codeview - g");
     671}
     672
     673
     674static void testCodeView_k(PDBGC pDbgc)
     675{
     676    RTTestISub("codeview - k");
     677}
     678
     679
     680static void testCodeView_kg(PDBGC pDbgc)
     681{
     682    RTTestISub("codeview - kg");
     683}
     684
     685
     686static void testCodeView_kh(PDBGC pDbgc)
     687{
     688    RTTestISub("codeview - kh");
     689}
     690
     691
     692static void testCodeView_lm(PDBGC pDbgc)
     693{
     694    RTTestISub("codeview - lm");
     695}
     696
     697
     698static void testCodeView_lmo(PDBGC pDbgc)
     699{
     700    RTTestISub("codeview - lmo");
     701}
     702
     703
     704static void testCodeView_ln(PDBGC pDbgc)
     705{
     706    RTTestISub("codeview - ln");
     707}
     708
     709
     710static void testCodeView_ls(PDBGC pDbgc)
     711{
     712    RTTestISub("codeview - ls");
     713}
     714
     715
     716static void testCodeView_m(PDBGC pDbgc)
     717{
     718    RTTestISub("codeview - m");
     719}
     720
     721
     722static void testCodeView_r(PDBGC pDbgc)
     723{
     724    RTTestISub("codeview - r");
     725}
     726
     727
     728static void testCodeView_rg(PDBGC pDbgc)
     729{
     730    RTTestISub("codeview - rg");
     731}
     732
     733
     734static void testCodeView_rg32(PDBGC pDbgc)
     735{
     736    RTTestISub("codeview - rg32");
     737}
     738
     739
     740static void testCodeView_rg64(PDBGC pDbgc)
     741{
     742    RTTestISub("codeview - rg64");
     743}
     744
     745
     746static void testCodeView_rh(PDBGC pDbgc)
     747{
     748    RTTestISub("codeview - rh");
     749}
     750
     751
     752static void testCodeView_rt(PDBGC pDbgc)
     753{
     754    RTTestISub("codeview - rt");
     755}
     756
     757
     758static void testCodeView_s(PDBGC pDbgc)
     759{
     760    RTTestISub("codeview - s");
     761}
     762
     763
     764static void testCodeView_sa(PDBGC pDbgc)
     765{
     766    RTTestISub("codeview - sa");
     767}
     768
     769
     770static void testCodeView_sb(PDBGC pDbgc)
     771{
     772    RTTestISub("codeview - sb");
     773}
     774
     775
     776static void testCodeView_sd(PDBGC pDbgc)
     777{
     778    RTTestISub("codeview - sd");
     779}
     780
     781
     782static void testCodeView_sq(PDBGC pDbgc)
     783{
     784    RTTestISub("codeview - sq");
     785}
     786
     787
     788static void testCodeView_su(PDBGC pDbgc)
     789{
     790    RTTestISub("codeview - su");
     791}
     792
     793
     794static void testCodeView_sw(PDBGC pDbgc)
     795{
     796    RTTestISub("codeview - sw");
     797}
     798
     799
     800static void testCodeView_t(PDBGC pDbgc)
     801{
     802    RTTestISub("codeview - t");
     803}
     804
     805
     806static void testCodeView_y(PDBGC pDbgc)
     807{
     808    RTTestISub("codeview - y");
     809}
     810
     811
     812static void testCodeView_u64(PDBGC pDbgc)
     813{
     814    RTTestISub("codeview - u64");
     815}
     816
     817
     818static void testCodeView_u32(PDBGC pDbgc)
     819{
     820    RTTestISub("codeview - u32");
     821}
     822
     823
     824static void testCodeView_u16(PDBGC pDbgc)
     825{
     826    RTTestISub("codeview - u16");
     827}
     828
     829
     830static void testCodeView_uv86(PDBGC pDbgc)
     831{
     832    RTTestISub("codeview - uv86");
     833}
     834
     835
     836/*
     837 * Common commands.
     838 */
     839
     840static void testCommon_bye_exit_quit(PDBGC pDbgc)
     841{
     842    RTTestISub("common - bye/exit/quit");
     843    /* These have the same parameter descriptor and handler, the command really
     844       just has a couple of aliases.*/
     845    tstTry(pDbgc, "bye\n", VINF_SUCCESS);
     846    tstTry(pDbgc, "bye x\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
     847    tstTry(pDbgc, "bye 1\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
     848    tstTry(pDbgc, "bye %bad:bad\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
     849    tstTry(pDbgc, "exit\n", VINF_SUCCESS);
     850    tstTry(pDbgc, "quit\n", VINF_SUCCESS);
     851}
     852
     853
     854static void testCommon_cpu(PDBGC pDbgc)
     855{
     856    RTTestISub("common - cpu");
     857    tstTry(pDbgc, "cpu\n", VINF_SUCCESS);
     858    tstTry(pDbgc, "cpu 1\n", VINF_SUCCESS);
     859    tstTry(pDbgc, "cpu 1 1\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
     860    tstTry(pDbgc, "cpu emt\n", VERR_DBGC_PARSE_INVALID_NUMBER);
     861    tstTry(pDbgc, "cpu @eax\n", VINF_SUCCESS);
     862    tstTry(pDbgc, "cpu %bad:bad\n", VERR_DBGC_PARSE_CONVERSION_FAILED);
     863}
     864
     865
     866static void testCommon_echo(PDBGC pDbgc)
     867{
     868    RTTestISub("common - echo");
     869    tstTry(pDbgc, "echo\n", VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS);
     870    tstTry(pDbgc, "echo 1\n", VINF_SUCCESS);
     871    tstTryEx(pDbgc, "echo 1 2 3  4 5   6\n", VINF_SUCCESS, false, "1 2 3 4 5 6", -1);
     872
     873    /* The idea here is that since the prefered input is a string, we
     874       definitely won't be mistaking number like beginnings as numbers. */
     875    tstTryEx(pDbgc, "echo 1234567890abcdefghijklmn\n", VINF_SUCCESS, false, "1234567890abcdefghijklmn", -1);
     876
     877    /* The idea here is that we'll perform the + operation and then convert the
     878       result to a string (hex). */
     879    tstTryEx(pDbgc, "echo 1 + 1\n", VINF_SUCCESS, false, "2", -1);
     880    tstTryEx(pDbgc, "echo \"1 + 1\"\n", VINF_SUCCESS, false, "1 + 1", -1);
     881
     882    tstTryEx(pDbgc, "echo 0i10 + 6\n", VINF_SUCCESS, false, "10", -1);
     883    tstTryEx(pDbgc, "echo \"0i10 + 6\"\n", VINF_SUCCESS, false, "0i10 + 6", -1);
     884
     885    tstTryEx(pDbgc, "echo %f000:0010\n", VINF_SUCCESS, false, "%00000000000f0010", -1);
     886    tstTryEx(pDbgc, "echo \"%f000:0010\"\n", VINF_SUCCESS, false, "%f000:0010", -1);
     887
     888    tstTry(pDbgc, "echo %bad:bad\n", VERR_DBGC_PARSE_CONVERSION_FAILED);
     889}
     890
     891
     892static void testCommon_format(PDBGC pDbgc)
     893{
     894    RTTestISub("common - format");
     895}
     896
     897
     898static void testCommon_detect(PDBGC pDbgc)
     899{
     900    RTTestISub("common - detect");
     901}
     902
     903
     904static void testCommon_harakiri(PDBGC pDbgc)
     905{
     906    RTTestISub("common - harakiri");
     907}
     908
     909
     910static void testCommon_help(PDBGC pDbgc)
     911{
     912    RTTestISub("common - help");
     913}
     914
     915
     916static void testCommon_info(PDBGC pDbgc)
     917{
     918    RTTestISub("common - info");
     919    tstTry(pDbgc, "info 12fg\n", VINF_SUCCESS);
     920    tstTry(pDbgc, "info fflags argument\n", VINF_SUCCESS);
     921}
     922
     923
     924static void testCommon_loadimage(PDBGC pDbgc)
     925{
     926    RTTestISub("common - loadimage");
     927}
     928
     929
     930static void testCommon_loadmap(PDBGC pDbgc)
     931{
     932    RTTestISub("common - loadmap");
     933}
     934
     935
     936static void testCommon_loadplugin(PDBGC pDbgc)
     937{
     938    RTTestISub("common - loadplugin");
     939}
     940
     941
     942static void testCommon_loadseg(PDBGC pDbgc)
     943{
     944    RTTestISub("common - loadseg");
     945}
     946
     947
     948static void testCommon_loadsyms(PDBGC pDbgc)
     949{
     950    RTTestISub("common - loadsyms");
     951}
     952
     953
     954static void testCommon_loadvars(PDBGC pDbgc)
     955{
     956    RTTestISub("common - loadvars");
     957}
     958
     959
     960static void testCommon_log(PDBGC pDbgc)
     961{
     962    RTTestISub("common - log");
     963}
     964
     965
     966static void testCommon_logdest(PDBGC pDbgc)
     967{
     968    RTTestISub("common - logdest");
     969}
     970
     971
     972static void testCommon_logflags(PDBGC pDbgc)
     973{
     974    RTTestISub("common - logflags");
     975}
     976
     977
     978static void testCommon_runscript(PDBGC pDbgc)
     979{
     980    RTTestISub("common - runscript");
     981}
     982
     983
     984static void testCommon_set(PDBGC pDbgc)
     985{
     986    RTTestISub("common - set");
     987}
     988
     989
     990static void testCommon_showplugins(PDBGC pDbgc)
     991{
     992    RTTestISub("common - showplugins");
     993}
     994
     995
     996static void testCommon_showvars(PDBGC pDbgc)
     997{
     998    RTTestISub("common - showvars");
     999}
     1000
     1001
     1002static void testCommon_stop(PDBGC pDbgc)
     1003{
     1004    RTTestISub("common - stop");
     1005}
     1006
     1007
     1008static void testCommon_unloadplugin(PDBGC pDbgc)
     1009{
     1010    RTTestISub("common - unloadplugin");
     1011}
     1012
     1013
     1014static void testCommon_unset(PDBGC pDbgc)
     1015{
     1016    RTTestISub("common - unset");
     1017}
     1018
     1019
     1020static void testCommon_writecore(PDBGC pDbgc)
     1021{
     1022    RTTestISub("common - writecore");
     1023}
     1024
     1025
     1026
     1027/*
     1028 * Basic tests.
     1029 */
     1030
     1031static void testBasicsOddCases(PDBGC pDbgc)
     1032{
     1033    RTTestISub("Odd cases");
     1034    tstTry(pDbgc, "r @rax\n", VINF_SUCCESS);
     1035    tstTry(pDbgc, "r @eax\n", VINF_SUCCESS);
     1036    tstTry(pDbgc, "r @ah\n", VINF_SUCCESS);
     1037    tstTry(pDbgc, "r @notavalidregister\n", VERR_DBGF_REGISTER_NOT_FOUND);
     1038}
     1039
     1040
     1041static void testBasicsOperators(PDBGC pDbgc)
     1042{
     1043    RTTestISub("Operators");
     1044    tstNumOp(pDbgc, "1",                                        1);
     1045    tstNumOp(pDbgc, "1",                                        1);
     1046    tstNumOp(pDbgc, "1",                                        1);
     1047
     1048    tstNumOp(pDbgc, "+1",                                       1);
     1049    tstNumOp(pDbgc, "++++++1",                                  1);
     1050
     1051    tstNumOp(pDbgc, "-1",                                       UINT64_MAX);
     1052    tstNumOp(pDbgc, "--1",                                      1);
     1053    tstNumOp(pDbgc, "---1",                                     UINT64_MAX);
     1054    tstNumOp(pDbgc, "----1",                                    1);
     1055
     1056    tstNumOp(pDbgc, "~0",                                       UINT64_MAX);
     1057    tstNumOp(pDbgc, "~1",                                       UINT64_MAX-1);
     1058    tstNumOp(pDbgc, "~~0",                                      0);
     1059    tstNumOp(pDbgc, "~~1",                                      1);
     1060
     1061    tstNumOp(pDbgc, "!1",                                       0);
     1062    tstNumOp(pDbgc, "!0",                                       1);
     1063    tstNumOp(pDbgc, "!42",                                      0);
     1064    tstNumOp(pDbgc, "!!42",                                     1);
     1065    tstNumOp(pDbgc, "!!!42",                                    0);
     1066    tstNumOp(pDbgc, "!!!!42",                                   1);
     1067
     1068    tstNumOp(pDbgc, "1 +1",                                     2);
     1069    tstNumOp(pDbgc, "1 + 1",                                    2);
     1070    tstNumOp(pDbgc, "1+1",                                      2);
     1071    tstNumOp(pDbgc, "1+ 1",                                     2);
     1072
     1073    tstNumOp(pDbgc, "1 - 1",                                    0);
     1074    tstNumOp(pDbgc, "99 - 90",                                  9);
     1075
     1076    tstNumOp(pDbgc, "2 * 2",                                    4);
     1077
     1078    tstNumOp(pDbgc, "2 / 2",                                    1);
     1079    tstNumOp(pDbgc, "2 / 0",                                    UINT64_MAX);
     1080    tstNumOp(pDbgc, "0i1024 / 0i4",                             256);
     1081
     1082    tstNumOp(pDbgc, "8 mod 7",                                  1);
     1083
     1084    tstNumOp(pDbgc, "1<<1",                                     2);
     1085    tstNumOp(pDbgc, "1<<0i32",                                  UINT64_C(0x0000000100000000));
     1086    tstNumOp(pDbgc, "1<<0i48",                                  UINT64_C(0x0001000000000000));
     1087    tstNumOp(pDbgc, "1<<0i63",                                  UINT64_C(0x8000000000000000));
     1088
     1089    tstNumOp(pDbgc, "fedcba0987654321>>0i04",                   UINT64_C(0x0fedcba098765432));
     1090    tstNumOp(pDbgc, "fedcba0987654321>>0i32",                   UINT64_C(0xfedcba09));
     1091    tstNumOp(pDbgc, "fedcba0987654321>>0i48",                   UINT64_C(0x0000fedc));
     1092
     1093    tstNumOp(pDbgc, "0ef & 4",                                  4);
     1094    tstNumOp(pDbgc, "01234567891 & fff",                        UINT64_C(0x00000000891));
     1095    tstNumOp(pDbgc, "01234567891 & ~fff",                       UINT64_C(0x01234567000));
     1096
     1097    tstNumOp(pDbgc, "1 | 1",                                    1);
     1098    tstNumOp(pDbgc, "0 | 4",                                    4);
     1099    tstNumOp(pDbgc, "4 | 0",                                    4);
     1100    tstNumOp(pDbgc, "4 | 4",                                    4);
     1101    tstNumOp(pDbgc, "1 | 4 | 2",                                7);
     1102
     1103    tstNumOp(pDbgc, "1 ^ 1",                                    0);
     1104    tstNumOp(pDbgc, "1 ^ 0",                                    1);
     1105    tstNumOp(pDbgc, "0 ^ 1",                                    1);
     1106    tstNumOp(pDbgc, "3 ^ 1",                                    2);
     1107    tstNumOp(pDbgc, "7 ^ 3",                                    4);
     1108
     1109    tstNumOp(pDbgc, "7 || 3",                                   1);
     1110    tstNumOp(pDbgc, "1 || 0",                                   1);
     1111    tstNumOp(pDbgc, "0 || 1",                                   1);
     1112    tstNumOp(pDbgc, "0 || 0",                                   0);
     1113
     1114    tstNumOp(pDbgc, "0 && 0",                                   0);
     1115    tstNumOp(pDbgc, "1 && 0",                                   0);
     1116    tstNumOp(pDbgc, "0 && 1",                                   0);
     1117    tstNumOp(pDbgc, "1 && 1",                                   1);
     1118    tstNumOp(pDbgc, "4 && 1",                                   1);
     1119}
     1120
     1121
     1122static void testBasicsFundametalParsing(PDBGC pDbgc)
     1123{
     1124    RTTestISub("Fundamental parsing");
     1125    tstTry(pDbgc, "stop\n", VINF_SUCCESS);
     1126    tstTry(pDbgc, "format 1\n", VINF_SUCCESS);
     1127    tstTry(pDbgc, "format \n", VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS);
     1128    tstTry(pDbgc, "format 0 1 23 4\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
     1129    tstTry(pDbgc, "sa 3 23 4 'q' \"21123123\" 'b' \n", VINF_SUCCESS);
    4531130}
    4541131
     
    4771154        if (RT_SUCCESS(rc))
    4781155        {
    479             RTTestSub(g_hTest, "basic parsing");
    480             tstTry(pDbgc, "stop\n", VINF_SUCCESS);
    481             tstTry(pDbgc, "format 1\n", VINF_SUCCESS);
    482             tstTry(pDbgc, "format \n", VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS);
    483             tstTry(pDbgc, "format 0 1 23 4\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
    484             tstTry(pDbgc, "sa 3 23 4 'q' \"21123123\" 'b' \n", VINF_SUCCESS);
    485 
     1156            /*
     1157             * Perform basic tests first.
     1158             */
     1159            testBasicsFundametalParsing(pDbgc);
    4861160            if (RTTestErrorCount(g_hTest) == 0)
    487             {
    488                 RTTestSub(g_hTest, "Operators");
    489                 tstNumOp(pDbgc, "1",                                        1);
    490                 tstNumOp(pDbgc, "1",                                        1);
    491                 tstNumOp(pDbgc, "1",                                        1);
    492 
    493                 tstNumOp(pDbgc, "+1",                                       1);
    494                 tstNumOp(pDbgc, "++++++1",                                  1);
    495 
    496                 tstNumOp(pDbgc, "-1",                                       UINT64_MAX);
    497                 tstNumOp(pDbgc, "--1",                                      1);
    498                 tstNumOp(pDbgc, "---1",                                     UINT64_MAX);
    499                 tstNumOp(pDbgc, "----1",                                    1);
    500 
    501                 tstNumOp(pDbgc, "~0",                                       UINT64_MAX);
    502                 tstNumOp(pDbgc, "~1",                                       UINT64_MAX-1);
    503                 tstNumOp(pDbgc, "~~0",                                      0);
    504                 tstNumOp(pDbgc, "~~1",                                      1);
    505 
    506                 tstNumOp(pDbgc, "!1",                                       0);
    507                 tstNumOp(pDbgc, "!0",                                       1);
    508                 tstNumOp(pDbgc, "!42",                                      0);
    509                 tstNumOp(pDbgc, "!!42",                                     1);
    510                 tstNumOp(pDbgc, "!!!42",                                    0);
    511                 tstNumOp(pDbgc, "!!!!42",                                   1);
    512 
    513                 tstNumOp(pDbgc, "1 +1",                                     2);
    514                 tstNumOp(pDbgc, "1 + 1",                                    2);
    515                 tstNumOp(pDbgc, "1+1",                                      2);
    516                 tstNumOp(pDbgc, "1+ 1",                                     2);
    517 
    518                 tstNumOp(pDbgc, "1 - 1",                                    0);
    519                 tstNumOp(pDbgc, "99 - 90",                                  9);
    520 
    521                 tstNumOp(pDbgc, "2 * 2",                                    4);
    522 
    523                 tstNumOp(pDbgc, "2 / 2",                                    1);
    524                 tstNumOp(pDbgc, "2 / 0",                                    UINT64_MAX);
    525                 tstNumOp(pDbgc, "0i1024 / 0i4",                             256);
    526 
    527                 tstNumOp(pDbgc, "8 mod 7",                                  1);
    528 
    529                 tstNumOp(pDbgc, "1<<1",                                     2);
    530                 tstNumOp(pDbgc, "1<<0i32",                                  UINT64_C(0x0000000100000000));
    531                 tstNumOp(pDbgc, "1<<0i48",                                  UINT64_C(0x0001000000000000));
    532                 tstNumOp(pDbgc, "1<<0i63",                                  UINT64_C(0x8000000000000000));
    533 
    534                 tstNumOp(pDbgc, "fedcba0987654321>>0i04",                   UINT64_C(0x0fedcba098765432));
    535                 tstNumOp(pDbgc, "fedcba0987654321>>0i32",                   UINT64_C(0xfedcba09));
    536                 tstNumOp(pDbgc, "fedcba0987654321>>0i48",                   UINT64_C(0x0000fedc));
    537 
    538                 tstNumOp(pDbgc, "0ef & 4",                                  4);
    539                 tstNumOp(pDbgc, "01234567891 & fff",                        UINT64_C(0x00000000891));
    540                 tstNumOp(pDbgc, "01234567891 & ~fff",                       UINT64_C(0x01234567000));
    541 
    542                 tstNumOp(pDbgc, "1 | 1",                                    1);
    543                 tstNumOp(pDbgc, "0 | 4",                                    4);
    544                 tstNumOp(pDbgc, "4 | 0",                                    4);
    545                 tstNumOp(pDbgc, "4 | 4",                                    4);
    546                 tstNumOp(pDbgc, "1 | 4 | 2",                                7);
    547 
    548                 tstNumOp(pDbgc, "1 ^ 1",                                    0);
    549                 tstNumOp(pDbgc, "1 ^ 0",                                    1);
    550                 tstNumOp(pDbgc, "0 ^ 1",                                    1);
    551                 tstNumOp(pDbgc, "3 ^ 1",                                    2);
    552                 tstNumOp(pDbgc, "7 ^ 3",                                    4);
    553 
    554                 tstNumOp(pDbgc, "7 || 3",                                   1);
    555                 tstNumOp(pDbgc, "1 || 0",                                   1);
    556                 tstNumOp(pDbgc, "0 || 1",                                   1);
    557                 tstNumOp(pDbgc, "0 || 0",                                   0);
    558 
    559                 tstNumOp(pDbgc, "0 && 0",                                   0);
    560                 tstNumOp(pDbgc, "1 && 0",                                   0);
    561                 tstNumOp(pDbgc, "0 && 1",                                   0);
    562                 tstNumOp(pDbgc, "1 && 1",                                   1);
    563                 tstNumOp(pDbgc, "4 && 1",                                   1);
    564             }
    565 
     1161                testBasicsOperators(pDbgc);
    5661162            if (RTTestErrorCount(g_hTest) == 0)
    567             {
    568                 RTTestSub(g_hTest, "Odd cases");
    569                 tstTry(pDbgc, "r @rax\n", VINF_SUCCESS);
    570                 tstTry(pDbgc, "r @eax\n", VINF_SUCCESS);
    571                 tstTry(pDbgc, "r @ah\n", VINF_SUCCESS);
    572                 tstTry(pDbgc, "r @notavalidregister\n", VERR_DBGF_REGISTER_NOT_FOUND);
    573             }
     1163                testBasicsOddCases(pDbgc);
    5741164
    5751165            /*
    576              * Test codeview commands.
     1166             * Test commands.
    5771167             */
    578 #ifdef DEBUG_bird /* This will fail for a while */
    5791168            if (RTTestErrorCount(g_hTest) == 0)
    5801169            {
    5811170                testCodeView_ba(pDbgc);
    582 
     1171                testCodeView_bc(pDbgc);
     1172                testCodeView_bd(pDbgc);
     1173                testCodeView_be(pDbgc);
     1174                testCodeView_bl(pDbgc);
     1175                testCodeView_bp(pDbgc);
     1176                testCodeView_br(pDbgc);
     1177                testCodeView_d(pDbgc);
     1178                testCodeView_da(pDbgc);
     1179                testCodeView_db(pDbgc);
     1180                testCodeView_dd(pDbgc);
     1181                testCodeView_dg(pDbgc);
     1182                testCodeView_dga(pDbgc);
     1183                testCodeView_di(pDbgc);
     1184                testCodeView_dia(pDbgc);
     1185                testCodeView_dl(pDbgc);
     1186                testCodeView_dla(pDbgc);
     1187                testCodeView_dpd(pDbgc);
     1188                testCodeView_dpda(pDbgc);
     1189                testCodeView_dpdb(pDbgc);
     1190                testCodeView_dpdg(pDbgc);
     1191                testCodeView_dpdh(pDbgc);
     1192                testCodeView_dph(pDbgc);
     1193                testCodeView_dphg(pDbgc);
     1194                testCodeView_dphh(pDbgc);
     1195                testCodeView_dq(pDbgc);
     1196                testCodeView_dt(pDbgc);
     1197                testCodeView_dt16(pDbgc);
     1198                testCodeView_dt32(pDbgc);
     1199                testCodeView_dt64(pDbgc);
     1200                testCodeView_dw(pDbgc);
     1201                testCodeView_eb(pDbgc);
     1202                testCodeView_ew(pDbgc);
     1203                testCodeView_ed(pDbgc);
     1204                testCodeView_eq(pDbgc);
     1205                testCodeView_g(pDbgc);
     1206                testCodeView_k(pDbgc);
     1207                testCodeView_kg(pDbgc);
     1208                testCodeView_kh(pDbgc);
     1209                testCodeView_lm(pDbgc);
     1210                testCodeView_lmo(pDbgc);
     1211                testCodeView_ln(pDbgc);
     1212                testCodeView_ls(pDbgc);
     1213                testCodeView_m(pDbgc);
     1214                testCodeView_r(pDbgc);
     1215                testCodeView_rg(pDbgc);
     1216                testCodeView_rg32(pDbgc);
     1217                testCodeView_rg64(pDbgc);
     1218                testCodeView_rh(pDbgc);
     1219                testCodeView_rt(pDbgc);
     1220                testCodeView_s(pDbgc);
     1221                testCodeView_sa(pDbgc);
     1222                testCodeView_sb(pDbgc);
     1223                testCodeView_sd(pDbgc);
     1224                testCodeView_sq(pDbgc);
     1225                testCodeView_su(pDbgc);
     1226                testCodeView_sw(pDbgc);
     1227                testCodeView_t(pDbgc);
     1228                testCodeView_y(pDbgc);
     1229                testCodeView_u64(pDbgc);
     1230                testCodeView_u32(pDbgc);
     1231                testCodeView_u16(pDbgc);
     1232                testCodeView_uv86(pDbgc);
     1233
     1234                testCommon_bye_exit_quit(pDbgc);
     1235                testCommon_cpu(pDbgc);
     1236                testCommon_echo(pDbgc);
     1237                testCommon_format(pDbgc);
     1238                testCommon_detect(pDbgc);
     1239                testCommon_harakiri(pDbgc);
     1240                testCommon_help(pDbgc);
     1241                testCommon_info(pDbgc);
     1242                testCommon_loadimage(pDbgc);
     1243                testCommon_loadmap(pDbgc);
     1244                testCommon_loadplugin(pDbgc);
     1245                testCommon_loadseg(pDbgc);
     1246                testCommon_loadsyms(pDbgc);
     1247                testCommon_loadvars(pDbgc);
     1248                testCommon_log(pDbgc);
     1249                testCommon_logdest(pDbgc);
     1250                testCommon_logflags(pDbgc);
     1251                testCommon_runscript(pDbgc);
     1252                testCommon_set(pDbgc);
     1253                testCommon_showplugins(pDbgc);
     1254                testCommon_showvars(pDbgc);
     1255                testCommon_stop(pDbgc);
     1256                testCommon_unloadplugin(pDbgc);
     1257                testCommon_unset(pDbgc);
     1258                testCommon_writecore(pDbgc);
    5831259            }
    584 #endif
    5851260        }
    5861261
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette