Changeset 100618 in vbox for trunk/src/bldprogs
- Timestamp:
- Jul 18, 2023 12:27:58 AM (21 months ago)
- svn:sync-xref-src-repo-rev:
- 158449
- Location:
- trunk/src/bldprogs
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/bldprogs/VBoxCPP.cpp
r100555 r100618 200 200 kVBCppExprKind_SignedValue, 201 201 kVBCppExprKind_UnsignedValue, 202 kVBCppExprKind_UndefMacroCall, 202 203 kVBCppExprKind_End 203 204 } VBCPPEXPRKIND; … … 308 309 uint64_t u64; 309 310 } UnsignedValue; 311 312 /** kVBCppExprKind_UndefMacroCall */ 313 struct 314 { 315 char *pszName; 316 size_t cArgs; 317 PVBCPPEXPR *papArgs; 318 } UndefMacroCall; 310 319 } u; 311 320 } VBCPPEXPR; … … 470 479 /** Whether to pass thru other pragmas. */ 471 480 bool fPassThruPragmaOther; 481 /** Whether to pass thru \#error directives or execute them. */ 482 bool fPassThruError; 472 483 /** Whether to remove dropped lines from the output. */ 473 484 bool fRemoveDroppedLines; … … 532 543 * Internal Functions * 533 544 *********************************************************************************************************************************/ 545 static VBCPPEXPRRET vbcppExprParseUnaryOrValue(PVBCPPEXPRPARSER pParser); 534 546 static PVBCPPMACRO vbcppMacroLookup(PVBCPP pThis, const char *pszDefine, size_t cchDefine); 535 547 static 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); 548 static RTEXITCODE vbcppMacroExpandReScan(PVBCPP pThis, PVBCPPMACROEXP pExp, VBCPPMACRORESCANMODE enmMode, 549 size_t *pcReplacements, size_t *pcDefinedUnknown); 537 550 static void vbcppMacroExpandCleanup(PVBCPPMACROEXP pExp); 538 551 … … 622 635 va_list va; 623 636 va_start(va, pszMsg); 624 RTMsgErrorV(pszMsg, va); 637 //RTMsgErrorV(pszMsg, va); 638 RTEXITCODE rcExit = vbcppErrorV(pThis, pszMsg, va); 625 639 va_end(va); 626 return pThis->rcExit = RTEXITCODE_FAILURE;640 return rcExit; 627 641 } 628 642 … … 1593 1607 rcExit = vbcppMacroExpandIt(pThis, &ExpCtx, 0 /* offset */, pMacro, cchDefine); 1594 1608 if (rcExit == RTEXITCODE_SUCCESS) 1595 rcExit = vbcppMacroExpandReScan(pThis, &ExpCtx, kMacroReScanMode_Normal, NULL );1609 rcExit = vbcppMacroExpandReScan(pThis, &ExpCtx, kMacroReScanMode_Normal, NULL, NULL); 1596 1610 if (rcExit == RTEXITCODE_SUCCESS) 1597 1611 { … … 2392 2406 * @param pcReplacements Where to return the number of replacements 2393 2407 * 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 */ 2411 static 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; 2400 2418 unsigned ch; 2401 2419 while ( off < pExp->StrBuf.cchBuf … … 2467 2485 { 2468 2486 cReplacements++; 2487 cDefinedUnknown++; 2469 2488 rcExit = vbcppMacroExpandDefinedOperator(pThis, pExp, offDefine, &off); 2470 2489 } … … 2482 2501 if (pcReplacements) 2483 2502 *pcReplacements = cReplacements; 2503 if (pcDefinedUnknown) 2504 *pcDefinedUnknown = cDefinedUnknown; 2484 2505 return rcExit; 2485 2506 } … … 2667 2688 * requires. Performing syntax validation while parsing. 2668 2689 */ 2669 uint32_t cchArgNames = 0; 2690 bool fVariadic = false; 2691 size_t cchArgNames = 0; 2670 2692 uint32_t cArgs = 0; 2671 2693 for (size_t off = 0; off < cchParams; off++) … … 2675 2697 while (off < cchParams) 2676 2698 { 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'))) 2678 2702 { 2679 2703 if (pszParams[off] != ',' || !fIgnoreComma) … … 2681 2705 if (vbcppIsCIdentifierLeadChar(pszParams[off])) 2682 2706 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); 2685 2728 } 2686 2729 fIgnoreComma = false; … … 2716 2759 *pszDst++ = '\0'; 2717 2760 pMacro->fFunction = true; 2718 pMacro->fVarArg = f alse;2761 pMacro->fVarArg = fVariadic; 2719 2762 pMacro->fCmdLine = fCmdLine; 2720 2763 pMacro->fExpanding = false; … … 2736 2779 while (off < cchParams) 2737 2780 { 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'))) 2739 2784 { 2740 2785 if (pszParams[off] != ',' || !fIgnoreComma) … … 2748 2793 2749 2794 /* Found and argument. First character is already validated. */ 2750 VBCPP_BITMAP_SET(pMacro->bmArgs, pszParams[off]);2751 2795 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 } 2757 2814 *pszDst++ = '\0'; 2758 2815 iArg++; … … 3032 3089 break; 3033 3090 } 3091 chPrev = ch; 3034 3092 ScmStreamGetCh(pStrmInput); 3035 3093 } … … 3231 3289 pCond->fElIfDecided = enmResult == kVBCppEval_True; 3232 3290 pCond->iLevel = pThis->cCondStackDepth; 3233 pCond->iKeepLevel = (pUp ? pUp->iKeepLevel : 0) + enmResult == kVBCppEval_Undecided;3291 pCond->iKeepLevel = (pUp ? pUp->iKeepLevel : 0) + (enmResult == kVBCppEval_Undecided); 3234 3292 pCond->pchCond = pchCondition; 3235 3293 pCond->cchCond = cchCondition; … … 3294 3352 case kVBCppExprKind_UnsignedValue: 3295 3353 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; 3296 3361 default: 3297 3362 AssertFailed(); … … 3348 3413 3349 3414 /** 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 */ 3423 static 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.) 3351 3443 * 3352 3444 * @returns Expression status. … … 3362 3454 { 3363 3455 vbcppExprParseSkipWhiteSpace(pParser); 3364 char c h = *pParser->pszCur;3456 char const ch = *pParser->pszCur; 3365 3457 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? */ 3368 3485 break; 3369 3486 pParser->pszCur++; … … 3371 3488 PVBCPPEXPR pCur = pParser->pCur; 3372 3489 while ( pCur 3490 && ( pCur->enmKind != kVBCppExprKind_UndefMacroCall 3491 || pCur->fComplete /*?*/) 3373 3492 && ( pCur->enmKind != kVBCppExprKind_Unary 3374 || pCur->u.Unary.enmOperator != kVBCppUnaryOp_Parenthesis)) 3493 || pCur->u.Unary.enmOperator != kVBCppUnaryOp_Parenthesis 3494 || pCur->fComplete)) 3375 3495 { 3376 3496 switch (pCur->enmKind) … … 3401 3521 #endif 3402 3522 break; 3523 case kVBCppExprKind_UndefMacroCall: 3524 break; 3403 3525 default: 3404 3526 return vbcppExprParseError(pParser, "Internal error (enmKind=%d)", pCur->enmKind); … … 3408 3530 if (!pCur) 3409 3531 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")); 3410 3552 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; 3420 3555 } 3421 3556 … … 3565 3700 */ 3566 3701 PVBCPPEXPR *ppPlace = NULL; 3567 PVBCPPEXPR pChild = NULL;3568 PVBCPPEXPR pParent = p Parser->pCur;3702 PVBCPPEXPR pChild = pParser->pCur; 3703 PVBCPPEXPR pParent = pChild->pParent; 3569 3704 while (pParent) 3570 3705 { … … 3600 3735 return vbcppExprParseError(pParser, "The ternary operator is not implemented"); 3601 3736 } 3737 else if (pParent->enmKind == kVBCppExprKind_UndefMacroCall) 3738 { 3739 ppPlace = &pParent->u.UndefMacroCall.papArgs[pParent->u.UndefMacroCall.cArgs]; 3740 break; 3741 } 3602 3742 else 3603 3743 AssertReturn( pParent->enmKind == kVBCppExprKind_SignedValue … … 3652 3792 3653 3793 /** 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 */ 3805 static 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 /** 3654 3892 * Parses an identifier in the expression, replacing it by 0. 3655 3893 * … … 3673 3911 while (vbcppIsCIdentifierChar(*pszNext)) 3674 3912 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 } 3676 3926 3677 3927 /* Create a signed value node. */ … … 3688 3938 *pParser->ppCur = pExpr; 3689 3939 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);3696 3940 3697 3941 return kExprRet_Value; … … 3750 3994 cchSuffix++; 3751 3995 3752 if (cchSuffix == '1'&& (*pszNext == 'u' || *pszNext == 'U'))3996 if (cchSuffix == 1 && (*pszNext == 'u' || *pszNext == 'U')) 3753 3997 fSigned = false; 3754 else if ( cchSuffix == '1'3998 else if ( cchSuffix == 1 3755 3999 && (*pszNext == 'l' || *pszNext == 'L')) 3756 4000 fSigned = true; 3757 else if ( cchSuffix == '2'4001 else if ( cchSuffix == 2 3758 4002 && (!strncmp(pszNext, "ul", 2) || !strncmp(pszNext, "UL", 2))) 3759 4003 fSigned = false; 3760 else if ( cchSuffix == '2'4004 else if ( cchSuffix == 2 3761 4005 && (!strncmp(pszNext, "ll", 2) || !strncmp(pszNext, "LL", 2))) 3762 4006 fSigned = true; 3763 else if ( cchSuffix == '3'4007 else if ( cchSuffix == 3 3764 4008 && (!strncmp(pszNext, "ull", 3) || !strncmp(pszNext, "ULL", 3))) 3765 4009 fSigned = false; … … 3856 4100 * @retval kExprRet_UnaryOperator if an unary operator was found and processed. 3857 4101 * @retval kExprRet_Error with msg. 4102 * @retval kExprRet_EndOfExpr if reached ',' or ')' if in an undefined call. 3858 4103 * @param pParser The parser instance. 3859 4104 */ … … 3899 4144 else if (ch == '(') 3900 4145 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 } 3901 4152 else 3902 return vbcppExprParseError(pParser, "Un knowntoken '%.*s'", 32, pParser->pszCur - 1);4153 return vbcppExprParseError(pParser, "Unexpected token '%.*s'", 32, pParser->pszCur - 1); 3903 4154 pParser->pszCur++; 3904 4155 … … 4265 4516 * @param pszExpr The expression. 4266 4517 * @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.) 4267 4521 * @param penmResult Where to store the result. 4268 4522 */ 4269 static RTEXITCODE vbcppExprEval(PVBCPP pThis, char *pszExpr, size_t cchExpr, size_t cReplacements, VBCPPEVAL *penmResult) 4523 static RTEXITCODE vbcppExprEval(PVBCPP pThis, char *pszExpr, size_t cchExpr, size_t cReplacements, size_t cDefinedUnknown, 4524 VBCPPEVAL *penmResult) 4270 4525 { 4271 4526 Assert(strlen(pszExpr) == cchExpr); … … 4277 4532 if (rcExit == RTEXITCODE_SUCCESS) 4278 4533 { 4279 if ( !cUndefined4534 if ( (!cUndefined && !cDefinedUnknown) 4280 4535 || pThis->enmMode == kVBCppMode_SelectiveD 4281 4536 || pThis->enmMode == kVBCppMode_Standard) … … 4502 4757 if (rcExit == RTEXITCODE_SUCCESS) 4503 4758 { 4759 if (RT_C_IS_SPACE(*pchCondition)) 4760 pchCondition++; 4504 4761 size_t const cchCondition = ScmStreamGetCur(pStrmInput) - pchCondition; 4505 4762 … … 4508 4765 */ 4509 4766 size_t cReplacements; 4510 rcExit = vbcppMacroExpandReScan(pThis, &ExpCtx, kMacroReScanMode_Expression, &cReplacements); 4767 size_t cDefinedUnknown; 4768 rcExit = vbcppMacroExpandReScan(pThis, &ExpCtx, kMacroReScanMode_Expression, &cReplacements, &cDefinedUnknown); 4511 4769 if (rcExit == RTEXITCODE_SUCCESS) 4512 4770 { … … 4530 4788 */ 4531 4789 VBCPPEVAL enmResult; 4532 rcExit = vbcppExprEval(pThis, pszExpr, cchExpr, cReplacements, &enmResult);4790 rcExit = vbcppExprEval(pThis, pszExpr, cchExpr, cReplacements, cDefinedUnknown, &enmResult); 4533 4791 if (rcExit == RTEXITCODE_SUCCESS) 4534 4792 { … … 4571 4829 ssize_t cch = ScmStreamPrintf(&pThis->StrmOutput, "#%*selif", pCond->iKeepLevel - 1, ""); 4572 4830 if (cch > 0) 4573 rcExit = vbcppOutputComment(pThis, pStrmInput, offStart, cch, 2);4831 rcExit = vbcppOutputComment(pThis, pStrmInput, offStart, cch, 1); 4574 4832 else 4575 4833 rcExit = vbcppError(pThis, "Output error %Rrc", (int)cch); … … 5018 5276 static RTEXITCODE vbcppDirectiveError(PVBCPP pThis, PSCMSTREAM pStrmInput, size_t offStart) 5019 5277 { 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 } 5020 5303 RT_NOREF_PV(offStart); 5021 RT_NOREF_PV(pStrmInput);5304 vbcppError(pThis, "Malformed #error"); 5022 5305 return vbcppError(pThis, "Hit an #error"); 5023 5306 } … … 5075 5358 { 5076 5359 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) 5078 5361 if (IS_DIRECTIVE("if")) 5079 5362 rcExit = vbcppDirectiveIfOrElif(pThis, pStrmInput, offStart, kVBCppCondKind_If); … … 5235 5518 static RTEXITCODE vbcppOpenStreams(PVBCPP pThis) 5236 5519 { 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])); 5242 5523 if (!pInput) 5243 5524 return vbcppError(pThis, "out of memory"); 5244 5525 pInput->pUp = pThis->pInputStack; 5245 5526 pInput->pszSpecified = pInput->szName; 5246 memcpy(pInput->szName, p This->pszInput, cchName + 1);5527 memcpy(pInput->szName, pszInput, cchName + 1); 5247 5528 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 } 5252 5544 5253 5545 rc = ScmStreamInitForWriting(&pThis->StrmOutput, &pInput->StrmInput); … … 5279 5571 pThis->fPassThruPragmaSTD = true; 5280 5572 pThis->fPassThruPragmaOther = true; 5573 pThis->fPassThruError = false; 5281 5574 pThis->fRemoveDroppedLines = false; 5282 5575 pThis->fLineSplicing = true; … … 5293 5586 pThis->fPassThruPragmaSTD = true; 5294 5587 pThis->fPassThruPragmaOther = true; 5588 pThis->fPassThruError = true; 5295 5589 pThis->fRemoveDroppedLines = true; 5296 5590 pThis->fLineSplicing = false; … … 5307 5601 pThis->fPassThruPragmaSTD = false; 5308 5602 pThis->fPassThruPragmaOther = false; 5603 pThis->fPassThruError = false; 5309 5604 pThis->fRemoveDroppedLines = true; 5310 5605 pThis->fLineSplicing = false; -
trunk/src/bldprogs/scmstream.cpp
r98368 r100618 87 87 pStream->cbAllocated = cbFile; 88 88 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 */ 102 int 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; 89 158 } 90 159 return rc; -
trunk/src/bldprogs/scmstream.h
r98368 r100618 103 103 104 104 int ScmStreamInitForReading(PSCMSTREAM pStream, const char *pszFilename); 105 int ScmStreamInitForReadingFromStdInput(PSCMSTREAM pStream); 105 106 int ScmStreamInitForWriting(PSCMSTREAM pStream, PCSCMSTREAM pRelatedStream); 106 107 void ScmStreamDelete(PSCMSTREAM pStream);
Note:
See TracChangeset
for help on using the changeset viewer.