VirtualBox

Changeset 41209 in vbox for trunk


Ignore:
Timestamp:
May 8, 2012 3:03:48 PM (13 years ago)
Author:
vboxsync
Message:

Good enough for vm.h.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bldprogs/VBoxCPP.cpp

    r41204 r41209  
    101101    /** Lead character bitmap for the argument names. */
    102102    VBCPP_BITMAP_TYPE   bmArgs[VBCPP_BITMAP_SIZE];
     103    /** The value length. */
     104    size_t              cchValue;
    103105    /** The define value.  (This is followed by the name and arguments.) */
    104106    char                szValue[1];
     
    932934
    933935/**
     936 * Looks up a define.
     937 *
     938 * @returns Pointer to the define if found, NULL if not.
     939 * @param   pThis               The C preprocessor instance.
     940 * @param   pszDefine           The define name and optionally the argument
     941 *                              list.
     942 * @param   cchDefine           The length of the name. RTSTR_MAX is ok.
     943 */
     944static PVBCPPDEF vbcppDefineLookup(PVBCPP pThis, const char *pszDefine, size_t cchDefine)
     945{
     946    if (!cchDefine)
     947        return NULL;
     948    if (!VBCPP_BITMAP_IS_SET(pThis->bmDefined, *pszDefine))
     949        return NULL;
     950    return (PVBCPPDEF)RTStrSpaceGetN(&pThis->StrSpace, pszDefine, cchDefine);
     951}
     952
     953
     954/**
    934955 * Frees a define.
    935956 *
     
    9941015static RTEXITCODE vbcppDefineInsert(PVBCPP pThis, PVBCPPDEF pDef)
    9951016{
     1017    /*
     1018     * Reject illegal macro names.
     1019     */
     1020    if (!strcmp(pDef->Core.pszString, "defined"))
     1021    {
     1022        RTEXITCODE rcExit = vbcppError(pThis, "Cannot use '%s' as a macro name", pDef->Core.pszString);
     1023        vbcppFreeDefine(&pDef->Core, NULL);
     1024        return rcExit;
     1025    }
     1026
    9961027    /*
    9971028     * Ignore in source-file defines when doing selective preprocessing.
     
    11211152    pDef->papszArgs = (const char **)((uintptr_t)pDef + cbDef - sizeof(const char *) * cArgs);
    11221153    VBCPP_BITMAP_EMPTY(pDef->bmArgs);
     1154    pDef->cchValue  = cchValue;
    11231155    memcpy(pDef->szValue, pszValue, cchValue);
    11241156    pDef->szValue[cchValue] = '\0';
     
    12311263    pDef->papszArgs = NULL;
    12321264    VBCPP_BITMAP_EMPTY(pDef->bmArgs);
     1265    pDef->cchValue  = cchValue;
    12331266    memcpy(pDef->szValue, pszValue, cchValue);
    12341267    pDef->szValue[cchValue] = '\0';
     
    13091342                        ScmStreamSeekByLine(pStrmInput, ScmStreamTellLine(pStrmInput) + 1);
    13101343                    }
    1311                     ScmStreamGetCh(pStrmInput);
     1344                    chPrev = ScmStreamGetCh(pStrmInput);
    13121345                }
    13131346                size_t cchValue = ScmStreamGetCur(pStrmInput) - pchValue;
     
    14611494
    14621495
     1496#if 0
     1497typedef enum VBCPPEXPRKIND
     1498{
     1499    kVBCppExprKind_Invalid = 0,
     1500    kVBCppExprKind_Binary,
     1501    kVBCppExprKind_Unary,
     1502    kVBCppExprKind_SignedValue,
     1503    kVBCppExprKind_UnsignedValue,
     1504    kVBCppExprKind_Define,
     1505    kVBCppExprKind_End
     1506} VBCPPEXPRKIND;
     1507
     1508typedef struct VBCPPEXPR *PVBCPPEXPR;
     1509
     1510/**
     1511 * Expression parsing structure.
     1512 */
     1513typedef struct VBCPPEXPR
     1514{
     1515    /** Pointer to the first byte of the expression. */
     1516    const char         *pchExpr;
     1517    /** The length of the expression. */
     1518    size_t              cchExpr;
     1519
     1520    uint32_t            iDepth;
     1521    /** The kind of expression. */
     1522    VBCPPEXPRKIND       enmKind;
     1523    /** */
     1524    union
     1525    {
     1526        struct
     1527        {
     1528            VBCPPUNARYOP    enmOperator;
     1529            PVBCPPEXPR      pArg;
     1530        } Unary;
     1531
     1532        struct
     1533        {
     1534            VBCPPBINARYOP   enmOperator;
     1535            PVBCPPEXPR      pLeft;
     1536            PVBCPPEXPR      pRight;
     1537        } Binary;
     1538
     1539        struct
     1540        {
     1541            int64_t         s64;
     1542            unsigned        cBits;
     1543        } SignedValue;
     1544
     1545        struct
     1546        {
     1547            uint64_t        u64;
     1548            unsigned        cBits;
     1549        } UnsignedValue;
     1550
     1551        struct
     1552        {
     1553            const char     *pch;
     1554            size_t          cch;
     1555        } Define;
     1556
     1557    } u;
     1558    /** Parent expression. */
     1559    PVBCPPEXPR          pParent;
     1560} VBCPPEXPR;
     1561
     1562
     1563
     1564typedef struct VBCPPEXPRPARSER
     1565{
     1566    PVBCPPEXPR          pStack
     1567} VBCPPEXPRPARSER;
     1568
     1569
     1570/**
     1571 * Operator return statuses.
     1572 */
     1573typedef enum
     1574{
     1575    kExprRet_Error = -1,
     1576    kExprRet_Ok = 0,
     1577    kExprRet_Operator,
     1578    kExprRet_Operand,
     1579    kExprRet_EndOfExpr,
     1580    kExprRet_End
     1581} VBCPPEXPRRET;
     1582
     1583
     1584static VBCPPEXPRRET vbcppExprEatUnaryOrOperand(PVBCPPEXPRPARSER pThis, PSCMSTREAM pStrmInput)
     1585{
     1586
     1587}
     1588
     1589#endif
     1590
     1591
     1592/**
     1593 * Evalutes the expression.
     1594 *
     1595 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
     1596 * @param   pThis               The C preprocessor instance.
     1597 * @param   pszExpr             The expression.
     1598 * @param   cchExpr             The length of the expression.
     1599 * @param   penmResult          Where to store the result.
     1600 */
     1601static RTEXITCODE vbcppExprEval(PVBCPP pThis, char *pszExpr, size_t cchExpr, VBCPPEVAL *penmResult)
     1602{
     1603    Assert(strlen(pszExpr) == cchExpr);
     1604#if 0
     1605    /** @todo */
     1606#else           /* Greatly simplified for getting DTrace working. */
     1607    RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
     1608    if (strcmp(pszExpr, "1"))
     1609        *penmResult = kVBCppEval_True;
     1610    else if (strcmp(pszExpr, "0"))
     1611        *penmResult = kVBCppEval_False;
     1612    else if (pThis->fUndecidedConditionals)
     1613        *penmResult = kVBCppEval_Undecided;
     1614    else
     1615        rcExit = vbcppError(pThis, "Too compliated expression '%s'", pszExpr);
     1616#endif
     1617    return rcExit;
     1618}
     1619
     1620
     1621/**
     1622 * Expands known macros in the expression.
     1623 *
     1624 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
     1625 * @param   pThis               The C preprocessor instance.
     1626 * @param   ppszExpr            The expression to expand. Input/Output.
     1627 * @param   pcchExpr            The length of the expression. Input/Output.
     1628 * @param   pcReplacements      Where to store the number of replacements made.
     1629 *                              Optional.
     1630 */
     1631static RTEXITCODE vbcppExprExpand(PVBCPP pThis, char **ppszExpr, size_t *pcchExpr, size_t *pcReplacements)
     1632{
     1633    RTEXITCODE  rcExit      = RTEXITCODE_SUCCESS;
     1634    char       *pszExpr     = *ppszExpr;
     1635    size_t      cchExpr     = pcchExpr ? *pcchExpr :  strlen(pszExpr);
     1636    size_t      cbExprAlloc = cchExpr + 1;
     1637    size_t      cHits       = 0;
     1638    size_t      off         = 0;
     1639    char        ch;
     1640    while ((ch = pszExpr[off]) != '\0')
     1641    {
     1642        if (!vbcppIsCIdentifierLeadChar(ch))
     1643            off++;
     1644        else
     1645        {
     1646            /* Extract the identifier. */
     1647            size_t const offIdentifier = off++;
     1648            while (   off < cchExpr
     1649                   && vbcppIsCIdentifierChar(pszExpr[off]))
     1650                off++;
     1651            size_t const cchIdentifier = off - offIdentifier;
     1652
     1653            /* Does it exist?  Will save a whole lot of trouble if it doesn't. */
     1654            PVBCPPDEF pDef = vbcppDefineLookup(pThis, &pszExpr[offIdentifier], cchIdentifier);
     1655            if (pDef)
     1656            {
     1657                /* Skip white space and check for parenthesis. */
     1658                while (   off < cchExpr
     1659                       && RT_C_IS_SPACE(pszExpr[off]))
     1660                    off++;
     1661                if (   off < cchExpr
     1662                    && pszExpr[off] == '(')
     1663                {
     1664                    /* Try expand function define. */
     1665                    rcExit = vbcppError(pThis, "Expanding function macros is not yet implemented");
     1666                    break;
     1667                }
     1668                else
     1669                {
     1670                    /* Expand simple define if found. */
     1671                    if (pDef->cchValue + 2 < cchIdentifier)
     1672                    {
     1673                        size_t offDelta = cchIdentifier - pDef->cchValue - 2;
     1674                        memmove(&pszExpr[offIdentifier], &pszExpr[offIdentifier + offDelta],
     1675                                cchExpr - offIdentifier - offDelta + 1); /* Lazy bird is moving too much! */
     1676                        cchExpr -= offDelta;
     1677                    }
     1678                    else if (pDef->cchValue + 2 > cchIdentifier)
     1679                    {
     1680                        size_t offDelta = pDef->cchValue + 2 - cchIdentifier;
     1681                        if (cchExpr + offDelta + 1 > cbExprAlloc)
     1682                        {
     1683                            do
     1684                            {
     1685                                cbExprAlloc *= 2;
     1686                            } while (cchExpr + offDelta + 1 > cbExprAlloc);
     1687                            void *pv = RTMemRealloc(pszExpr,  cbExprAlloc);
     1688                            if (!pv)
     1689                            {
     1690                                rcExit = vbcppError(pThis, "out of memory (%zu bytes)", cbExprAlloc);
     1691                                break;
     1692                            }
     1693                            pszExpr = (char *)pv;
     1694                        }
     1695                        memmove(&pszExpr[offIdentifier + offDelta], &pszExpr[offIdentifier],
     1696                                cchExpr - offIdentifier + 1); /* Lazy bird is moving too much! */
     1697                        cchExpr += offDelta;
     1698                    }
     1699
     1700                    /* Insert with spaces around it. Not entirely sure how
     1701                       standard compliant this is... */
     1702                    pszExpr[offIdentifier] = ' ';
     1703                    memcpy(&pszExpr[offIdentifier + 1], pDef->szValue, pDef->cchValue);
     1704                    pszExpr[offIdentifier + 1 + pDef->cchValue] = ' ';
     1705
     1706                    /* Restart parsing at the inserted macro. */
     1707                    off = offIdentifier + 1;
     1708                }
     1709            }
     1710        }
     1711    }
     1712
     1713    return rcExit;
     1714}
     1715
     1716
     1717
     1718/**
     1719 * Extracts the expression.
     1720 *
     1721 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg.
     1722 * @param   pThis               The C preprocessor instance.
     1723 * @param   pStrmInput          The input stream.
     1724 * @param   ppszExpr            Where to return the expression string..
     1725 * @param   pcchExpr            Where to return the expression length.
     1726 *                              Optional.
     1727 * @param   poffComment         Where to note down the position of the final
     1728 *                              comment. Optional.
     1729 */
     1730static RTEXITCODE vbcppExprExtract(PVBCPP pThis, PSCMSTREAM pStrmInput,
     1731                                   char **ppszExpr, size_t *pcchExpr, size_t *poffComment)
     1732{
     1733    RTEXITCODE  rcExit      = RTEXITCODE_SUCCESS;
     1734    size_t      cbExprAlloc = 0;
     1735    size_t      cchExpr     = 0;
     1736    char       *pszExpr     = NULL;
     1737    bool        fInComment  = false;
     1738    size_t      offComment  = ~(size_t)0;
     1739    unsigned    chPrev      = 0;
     1740    unsigned    ch;
     1741    while ((ch = ScmStreamPeekCh(pStrmInput)) != ~(unsigned)0)
     1742    {
     1743        if (ch == '\r' || ch == '\n')
     1744        {
     1745            if (chPrev == '\\')
     1746            {
     1747                ScmStreamSeekByLine(pStrmInput, ScmStreamTellLine(pStrmInput) + 1);
     1748                pszExpr[--cchExpr] = '\0';
     1749                continue;
     1750            }
     1751            if (!fInComment)
     1752                break;
     1753            /* The expression continues after multi-line comments. Cool. :-) */
     1754        }
     1755        else if (!fInComment)
     1756        {
     1757            if (chPrev == '/' && ch == '*' )
     1758            {
     1759                pszExpr[--cchExpr] = '\0';
     1760                fInComment = true;
     1761                offComment = ScmStreamTell(pStrmInput) - 1;
     1762            }
     1763            else if (chPrev == '/' && ch == '/')
     1764            {
     1765                offComment = ScmStreamTell(pStrmInput) - 1;
     1766                rcExit = vbcppProcessSkipWhiteEscapedEolAndComments(pThis, pStrmInput);
     1767                break;                  /* done */
     1768            }
     1769            /* Append the char to the expression. */
     1770            else
     1771            {
     1772                if (cchExpr + 2 > cbExprAlloc)
     1773                {
     1774                    cbExprAlloc = cbExprAlloc ? cbExprAlloc * 2 : 8;
     1775                    void *pv = RTMemRealloc(pszExpr, cbExprAlloc);
     1776                    if (!pv)
     1777                    {
     1778                        rcExit = vbcppError(pThis, "out of memory (%zu bytes)", cbExprAlloc);
     1779                        break;
     1780                    }
     1781                    pszExpr = (char *)pv;
     1782                }
     1783                pszExpr[cchExpr++] = ch;
     1784                pszExpr[cchExpr]   = '\0';
     1785            }
     1786        }
     1787        else if (ch == '/' && chPrev == '*')
     1788            fInComment = false;
     1789
     1790        /* advance */
     1791        chPrev = ch;
     1792        ch = ScmStreamGetCh(pStrmInput); Assert(ch == chPrev);
     1793    }
     1794
     1795    if (rcExit == RTEXITCODE_SUCCESS)
     1796    {
     1797        *ppszExpr = pszExpr;
     1798        if (pcchExpr)
     1799            *pcchExpr = cchExpr;
     1800        if (poffComment)
     1801            *poffComment;
     1802    }
     1803    else
     1804        RTMemFree(pszExpr);
     1805    return rcExit;
     1806}
     1807
     1808
    14631809/**
    14641810 * Processes a abbreviated line number directive.
     
    14691815 * @param   offStart            The stream position where the directive
    14701816 *                              started (for pass thru).
    1471  */
    1472 static RTEXITCODE vbcppProcessIf(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
    1473 {
    1474     return vbcppError(pThis, "Not implemented %s", __FUNCTION__);
     1817 * @param   enmKind             The kind of directive we're processing.
     1818 */
     1819static RTEXITCODE vbcppProcessIfOrElif(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart,
     1820                                       VBCPPCONDKIND enmKind)
     1821{
     1822    /*
     1823     * Check for missing #if if #elif.
     1824     */
     1825    if (   enmKind == kVBCppCondKind_ElIf
     1826        && !pThis->pCondStack )
     1827        return vbcppError(pThis, "#elif without #if");
     1828
     1829    /*
     1830     * Extract and expand the expression string.
     1831     */
     1832    const char *pchCondition = ScmStreamGetCur(pStrmInput);
     1833    char       *pszExpr;
     1834    size_t      cchExpr;
     1835    size_t      offComment;
     1836    RTEXITCODE  rcExit = vbcppExprExtract(pThis, pStrmInput, &pszExpr, &cchExpr, &offComment);
     1837    if (rcExit == RTEXITCODE_SUCCESS)
     1838    {
     1839        size_t const    cchCondition = ScmStreamGetCur(pStrmInput) - pchCondition;
     1840        size_t          cReplacements;
     1841        rcExit = vbcppExprExpand(pThis, &pszExpr, &cchExpr, &cReplacements);
     1842        if (rcExit == RTEXITCODE_SUCCESS)
     1843        {
     1844            /*
     1845             * Strip it and check that it's not empty.
     1846             */
     1847            char *pszExpr2 = pszExpr;
     1848            while (cchExpr > 0 && RT_C_IS_SPACE(*pszExpr2))
     1849                pszExpr2++, cchExpr--;
     1850
     1851            while (cchExpr > 0 && RT_C_IS_SPACE(pszExpr2[cchExpr - 1]))
     1852                pszExpr2[--cchExpr] = '\0';
     1853            if (cchExpr)
     1854            {
     1855                /*
     1856                 * Now, evalute the expression.
     1857                 */
     1858                VBCPPEVAL enmResult;
     1859                rcExit = vbcppExprEval(pThis, pszExpr2, cchExpr, &enmResult);
     1860                if (rcExit == RTEXITCODE_SUCCESS)
     1861                {
     1862                    /*
     1863                     * Take action.
     1864                     */
     1865                    if (enmKind != kVBCppCondKind_ElIf)
     1866                        rcExit = vbcppCondPush(pThis, pStrmInput, offComment, enmKind, enmResult,
     1867                                               pchCondition, cchCondition);
     1868                    else
     1869                    {
     1870                        PVBCPPCOND pCond = pThis->pCondStack;
     1871                        if (   pCond->enmResult != kVBCppEval_Undecided
     1872                            && (   !pCond->pUp
     1873                                || pCond->pUp->enmStackResult == kVBCppEval_True))
     1874                        {
     1875                            if (enmResult == kVBCppEval_True)
     1876                                pCond->enmStackResult = kVBCppEval_False;
     1877                            else
     1878                                pCond->enmStackResult = kVBCppEval_True;
     1879                            pThis->fIf0Mode = pCond->enmStackResult == kVBCppEval_False;
     1880                        }
     1881                        pCond->enmResult = enmResult;
     1882                        pCond->pchCond   = pchCondition;
     1883                        pCond->cchCond   = cchCondition;
     1884
     1885                        /*
     1886                         * Do #elif pass thru.
     1887                         */
     1888                        if (   !pThis->fIf0Mode
     1889                            && pCond->enmResult == kVBCppEval_Undecided)
     1890                        {
     1891                            ssize_t cch = ScmStreamPrintf(&pThis->StrmOutput, "#%*selif", pCond->iKeepLevel - 1, "");
     1892                            if (cch > 0)
     1893                                rcExit = vbcppOutputComment(pThis, pStrmInput, offStart, cch, 2);
     1894                            else
     1895                                rcExit = vbcppError(pThis, "Output error %Rrc", (int)cch);
     1896                        }
     1897                    }
     1898                }
     1899            }
     1900            else
     1901                rcExit = vbcppError(pThis, "Empty #if expression");
     1902        }
     1903        RTMemFree(pszExpr);
     1904    }
     1905    return rcExit;
    14751906}
    14761907
     
    15061937                if (vbcppDefineExists(pThis, pchDefine, cchDefine))
    15071938                    enmEval = kVBCppEval_True;
    1508                 else if (   pThis->fUndecidedConditionals
     1939                else if (   !pThis->fUndecidedConditionals
    15091940                         || RTStrSpaceGetN(&pThis->UndefStrSpace, pchDefine, cchDefine) != NULL)
    15101941                    enmEval = kVBCppEval_False;
     
    15521983                if (vbcppDefineExists(pThis, pchDefine, cchDefine))
    15531984                    enmEval = kVBCppEval_False;
    1554                 else if (   pThis->fUndecidedConditionals
     1985                else if (   !pThis->fUndecidedConditionals
    15551986                         || RTStrSpaceGetN(&pThis->UndefStrSpace, pchDefine, cchDefine) != NULL)
    15561987                    enmEval = kVBCppEval_True;
     
    18872318#define IS_DIRECTIVE(a_sz) ( sizeof(a_sz) - 1 == cchDirective && strncmp(pchDirective, a_sz, sizeof(a_sz) - 1) == 0)
    18882319        if (IS_DIRECTIVE("if"))
    1889             rcExit = vbcppProcessIf(pThis, pStrmInput, offStart);
     2320            rcExit = vbcppProcessIfOrElif(pThis, pStrmInput, offStart, kVBCppCondKind_If);
     2321        else if (IS_DIRECTIVE("elif"))
     2322            rcExit = vbcppProcessIfOrElif(pThis, pStrmInput, offStart, kVBCppCondKind_ElIf);
    18902323        else if (IS_DIRECTIVE("ifdef"))
    18912324            rcExit = vbcppProcessIfDef(pThis, pStrmInput, offStart);
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