VirtualBox

Ignore:
Timestamp:
Dec 2, 2022 1:06:38 AM (2 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
154789
Message:

DBGC: Support multiple commands for a breakpoint. (This code sucks and needs rewriting.)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Debugger/DBGCEval.cpp

    r96407 r97728  
    422422 * @param   fExternal           Whether it's an external name.
    423423 * @param   pszArgs             The start of the arguments (after parenthesis).
    424  * @param   cchArgs             The length for the argument (exclusing
     424 * @param   cchArgs             The length for the argument (excluding
    425425 *                              parentesis).
    426426 * @param   enmCategory         The desired category of the result (ignored).
     
    809809    }
    810810    else
    811         /* plain expression, qutoed string, or using unary operators perhaps with parentheses. */
     811        /* plain expression, quoted string, or using unary operators perhaps with parentheses. */
    812812        rc = dbgcEvalSubUnary(pDbgc, pszExpr, cchExpr, enmCategory, pResult);
    813813
     
    13361336int dbgcEvalCommand(PDBGC pDbgc, char *pszCmd, size_t cchCmd, bool fNoExecute)
    13371337{
     1338    Assert(RTStrNLen(pszCmd, cchCmd) == cchCmd);
    13381339    char *pszCmdInput = pszCmd;
    13391340
     
    13501351
    13511352    /*
    1352      * Find arguments.
    1353      */
    1354     char *pszArgs = pszCmd;
    1355     while (RT_C_IS_ALNUM(*pszArgs) || *pszArgs == '_')
    1356         pszArgs++;
    1357     if (   (*pszArgs && !RT_C_IS_BLANK(*pszArgs))
    1358         || !RT_C_IS_ALPHA(*pszCmd))
    1359     {
    1360         DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "Syntax error: Invalid command '%s'!\n", pszCmdInput);
    1361         return pDbgc->rcCmd = VERR_DBGC_PARSE_INVALD_COMMAND_NAME;
     1353     * Find the end of the command name.
     1354     */
     1355    size_t cchName = 0;
     1356    while (cchName < cchCmd)
     1357    {
     1358        char const ch = pszCmd[cchName];
     1359        if (RT_C_IS_ALNUM(ch) || ch == '_')
     1360            cchName++;
     1361        else if (RT_C_IS_SPACE(ch))
     1362            break;
     1363        else
     1364        {
     1365            DBGCCmdHlpPrintf(&pDbgc->CmdHlp, "Syntax error: Invalid command '%s'!\n", pszCmdInput);
     1366            return pDbgc->rcCmd = VERR_DBGC_PARSE_INVALD_COMMAND_NAME;
     1367        }
    13621368    }
    13631369
     
    13651371     * Find the command.
    13661372     */
    1367     PCDBGCCMD pCmd = dbgcCommandLookup(pDbgc, pszCmd, pszArgs - pszCmd, fExternal);
     1373    PCDBGCCMD pCmd = dbgcCommandLookup(pDbgc, pszCmd, cchName, fExternal);
    13681374    if (!pCmd)
    13691375    {
     
    13741380    /*
    13751381     * Parse arguments (if any).
    1376      */
     1382     *
     1383     * If the input isn't zero terminated, we have to make a copy because the
     1384     * argument parser code is to crappy to deal with sub-strings at present.
     1385     */
     1386    size_t offArgs = cchName;
     1387    while (offArgs < cchCmd && RT_C_IS_SPACE(pszCmd[offArgs]))
     1388        offArgs++;
     1389
     1390    char  szEmpty[]   = "";
     1391    char *pszArgsFree = NULL;
     1392    char *pszArgs     = offArgs < cchCmd ? &pszCmd[offArgs] : szEmpty;
     1393    if (pszArgs[cchCmd - offArgs] != '\0')
     1394    {
     1395        /** @todo rewrite the code so it doesn't require modifiable input! */
     1396        pszArgsFree = pszArgs = (char *)RTMemDupEx(pszArgs, cchCmd - offArgs, 1);
     1397        AssertReturn(pszArgs, VERR_NO_MEMORY);
     1398    }
     1399
    13771400    unsigned iArg;
    13781401    unsigned cArgs;
     
    14911514    }
    14921515
     1516    RTMemFree(pszArgsFree);
    14931517    return rc;
     1518}
     1519
     1520
     1521/**
     1522 * Evaluate one or commands separated by ';' or '\n'.
     1523 *
     1524 * @returns VBox status code. This is also stored in DBGC::rcCmd.
     1525 *
     1526 * @param   pDbgc       Debugger console instance data.
     1527 * @param   pszCmd      Pointer to the command.
     1528 * @param   cchCmd      Length of the command.
     1529 * @param   fNoExecute  Indicates that no commands should actually be executed.
     1530 */
     1531int dbgcEvalCommands(PDBGC pDbgc, char *pszCmds, size_t cchCmds, bool fNoExecute)
     1532{
     1533    /*
     1534     * Trim the input.
     1535     */
     1536    while (cchCmds > 0 && RT_C_IS_SPACE(pszCmds[cchCmds]))
     1537        cchCmds--;
     1538    while (cchCmds > 0 && RT_C_IS_SPACE(*pszCmds))
     1539        cchCmds--, pszCmds++;
     1540
     1541    /*
     1542     * Split up the commands and pass them to dbgcEvalCommand.
     1543     */
     1544    int    rcRet    = VINF_SUCCESS;
     1545    char   chQuote  = 0;
     1546    size_t offStart = 0;
     1547    size_t off      = 0;
     1548    while (off < cchCmds)
     1549    {
     1550        char const ch = pszCmds[off];
     1551        if (ch == '"' || ch == '\'')
     1552            chQuote = ch == chQuote ? 0 : chQuote == 0 ? ch : chQuote;
     1553        else if (ch == ';' || ch == '\n')
     1554        {
     1555            /* Skip leading blanks and ignore empty commands. */
     1556            while (offStart < off && RT_C_IS_SPACE(pszCmds[offStart]))
     1557                offStart++;
     1558            if (off > offStart)
     1559            {
     1560                int rc = dbgcEvalCommand(pDbgc, &pszCmds[offStart], off - offStart, fNoExecute);
     1561                if (rcRet == VINF_SUCCESS || (RT_SUCCESS(rcRet) && RT_FAILURE(rc)))
     1562                    rcRet = rc;
     1563                if (   rc == VERR_DBGC_QUIT
     1564                    || rc == VWRN_DBGC_CMD_PENDING)
     1565                    break;
     1566            }
     1567            offStart = ++off;
     1568            continue;
     1569        }
     1570        off++;
     1571    }
     1572
     1573    /*
     1574     * Pending command?
     1575     *
     1576     * No need to skip leading blanks here in order to check for empty
     1577     * commands, since we've already trimmed off tailing blanks.)
     1578     */
     1579    if (off > offStart)
     1580    {
     1581        int rc = dbgcEvalCommand(pDbgc, &pszCmds[offStart], off - offStart, fNoExecute);
     1582        if (rcRet == VINF_SUCCESS || (RT_SUCCESS(rcRet) && RT_FAILURE(rc)))
     1583            rcRet = rc;
     1584    }
     1585
     1586    return rcRet;
    14941587}
    14951588
Note: See TracChangeset for help on using the changeset viewer.

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