VirtualBox

Changeset 100618 in vbox for trunk/src/bldprogs


Ignore:
Timestamp:
Jul 18, 2023 12:27:58 AM (21 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
158449
Message:

VBoxCPP: Some fun over the weekend.

Location:
trunk/src/bldprogs
Files:
3 edited

Legend:

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

    r100555 r100618  
    200200    kVBCppExprKind_SignedValue,
    201201    kVBCppExprKind_UnsignedValue,
     202    kVBCppExprKind_UndefMacroCall,
    202203    kVBCppExprKind_End
    203204} VBCPPEXPRKIND;
     
    308309            uint64_t        u64;
    309310        } UnsignedValue;
     311
     312        /** kVBCppExprKind_UndefMacroCall */
     313        struct
     314        {
     315            char           *pszName;
     316            size_t          cArgs;
     317            PVBCPPEXPR     *papArgs;
     318        } UndefMacroCall;
    310319    } u;
    311320} VBCPPEXPR;
     
    470479    /** Whether to pass thru other pragmas. */
    471480    bool                fPassThruPragmaOther;
     481    /** Whether to pass thru \#error directives or execute them. */
     482    bool                fPassThruError;
    472483    /** Whether to remove dropped lines from the output. */
    473484    bool                fRemoveDroppedLines;
     
    532543*   Internal Functions                                                                                                           *
    533544*********************************************************************************************************************************/
     545static VBCPPEXPRRET vbcppExprParseUnaryOrValue(PVBCPPEXPRPARSER pParser);
    534546static PVBCPPMACRO  vbcppMacroLookup(PVBCPP pThis, const char *pszDefine, size_t cchDefine);
    535547static RTEXITCODE   vbcppMacroExpandIt(PVBCPP pThis, PVBCPPMACROEXP pExp, size_t offMacro, PVBCPPMACRO pMacro, size_t offParameters);
    536 static RTEXITCODE   vbcppMacroExpandReScan(PVBCPP pThis, PVBCPPMACROEXP pExp, VBCPPMACRORESCANMODE enmMode, size_t *pcReplacements);
     548static RTEXITCODE   vbcppMacroExpandReScan(PVBCPP pThis, PVBCPPMACROEXP pExp, VBCPPMACRORESCANMODE enmMode,
     549                                           size_t *pcReplacements, size_t *pcDefinedUnknown);
    537550static void         vbcppMacroExpandCleanup(PVBCPPMACROEXP pExp);
    538551
     
    622635    va_list va;
    623636    va_start(va, pszMsg);
    624     RTMsgErrorV(pszMsg, va);
     637    //RTMsgErrorV(pszMsg, va);
     638    RTEXITCODE rcExit = vbcppErrorV(pThis, pszMsg, va);
    625639    va_end(va);
    626     return pThis->rcExit = RTEXITCODE_FAILURE;
     640    return rcExit;
    627641}
    628642
     
    15931607            rcExit = vbcppMacroExpandIt(pThis, &ExpCtx, 0 /* offset */, pMacro, cchDefine);
    15941608        if (rcExit == RTEXITCODE_SUCCESS)
    1595             rcExit = vbcppMacroExpandReScan(pThis, &ExpCtx, kMacroReScanMode_Normal, NULL);
     1609            rcExit = vbcppMacroExpandReScan(pThis, &ExpCtx, kMacroReScanMode_Normal, NULL, NULL);
    15961610        if (rcExit == RTEXITCODE_SUCCESS)
    15971611        {
     
    23922406 * @param   pcReplacements      Where to return the number of replacements
    23932407 *                              performed.  Optional.
    2394  */
    2395 static RTEXITCODE vbcppMacroExpandReScan(PVBCPP pThis, PVBCPPMACROEXP pExp, VBCPPMACRORESCANMODE enmMode, size_t *pcReplacements)
    2396 {
    2397     RTEXITCODE  rcExit        = RTEXITCODE_SUCCESS;
    2398     size_t      cReplacements = 0;
    2399     size_t      off           = 0;
     2408 * @param   pcDefinedUnknown    Where to return the number of defined() checks
     2409 *                              on unknown macros.  Optional.
     2410 */
     2411static RTEXITCODE vbcppMacroExpandReScan(PVBCPP pThis, PVBCPPMACROEXP pExp, VBCPPMACRORESCANMODE enmMode,
     2412                                         size_t *pcReplacements, size_t *pcDefinedUnknown)
     2413{
     2414    RTEXITCODE  rcExit          = RTEXITCODE_SUCCESS;
     2415    size_t      cReplacements   = 0;
     2416    size_t      cDefinedUnknown = 0;
     2417    size_t      off             = 0;
    24002418    unsigned    ch;
    24012419    while (   off < pExp->StrBuf.cchBuf
     
    24672485                {
    24682486                    cReplacements++;
     2487                    cDefinedUnknown++;
    24692488                    rcExit = vbcppMacroExpandDefinedOperator(pThis, pExp, offDefine, &off);
    24702489                }
     
    24822501    if (pcReplacements)
    24832502        *pcReplacements = cReplacements;
     2503    if (pcDefinedUnknown)
     2504        *pcDefinedUnknown = cDefinedUnknown;
    24842505    return rcExit;
    24852506}
     
    26672688     * requires.  Performing syntax validation while parsing.
    26682689     */
    2669     uint32_t cchArgNames = 0;
     2690    bool     fVariadic   = false;
     2691    size_t   cchArgNames = 0;
    26702692    uint32_t cArgs       = 0;
    26712693    for (size_t off = 0; off < cchParams; off++)
     
    26752697        while (off < cchParams)
    26762698        {
    2677             if (!RT_C_IS_SPACE(pszParams[off]))
     2699            if (   !RT_C_IS_SPACE(pszParams[off])
     2700                && (   pszParams[off] != '\\'
     2701                    || (pszParams[off + 1] != '\n' && pszParams[off + 1] != '\r')))
    26782702            {
    26792703                if (pszParams[off] != ',' || !fIgnoreComma)
     
    26812705                    if (vbcppIsCIdentifierLeadChar(pszParams[off]))
    26822706                        break;
    2683                     /** @todo variadic macros. */
    2684                     return vbcppErrorPos(pThis, &pszParams[off], "Unexpected character");
     2707
     2708                    /* Check for variadic macro argument, just parsing it for now. */
     2709                    if (   pszParams[off]     == '.'
     2710                        && off + 3 <= cchParams
     2711                        && pszParams[off + 1] == '.'
     2712                        && pszParams[off + 2] == '.')
     2713                    {
     2714                        size_t const offSaved = off;
     2715                        off += 3;
     2716                        while (off < cchParams && RT_C_IS_SPACE(pszParams[off]))
     2717                            off++;
     2718                        if (off == cchParams)
     2719                        {
     2720                            cArgs++;
     2721                            cchArgNames += sizeof("...");
     2722                            fVariadic = true;
     2723                            break;
     2724                        }
     2725                        off = offSaved;
     2726                    }
     2727                    return vbcppErrorPos(pThis, &pszParams[off], "Unexpected character (%#x, off=%zu)", pszParams[off], off);
    26852728                }
    26862729                fIgnoreComma = false;
     
    27162759    *pszDst++ = '\0';
    27172760    pMacro->fFunction   = true;
    2718     pMacro->fVarArg     = false;
     2761    pMacro->fVarArg     = fVariadic;
    27192762    pMacro->fCmdLine    = fCmdLine;
    27202763    pMacro->fExpanding  = false;
     
    27362779        while (off < cchParams)
    27372780        {
    2738             if (!RT_C_IS_SPACE(pszParams[off]))
     2781            if (   !RT_C_IS_SPACE(pszParams[off])
     2782                && (   pszParams[off] != '\\'
     2783                    || (pszParams[off + 1] != '\n' && pszParams[off + 1] != '\r')))
    27392784            {
    27402785                if (pszParams[off] != ',' || !fIgnoreComma)
     
    27482793
    27492794        /* Found and argument. First character is already validated. */
    2750         VBCPP_BITMAP_SET(pMacro->bmArgs, pszParams[off]);
    27512795        pMacro->papszArgs[iArg] = pszDst;
    2752         do
    2753         {
    2754             *pszDst++ = pszParams[off++];
    2755         } while (   off < cchParams
    2756                  && vbcppIsCIdentifierChar(pszParams[off]));
     2796        if (!fVariadic || iArg + 1 < cArgs)
     2797        {
     2798            VBCPP_BITMAP_SET(pMacro->bmArgs, pszParams[off]);
     2799            do
     2800            {
     2801                *pszDst++ = pszParams[off++];
     2802            } while (   off < cchParams
     2803                     && vbcppIsCIdentifierChar(pszParams[off]));
     2804        }
     2805        else
     2806        {
     2807            Assert(strncmp(&pszParams[off], "...", 3) == 0);
     2808            VBCPP_BITMAP_SET(pMacro->bmArgs, '_'); /* __VA_ARGS__ */
     2809            off += 3;
     2810            *pszDst++ = '.';
     2811            *pszDst++ = '.';
     2812            *pszDst++ = '.';
     2813        }
    27572814        *pszDst++ = '\0';
    27582815        iArg++;
     
    30323089                        break;
    30333090                    }
     3091                    chPrev = ch;
    30343092                    ScmStreamGetCh(pStrmInput);
    30353093                }
     
    32313289    pCond->fElIfDecided     = enmResult == kVBCppEval_True;
    32323290    pCond->iLevel           = pThis->cCondStackDepth;
    3233     pCond->iKeepLevel       = (pUp ? pUp->iKeepLevel : 0) + enmResult == kVBCppEval_Undecided;
     3291    pCond->iKeepLevel       = (pUp ? pUp->iKeepLevel : 0) + (enmResult == kVBCppEval_Undecided);
    32343292    pCond->pchCond          = pchCondition;
    32353293    pCond->cchCond          = cchCondition;
     
    32943352        case kVBCppExprKind_UnsignedValue:
    32953353            break;
     3354        case kVBCppExprKind_UndefMacroCall:
     3355            pExpr->u.UndefMacroCall.pszName = NULL;
     3356            for (size_t i = 0; i < pExpr->u.UndefMacroCall.cArgs; i++)
     3357                vbcppExprDestoryTree(pExpr->u.UndefMacroCall.papArgs[i]);
     3358            RTMemFree(pExpr->u.UndefMacroCall.papArgs);
     3359            RTMemFree(pExpr->u.UndefMacroCall.pszName);
     3360            break;
    32963361        default:
    32973362            AssertFailed();
     
    33483413
    33493414/**
    3350  * Looks for right parentheses and/or end of expression.
     3415 * Checks if we're currently in an call to an undefined macro.
     3416 *
     3417 * This will walk up the expression chain and check for a call node while also
     3418 * taking parenthesis nodes into account.
     3419 *
     3420 * @returns true if we are, false if we aren't.
     3421 * @param   pParser             The parser instance.
     3422 */
     3423static bool vbcppExprParseIsInUndefCall(PVBCPPEXPRPARSER pParser)
     3424{
     3425    PVBCPPEXPR pExpr = pParser->pCur;
     3426    while (pExpr)
     3427    {
     3428        if (pExpr->enmKind == kVBCppExprKind_UndefMacroCall)
     3429            return true;
     3430        if (   pExpr->enmKind == kVBCppExprKind_Unary
     3431            && pExpr->u.Unary.enmOperator == kVBCppUnaryOp_Parenthesis)
     3432               break;
     3433        pExpr = pExpr->pParent;
     3434    }
     3435    return false;
     3436}
     3437
     3438
     3439/**
     3440 * Looks for right parentheses, comma and/or end of expression.
     3441 *
     3442 * (The comma is only if we're in the context of a undefined macro call.)
    33513443 *
    33523444 * @returns Expression status.
     
    33623454    {
    33633455        vbcppExprParseSkipWhiteSpace(pParser);
    3364         char ch = *pParser->pszCur;
     3456        char const ch = *pParser->pszCur;
    33653457        if (ch == '\0')
    3366             return kExprRet_EndOfExpr;
    3367         if (ch != ')')
     3458        {
     3459            /* Unwind making sure we don't have any incomplete parentheses or
     3460               incomplete call expressions on the stack. */
     3461            PVBCPPEXPR pCur = pParser->pCur;
     3462            Assert(pCur);
     3463            for (;;)
     3464            {
     3465                if (!pCur->fComplete)
     3466                {
     3467                    if (   pCur->enmKind == kVBCppExprKind_Unary
     3468                        && pCur->u.Unary.enmOperator == kVBCppUnaryOp_Parenthesis)
     3469                        return vbcppExprParseError(pParser, "Missing right parenthesis");
     3470                    if (pCur->enmKind == kVBCppExprKind_UndefMacroCall)
     3471                        return vbcppExprParseError(pParser, "Missing right parenthesis for undefined macro call");
     3472                }
     3473                if (pCur->pParent)
     3474                    pCur = pCur->pParent;
     3475                else
     3476                {
     3477                    pParser->pCur  = pCur;
     3478                    pParser->ppCur = NULL;
     3479                    return kExprRet_EndOfExpr;
     3480                }
     3481            }
     3482        }
     3483
     3484        if (ch != ')' && (ch != ',' || !vbcppExprParseIsInUndefCall(pParser))) /** @todo just immediate?  */
    33683485            break;
    33693486        pParser->pszCur++;
     
    33713488        PVBCPPEXPR pCur = pParser->pCur;
    33723489        while (   pCur
     3490               && (   pCur->enmKind != kVBCppExprKind_UndefMacroCall
     3491                   || pCur->fComplete /*?*/)
    33733492               && (   pCur->enmKind != kVBCppExprKind_Unary
    3374                    || pCur->u.Unary.enmOperator != kVBCppUnaryOp_Parenthesis))
     3493                   || pCur->u.Unary.enmOperator != kVBCppUnaryOp_Parenthesis
     3494                   || pCur->fComplete))
    33753495        {
    33763496            switch (pCur->enmKind)
     
    34013521#endif
    34023522                    break;
     3523                case kVBCppExprKind_UndefMacroCall:
     3524                    break;
    34033525                default:
    34043526                    return vbcppExprParseError(pParser, "Internal error (enmKind=%d)", pCur->enmKind);
     
    34083530        if (!pCur)
    34093531            return vbcppExprParseError(pParser, "Right parenthesis without a left one");
     3532
     3533        /*
     3534         * If we got down to an undefined macro call, we make it the current
     3535         * parser expression and return EndOfExpr.  The call expression is
     3536         * completed if we hit a ')'.
     3537         */
     3538        if (pCur->enmKind == kVBCppExprKind_UndefMacroCall)
     3539        {
     3540            pCur->fComplete = ch == ')';
     3541            pParser->pCur  = pCur;
     3542            pParser->ppCur = NULL;
     3543            return kExprRet_EndOfExpr;
     3544        }
     3545
     3546        /*
     3547         * Complete the parenthesis expression and make it current.
     3548         */
     3549        Assert(   pCur->enmKind == kVBCppExprKind_Unary
     3550               && pCur->u.Unary.enmOperator == kVBCppUnaryOp_Parenthesis);
     3551        AssertReturn(pCur->u.Unary.pArg, vbcppExprParseError(pParser, "internal error"));
    34103552        pCur->fComplete = true;
    3411 
    3412         while (   pCur->enmKind == kVBCppExprKind_Unary
    3413                && pCur->u.Unary.enmOperator != kVBCppUnaryOp_Parenthesis
    3414                && pCur->pParent)
    3415         {
    3416             AssertReturn(pCur->u.Unary.pArg, vbcppExprParseError(pParser, "internal error"));
    3417             pCur->fComplete = true;
    3418             pCur = pCur->pParent;
    3419         }
     3553        pParser->pCur  = pCur;
     3554        pParser->ppCur = NULL;
    34203555    }
    34213556
     
    35653700     */
    35663701    PVBCPPEXPR *ppPlace = NULL;
    3567     PVBCPPEXPR  pChild  = NULL;
    3568     PVBCPPEXPR  pParent = pParser->pCur;
     3702    PVBCPPEXPR  pChild  = pParser->pCur;
     3703    PVBCPPEXPR  pParent = pChild->pParent;
    35693704    while (pParent)
    35703705    {
     
    36003735            return vbcppExprParseError(pParser, "The ternary operator is not implemented");
    36013736        }
     3737        else if (pParent->enmKind == kVBCppExprKind_UndefMacroCall)
     3738        {
     3739            ppPlace = &pParent->u.UndefMacroCall.papArgs[pParent->u.UndefMacroCall.cArgs];
     3740            break;
     3741        }
    36023742        else
    36033743            AssertReturn(   pParent->enmKind == kVBCppExprKind_SignedValue
     
    36523792
    36533793/**
     3794 * Worker for vbcppExprParseIdentifier that parses a call to an undefined macro
     3795 * in selective mode.
     3796 *
     3797 * @returns Expression status.
     3798 * @retval  kExprRet_Ok if binary operator was found processed.
     3799 * @retval  kExprRet_Error with msg.
     3800 * @retval  kExprRet_EndOfExpr
     3801 * @param   pParser             The parser instance.
     3802 * @param   pszMacro            The start of the macro name.
     3803 * @param   cchMacro            The length of the macro name.
     3804 */
     3805static VBCPPEXPRRET vbcppExprParseUndefMacroCall(PVBCPPEXPRPARSER pParser, const char *pszMacro, size_t cchMacro)
     3806{
     3807    /*
     3808     * Treat it as a call to an undefined macro function.
     3809     */
     3810    /* Create a node. */
     3811    PVBCPPEXPR const pExpr = vbcppExprParseAllocNode(pParser);
     3812    if (!pExpr)
     3813        return kExprRet_Error;
     3814    pExpr->enmKind                  = kVBCppExprKind_UndefMacroCall;
     3815    pExpr->fComplete                = false;
     3816    pExpr->u.UndefMacroCall.cArgs   = 0;
     3817    pExpr->u.UndefMacroCall.papArgs = NULL;
     3818    pExpr->u.UndefMacroCall.pszName = RTStrDupN(pszMacro, cchMacro);
     3819    AssertReturn(pExpr->u.UndefMacroCall.pszName, vbcppExprParseError(pParser, "out of memory"));
     3820
     3821    /* Link it. */
     3822    pExpr->pParent  = pParser->pCur;
     3823    pParser->pCur   = pExpr;
     3824    *pParser->ppCur = pExpr;
     3825    pParser->ppCur  = NULL;
     3826
     3827    /*
     3828     * Parse the argument list.
     3829     */
     3830    pParser->pszCur++;
     3831    for (size_t iArg = 0 ; ; iArg++)
     3832    {
     3833        /*
     3834         * Prepare the next argument expression pointer.
     3835         */
     3836        if (!(iArg % 16))
     3837        {
     3838            void *pvNew = RTMemRealloc(pExpr->u.UndefMacroCall.papArgs,
     3839                                       sizeof(pExpr->u.UndefMacroCall.papArgs[0]) * (iArg + 16));
     3840            AssertPtrReturn(pvNew, vbcppExprParseError(pParser, "out of memory"));
     3841            pExpr->u.UndefMacroCall.papArgs = (PVBCPPEXPR *)pvNew;
     3842        }
     3843        pExpr->u.UndefMacroCall.papArgs[iArg] = NULL;
     3844        pParser->ppCur = &pExpr->u.UndefMacroCall.papArgs[iArg];
     3845
     3846        /*
     3847         * Do the parsing.
     3848         */
     3849        for (;;)
     3850        {
     3851            /*
     3852             * Eat unary operators until we hit a value or end of argument/call.
     3853             */
     3854            VBCPPEXPRRET enmRet;
     3855            do
     3856                enmRet = vbcppExprParseUnaryOrValue(pParser);
     3857            while (enmRet == kExprRet_UnaryOperator);
     3858            if (enmRet == kExprRet_EndOfExpr)
     3859                break;
     3860            if (enmRet == kExprRet_Error)
     3861                return enmRet;
     3862            AssertReturn(enmRet == kExprRet_Value, vbcppExprParseError(pParser, "Expected value (enmRet=%d)", enmRet));
     3863
     3864            /*
     3865             * Non-unary operator, right parenthesis or end of argument/call is up next.
     3866             */
     3867            enmRet = vbcppExprParseBinaryOrEoeOrRparen(pParser);
     3868            if (enmRet == kExprRet_EndOfExpr)
     3869                break;
     3870            if (enmRet == kExprRet_Error)
     3871                return enmRet;
     3872            AssertReturn(enmRet == kExprRet_Ok, vbcppExprParseError(pParser, "Expected value (enmRet=%d)", enmRet));
     3873        }
     3874
     3875        /*
     3876         * Append the argument and skip past the comma or right parenthesis.
     3877         */
     3878        if (pExpr->u.UndefMacroCall.papArgs[iArg] != NULL || !pExpr->fComplete)
     3879            pExpr->u.UndefMacroCall.cArgs = iArg + 1;
     3880
     3881        Assert(pParser->pCur == pExpr);
     3882        if (pExpr->fComplete)
     3883            break;
     3884    }
     3885
     3886    pParser->ppCur = NULL;
     3887    return kExprRet_Value;
     3888}
     3889
     3890
     3891/**
    36543892 * Parses an identifier in the expression, replacing it by 0.
    36553893 *
     
    36733911    while (vbcppIsCIdentifierChar(*pszNext))
    36743912        pszNext++;
    3675     size_t cchMacro = pszNext - pszMacro;
     3913    size_t const cchMacro = pszNext - pszMacro;
     3914
     3915    /* Skip spaces and check for parenthesis. */
     3916    pParser->pszCur = pszNext;
     3917    vbcppExprParseSkipWhiteSpace(pParser);
     3918    if (*pParser->pszCur == '(')
     3919    {
     3920        if (pParser->pThis->enmMode == kVBCppMode_Selective)
     3921            return vbcppExprParseUndefMacroCall(pParser, pszMacro, cchMacro);
     3922        return vbcppExprParseError(pParser, "%sUnknown unary operator '%.*s'",
     3923                                   pParser->pThis->enmMode != kVBCppMode_Standard ? "TODO selective: " : "",
     3924                                   cchMacro, pszMacro);
     3925    }
    36763926
    36773927    /* Create a signed value node. */
     
    36883938    *pParser->ppCur             = pExpr;
    36893939    pParser->ppCur              = NULL;
    3690 
    3691     /* Skip spaces and check for parenthesis. */
    3692     pParser->pszCur = pszNext;
    3693     vbcppExprParseSkipWhiteSpace(pParser);
    3694     if (*pParser->pszCur == '(')
    3695         return vbcppExprParseError(pParser, "Unknown unary operator '%.*s'", cchMacro, pszMacro);
    36963940
    36973941    return kExprRet_Value;
     
    37503994            cchSuffix++;
    37513995
    3752         if (cchSuffix == '1' && (*pszNext == 'u' || *pszNext == 'U'))
     3996        if (cchSuffix == 1 && (*pszNext == 'u' || *pszNext == 'U'))
    37533997            fSigned = false;
    3754         else if (   cchSuffix == '1'
     3998        else if (   cchSuffix == 1
    37553999                 && (*pszNext == 'l' || *pszNext == 'L'))
    37564000            fSigned = true;
    3757         else if (   cchSuffix == '2'
     4001        else if (   cchSuffix == 2
    37584002                 && (!strncmp(pszNext, "ul", 2) || !strncmp(pszNext, "UL", 2)))
    37594003            fSigned = false;
    3760         else if (   cchSuffix == '2'
     4004        else if (   cchSuffix == 2
    37614005                 && (!strncmp(pszNext, "ll", 2) || !strncmp(pszNext, "LL", 2)))
    37624006            fSigned = true;
    3763         else if (   cchSuffix == '3'
     4007        else if (   cchSuffix == 3
    37644008                 && (!strncmp(pszNext, "ull", 3) || !strncmp(pszNext, "ULL", 3)))
    37654009            fSigned = false;
     
    38564100 * @retval  kExprRet_UnaryOperator if an unary operator was found and processed.
    38574101 * @retval  kExprRet_Error with msg.
     4102 * @retval  kExprRet_EndOfExpr if reached ',' or ')' if in an undefined call.
    38584103 * @param   pParser             The parser instance.
    38594104 */
     
    38994144    else if (ch == '(')
    39004145        enmOperator = kVBCppUnaryOp_Parenthesis;
     4146    else if ((ch == ',' || ch == ')') && pParser->pCur->enmKind == kVBCppExprKind_UndefMacroCall)
     4147    {
     4148        pParser->pszCur++;
     4149        pParser->pCur->fComplete = ch == ')';
     4150        return kExprRet_EndOfExpr;
     4151    }
    39014152    else
    3902         return vbcppExprParseError(pParser, "Unknown token '%.*s'", 32, pParser->pszCur - 1);
     4153        return vbcppExprParseError(pParser, "Unexpected token '%.*s'", 32, pParser->pszCur - 1);
    39034154    pParser->pszCur++;
    39044155
     
    42654516 * @param   pszExpr             The expression.
    42664517 * @param   cchExpr             The length of the expression.
     4518 * @param   cReplacements       The number of replacements.
     4519 * @param   cDefinedUnknown     The number of defined(UNKNOWN) cases.  (Relevant
     4520 *                              for selective modes.)
    42674521 * @param   penmResult          Where to store the result.
    42684522 */
    4269 static RTEXITCODE vbcppExprEval(PVBCPP pThis, char *pszExpr, size_t cchExpr, size_t cReplacements, VBCPPEVAL *penmResult)
     4523static RTEXITCODE vbcppExprEval(PVBCPP pThis, char *pszExpr, size_t cchExpr, size_t cReplacements, size_t cDefinedUnknown,
     4524                                VBCPPEVAL *penmResult)
    42704525{
    42714526    Assert(strlen(pszExpr) == cchExpr);
     
    42774532    if (rcExit == RTEXITCODE_SUCCESS)
    42784533    {
    4279         if (   !cUndefined
     4534        if (   (!cUndefined && !cDefinedUnknown)
    42804535            || pThis->enmMode == kVBCppMode_SelectiveD
    42814536            || pThis->enmMode == kVBCppMode_Standard)
     
    45024757    if (rcExit == RTEXITCODE_SUCCESS)
    45034758    {
     4759        if (RT_C_IS_SPACE(*pchCondition))
     4760            pchCondition++;
    45044761        size_t const    cchCondition = ScmStreamGetCur(pStrmInput) - pchCondition;
    45054762
     
    45084765         */
    45094766        size_t          cReplacements;
    4510         rcExit = vbcppMacroExpandReScan(pThis, &ExpCtx, kMacroReScanMode_Expression, &cReplacements);
     4767        size_t          cDefinedUnknown;
     4768        rcExit = vbcppMacroExpandReScan(pThis, &ExpCtx, kMacroReScanMode_Expression, &cReplacements, &cDefinedUnknown);
    45114769        if (rcExit == RTEXITCODE_SUCCESS)
    45124770        {
     
    45304788                 */
    45314789                VBCPPEVAL enmResult;
    4532                 rcExit = vbcppExprEval(pThis, pszExpr, cchExpr, cReplacements, &enmResult);
     4790                rcExit = vbcppExprEval(pThis, pszExpr, cchExpr, cReplacements, cDefinedUnknown, &enmResult);
    45334791                if (rcExit == RTEXITCODE_SUCCESS)
    45344792                {
     
    45714829                            ssize_t cch = ScmStreamPrintf(&pThis->StrmOutput, "#%*selif", pCond->iKeepLevel - 1, "");
    45724830                            if (cch > 0)
    4573                                 rcExit = vbcppOutputComment(pThis, pStrmInput, offStart, cch, 2);
     4831                                rcExit = vbcppOutputComment(pThis, pStrmInput, offStart, cch, 1);
    45744832                            else
    45754833                                rcExit = vbcppError(pThis, "Output error %Rrc", (int)cch);
     
    50185276static RTEXITCODE vbcppDirectiveError(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart)
    50195277{
     5278    RT_NOREF(offStart);
     5279
     5280    /*
     5281     * Parse out the message.
     5282     */
     5283    size_t const off1st = vbcppProcessSkipWhite(pStrmInput);
     5284    size_t       offComment;
     5285    RTEXITCODE rcExit = vbcppInputSkipToEndOfDirectiveLine(pThis, pStrmInput, &offComment);
     5286    if (rcExit == RTEXITCODE_SUCCESS)
     5287    {
     5288        /*
     5289         * What to do about this
     5290         */
     5291        if (pThis->fPassThruError)
     5292        {
     5293            unsigned cchIndent = pThis->pCondStack ? pThis->pCondStack->iKeepLevel : 0;
     5294            ssize_t  cch = ScmStreamPrintf(&pThis->StrmOutput, "#%*serror", cchIndent, "");
     5295            if (cch > 0)
     5296                rcExit = vbcppOutputComment(pThis, pStrmInput, off1st, cch, 1);
     5297            else
     5298                rcExit = vbcppError(pThis, "output error");
     5299            return RTEXITCODE_SUCCESS;
     5300        }
     5301        return vbcppError(pThis, "Hit an #error");
     5302    }
    50205303    RT_NOREF_PV(offStart);
    5021     RT_NOREF_PV(pStrmInput);
     5304    vbcppError(pThis, "Malformed #error");
    50225305    return vbcppError(pThis, "Hit an #error");
    50235306}
     
    50755358    {
    50765359        size_t const offStart = ScmStreamTell(pStrmInput);
    5077 #define IS_DIRECTIVE(a_sz) ( sizeof(a_sz) - 1 == cchDirective && strncmp(pchDirective, a_sz, sizeof(a_sz) - 1) == 0)
     5360#define IS_DIRECTIVE(a_sz) ( sizeof(a_sz) - 1 == cchDirective && memcmp(pchDirective, a_sz, sizeof(a_sz) - 1) == 0)
    50785361        if (IS_DIRECTIVE("if"))
    50795362            rcExit = vbcppDirectiveIfOrElif(pThis, pStrmInput, offStart, kVBCppCondKind_If);
     
    52355518static RTEXITCODE vbcppOpenStreams(PVBCPP pThis)
    52365519{
    5237     if (!pThis->pszInput)
    5238         return vbcppError(pThis, "Preprocessing the standard input stream is currently not supported");
    5239 
    5240     size_t      cchName = strlen(pThis->pszInput);
    5241     PVBCPPINPUT pInput = (PVBCPPINPUT)RTMemAlloc(RT_UOFFSETOF_DYN(VBCPPINPUT, szName[cchName + 1]));
     5520    const char * const pszInput = pThis->pszInput ? pThis->pszInput : "stdin";
     5521    size_t const       cchName  = strlen(pszInput);
     5522    PVBCPPINPUT const  pInput   = (PVBCPPINPUT)RTMemAlloc(RT_UOFFSETOF_DYN(VBCPPINPUT, szName[cchName + 1]));
    52425523    if (!pInput)
    52435524        return vbcppError(pThis, "out of memory");
    52445525    pInput->pUp          = pThis->pInputStack;
    52455526    pInput->pszSpecified = pInput->szName;
    5246     memcpy(pInput->szName, pThis->pszInput, cchName + 1);
     5527    memcpy(pInput->szName, pszInput, cchName + 1);
    52475528    pThis->pInputStack   = pInput;
    5248     int rc = ScmStreamInitForReading(&pInput->StrmInput, pThis->pszInput);
    5249     if (RT_FAILURE(rc))
    5250         return vbcppError(pThis, "ScmStreamInitForReading returned %Rrc when opening input file (%s)",
    5251                           rc, pThis->pszInput);
     5529    int rc;
     5530    if (pThis->pszInput)
     5531    {
     5532        rc = ScmStreamInitForReading(&pInput->StrmInput, pThis->pszInput);
     5533        if (RT_FAILURE(rc))
     5534            return vbcppError(pThis, "ScmStreamInitForReading returned %Rrc when opening and reading in input file (%s)",
     5535                              rc, pThis->pszInput);
     5536    }
     5537    else
     5538    {
     5539        rc = ScmStreamInitForReadingFromStdInput(&pInput->StrmInput);
     5540        if (RT_FAILURE(rc))
     5541            return vbcppError(pThis, "ScmStreamInitForReadingFromStdInput returned %Rrc", rc);
     5542
     5543    }
    52525544
    52535545    rc = ScmStreamInitForWriting(&pThis->StrmOutput, &pInput->StrmInput);
     
    52795571            pThis->fPassThruPragmaSTD               = true;
    52805572            pThis->fPassThruPragmaOther             = true;
     5573            pThis->fPassThruError                   = false;
    52815574            pThis->fRemoveDroppedLines              = false;
    52825575            pThis->fLineSplicing                    = true;
     
    52935586            pThis->fPassThruPragmaSTD               = true;
    52945587            pThis->fPassThruPragmaOther             = true;
     5588            pThis->fPassThruError                   = true;
    52955589            pThis->fRemoveDroppedLines              = true;
    52965590            pThis->fLineSplicing                    = false;
     
    53075601            pThis->fPassThruPragmaSTD               = false;
    53085602            pThis->fPassThruPragmaOther             = false;
     5603            pThis->fPassThruError                   = false;
    53095604            pThis->fRemoveDroppedLines              = true;
    53105605            pThis->fLineSplicing                    = false;
  • trunk/src/bldprogs/scmstream.cpp

    r98368 r100618  
    8787        pStream->cbAllocated    = cbFile;
    8888        pStream->fFileMemory    = true;
     89    }
     90    return rc;
     91}
     92
     93/**
     94 * Initialize an input stream from stdin.
     95 *
     96 * This will read the entire file from stdin before returning.
     97 *
     98 * @returns IPRT status code.
     99 * @param   pStream             The stream to initialize.
     100 * @param   pszFilename         The file to take the stream content from.
     101 */
     102int ScmStreamInitForReadingFromStdInput(PSCMSTREAM pStream)
     103{
     104    scmStreamInitInternal(pStream, false /*fWriteOrRead*/);
     105
     106    RTFILE hStdIn = NIL_RTFILE;
     107    int rc = RTFileFromNative(&hStdIn, RTFILE_NATIVE_STDIN);
     108    if (RT_SUCCESS(rc))
     109    {
     110        /*
     111         * Allocate initial buffer.
     112         */
     113        pStream->pch = (char *)RTMemAlloc(_64K);
     114        if (pStream->pch)
     115        {
     116            pStream->cbAllocated    = _64K;
     117            pStream->fFileMemory    = false;
     118
     119            /*
     120             * The read loop.
     121             */
     122            for (;;)
     123            {
     124                /* Make sure we've got at least 4K (random number) of buffer space to read into. */
     125                size_t cbToRead = pStream->cbAllocated - pStream->cb;
     126                if (cbToRead < _4K)
     127                {
     128                    size_t const cbNew = pStream->cbAllocated < _16M ? pStream->cbAllocated * 2 : pStream->cbAllocated + _16M;
     129                    AssertStmt(cbNew < _2G, rc = VERR_TOO_MUCH_DATA);
     130                    void * const pvNew = RTMemRealloc(pStream->pch, cbNew);
     131                    AssertStmt(pvNew, rc = VERR_NO_MEMORY);
     132
     133                    pStream->pch         = (char *)pvNew;
     134                    pStream->cbAllocated = cbNew;
     135                    cbToRead = cbNew - pStream->cb;
     136                }
     137
     138                /* Do the actual reading. */
     139                size_t cbRead = 0;
     140                rc = RTFileRead(hStdIn, &pStream->pch[pStream->cb], cbToRead, &cbRead);
     141                if (RT_SUCCESS(rc))
     142                {
     143                    if (cbRead)
     144                        pStream->cb += cbRead;
     145                    else
     146                        break;
     147                }
     148                else
     149                {
     150                    if (rc == VERR_EOF)
     151                        rc = VINF_SUCCESS;
     152                    break;
     153                }
     154            }
     155        }
     156        else
     157            rc = VERR_NO_MEMORY;
    89158    }
    90159    return rc;
  • trunk/src/bldprogs/scmstream.h

    r98368 r100618  
    103103
    104104int         ScmStreamInitForReading(PSCMSTREAM pStream, const char *pszFilename);
     105int         ScmStreamInitForReadingFromStdInput(PSCMSTREAM pStream);
    105106int         ScmStreamInitForWriting(PSCMSTREAM pStream, PCSCMSTREAM pRelatedStream);
    106107void        ScmStreamDelete(PSCMSTREAM pStream);
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