- Timestamp:
- May 14, 2012 7:55:04 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/bldprogs/VBoxCPP.cpp
r41263 r41266 69 69 * Structures and Typedefs * 70 70 *******************************************************************************/ 71 /** Pointer to the C preprocessor instance data. */ 72 typedef struct VBCPP *PVBCPP; 73 74 71 75 /** 72 76 * Variable string buffer (very simple version of SCMSTREAM). … … 169 173 kMacroReScanMode_End 170 174 } VBCPPMACRORESCANMODE; 175 176 177 /** 178 * Expression node type. 179 */ 180 typedef enum VBCPPEXPRKIND 181 { 182 kVBCppExprKind_Invalid = 0, 183 kVBCppExprKind_Unary, 184 kVBCppExprKind_Binary, 185 kVBCppExprKind_Ternary, 186 kVBCppExprKind_SignedValue, 187 kVBCppExprKind_UnsignedValue, 188 kVBCppExprKind_End 189 } VBCPPEXPRKIND; 190 191 192 /** Macro used for the precedence field. */ 193 #define VBCPPOP_PRECEDENCE(a_iPrecedence) ((a_iPrecedence) << 8) 194 /** Mask for getting the precedence field value. */ 195 #define VBCPPOP_PRECEDENCE_MASK 0xff00 196 /** Operator associativity - Left to right. */ 197 #define VBCPPOP_L2R (1 << 16) 198 /** Operator associativity - Right to left. */ 199 #define VBCPPOP_R2L (2 << 16) 200 201 /** 202 * Unary operators. 203 */ 204 typedef enum VBCPPUNARYOP 205 { 206 kVBCppUnaryOp_Invalid = 0, 207 kVBCppUnaryOp_Pluss = VBCPPOP_R2L | VBCPPOP_PRECEDENCE( 3) | 5, 208 kVBCppUnaryOp_Minus = VBCPPOP_R2L | VBCPPOP_PRECEDENCE( 3) | 6, 209 kVBCppUnaryOp_LogicalNot = VBCPPOP_R2L | VBCPPOP_PRECEDENCE( 3) | 7, 210 kVBCppUnaryOp_BitwiseNot = VBCPPOP_R2L | VBCPPOP_PRECEDENCE( 3) | 8, 211 kVBCppUnaryOp_Parenthesis = VBCPPOP_R2L | VBCPPOP_PRECEDENCE(15) | 9, 212 kVBCppUnaryOp_End 213 } VBCPPUNARYOP; 214 215 /** 216 * Binary operators. 217 */ 218 typedef enum VBCPPBINARYOP 219 { 220 kVBCppBinary_Invalid = 0, 221 kVBCppBinary_Multiplication = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 5) | 2, 222 kVBCppBinary_Division = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 5) | 4, 223 kVBCppBinary_Modulo = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 5) | 5, 224 kVBCppBinary_Addition = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 6) | 6, 225 kVBCppBinary_Subtraction = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 6) | 7, 226 kVBCppBinary_LeftShift = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 7) | 8, 227 kVBCppBinary_RightShift = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 7) | 9, 228 kVBCppBinary_LessThan = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 8) | 10, 229 kVBCppBinary_LessThanOrEqual = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 8) | 11, 230 kVBCppBinary_GreaterThan = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 8) | 12, 231 kVBCppBinary_GreaterThanOrEqual = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 8) | 13, 232 kVBCppBinary_EqualTo = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 9) | 14, 233 kVBCppBinary_NotEqualTo = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 9) | 15, 234 kVBCppBinary_BitwiseAnd = VBCPPOP_L2R | VBCPPOP_PRECEDENCE(10) | 16, 235 kVBCppBinary_BitwiseXor = VBCPPOP_L2R | VBCPPOP_PRECEDENCE(11) | 17, 236 kVBCppBinary_BitwiseOr = VBCPPOP_L2R | VBCPPOP_PRECEDENCE(12) | 18, 237 kVBCppBinary_LogicalAnd = VBCPPOP_L2R | VBCPPOP_PRECEDENCE(13) | 19, 238 kVBCppBinary_LogicalOr = VBCPPOP_L2R | VBCPPOP_PRECEDENCE(14) | 20, 239 kVBCppBinary_End 240 } VBCPPBINARYOP; 241 242 /** The precedence of the ternary operator (expr ? true : false). */ 243 #define VBCPPTERNAROP_PRECEDENCE VBCPPOP_PRECEDENCE(16) 244 245 246 /** Pointer to an expression parsing node. */ 247 typedef struct VBCPPEXPR *PVBCPPEXPR; 248 /** 249 * Expression parsing node. 250 */ 251 typedef struct VBCPPEXPR 252 { 253 /** Parent expression. */ 254 PVBCPPEXPR pParent; 255 /** Whether the expression is complete or not. */ 256 bool fComplete; 257 /** The kind of expression. */ 258 VBCPPEXPRKIND enmKind; 259 /** Kind specific content. */ 260 union 261 { 262 /** kVBCppExprKind_Unary */ 263 struct 264 { 265 VBCPPUNARYOP enmOperator; 266 PVBCPPEXPR pArg; 267 } Unary; 268 269 /** kVBCppExprKind_Binary */ 270 struct 271 { 272 VBCPPBINARYOP enmOperator; 273 PVBCPPEXPR pLeft; 274 PVBCPPEXPR pRight; 275 } Binary; 276 277 /** kVBCppExprKind_Ternary */ 278 struct 279 { 280 PVBCPPEXPR pExpr; 281 PVBCPPEXPR pTrue; 282 PVBCPPEXPR pFalse; 283 } Ternary; 284 285 /** kVBCppExprKind_SignedValue */ 286 struct 287 { 288 int64_t s64; 289 } SignedValue; 290 291 /** kVBCppExprKind_UnsignedValue */ 292 struct 293 { 294 uint64_t u64; 295 } UnsignedValue; 296 } u; 297 } VBCPPEXPR; 298 299 300 /** 301 * Operator return statuses. 302 */ 303 typedef enum VBCPPEXPRRET 304 { 305 kExprRet_Error = -1, 306 kExprRet_Ok = 0, 307 kExprRet_UnaryOperator, 308 kExprRet_Value, 309 kExprRet_EndOfExpr, 310 kExprRet_End 311 } VBCPPEXPRRET; 312 313 /** 314 * Expression parser context. 315 */ 316 typedef struct VBCPPEXPRPARSER 317 { 318 /** The current expression posistion. */ 319 const char *pszCur; 320 /** The root node. */ 321 PVBCPPEXPR pRoot; 322 /** The current expression node. */ 323 PVBCPPEXPR pCur; 324 /** Where to insert the next expression. */ 325 PVBCPPEXPR *ppCur; 326 /** The expression. */ 327 const char *pszExpr; 328 /** The number of undefined macros we've encountered while parsing. */ 329 size_t cUndefined; 330 /** Pointer to the C preprocessor instance. */ 331 PVBCPP pThis; 332 } VBCPPEXPRPARSER; 333 /** Pointer to an expression parser context. */ 334 typedef VBCPPEXPRPARSER *PVBCPPEXPRPARSER; 171 335 172 336 … … 349 513 bool fStrmOutputValid; 350 514 } VBCPP; 351 /** Pointer to the C preprocessor instance data. */352 typedef VBCPP *PVBCPP;353 515 354 516 … … 470 632 471 633 634 /** 635 * Initializes a string buffer. 636 * 637 * @param pStrBuf The buffer structure to initialize. 638 * @param pThis The C preprocessor instance. 639 */ 472 640 static void vbcppStrBufInit(PVBCPPSTRBUF pStrBuf, PVBCPP pThis) 473 641 { … … 479 647 480 648 649 /** 650 * Deletes a string buffer. 651 * 652 * @param pStrBuf Pointer to the string buffer. 653 */ 481 654 static void vbcppStrBufDelete(PVBCPPSTRBUF pStrBuf) 482 655 { … … 486 659 487 660 661 /** 662 * Ensures that sufficient bufferspace is available, growing the buffer if 663 * necessary. 664 * 665 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg. 666 * @param pStrBuf Pointer to the string buffer. 667 * @param cbMin The minimum buffer size. 668 */ 488 669 static RTEXITCODE vbcppStrBufGrow(PVBCPPSTRBUF pStrBuf, size_t cbMin) 489 670 { … … 504 685 505 686 687 /** 688 * Appends a substring. 689 * 690 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg. 691 * @param pStrBuf Pointer to the string buffer. 692 * @param pchSrc Pointer to the first character in the substring. 693 * @param cchSrc The length of the substring. 694 */ 506 695 static RTEXITCODE vbcppStrBufAppendN(PVBCPPSTRBUF pStrBuf, const char *pchSrc, size_t cchSrc) 507 696 { … … 523 712 524 713 714 /** 715 * Appends a character. 716 * 717 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg. 718 * @param pStrBuf Pointer to the string buffer. 719 * @param ch The charater to append. 720 */ 525 721 static RTEXITCODE vbcppStrBufAppendCh(PVBCPPSTRBUF pStrBuf, char ch) 526 722 { … … 541 737 542 738 739 /** 740 * Appends a string to the buffer. 741 * 742 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg. 743 * @param pStrBuf Pointer to the string buffer. 744 * @param psz The string to append. 745 */ 543 746 static RTEXITCODE vbcppStrBufAppend(PVBCPPSTRBUF pStrBuf, const char *psz) 544 747 { … … 547 750 548 751 752 /** 753 * Gets the last char in the buffer. 754 * 755 * @returns Last character, 0 if empty. 756 * @param pStrBuf Pointer to the string buffer. 757 */ 549 758 static char vbcppStrBufLastCh(PVBCPPSTRBUF pStrBuf) 550 759 { … … 638 847 } 639 848 640 849 #if 0 641 850 642 851 /** … … 794 1003 } 795 1004 1005 #endif 1006 1007 796 1008 797 1009 … … 1117 1329 return rcExit; 1118 1330 } 1119 1120 1331 1121 1332 … … 1261 1472 * Processes a single quoted constant. 1262 1473 * 1263 * Must not replace any C-words in strings.1474 * Must not replace any C-words in character constants. 1264 1475 * 1265 1476 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg. … … 1297 1508 /** 1298 1509 * Processes a integer or floating point number constant. 1510 * 1511 * Must not replace the type suffix. 1299 1512 * 1300 1513 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg. … … 1471 1684 return UINT32_MAX; 1472 1685 } 1473 1474 1475 1686 1476 1687 … … 3020 3231 3021 3232 3022 typedef enum VBCPPEXPRKIND3023 {3024 kVBCppExprKind_Invalid = 0,3025 kVBCppExprKind_Unary,3026 kVBCppExprKind_Binary,3027 kVBCppExprKind_Ternary,3028 kVBCppExprKind_SignedValue,3029 kVBCppExprKind_UnsignedValue,3030 kVBCppExprKind_End3031 } VBCPPEXPRKIND;3032 3033 #define VBCPPOP_PRECEDENCE(a_iPrecedence) ((a_iPrecedence) << 8)3034 #define VBCPPOP_PRECEDENCE_MASK 0xff003035 #define VBCPPOP_L2R (1 << 16)3036 #define VBCPPOP_R2L (2 << 16)3037 3038 typedef enum VBCPPUNARYOP3039 {3040 kVBCppUnaryOp_Invalid = 0,3041 kVBCppUnaryOp_Pluss = VBCPPOP_R2L | VBCPPOP_PRECEDENCE( 3) | 5,3042 kVBCppUnaryOp_Minus = VBCPPOP_R2L | VBCPPOP_PRECEDENCE( 3) | 6,3043 kVBCppUnaryOp_LogicalNot = VBCPPOP_R2L | VBCPPOP_PRECEDENCE( 3) | 7,3044 kVBCppUnaryOp_BitwiseNot = VBCPPOP_R2L | VBCPPOP_PRECEDENCE( 3) | 8,3045 kVBCppUnaryOp_Parenthesis = VBCPPOP_R2L | VBCPPOP_PRECEDENCE(15) | 9,3046 kVBCppUnaryOp_End3047 } VBCPPUNARYOP;3048 3049 typedef enum VBCPPBINARYOP3050 {3051 kVBCppBinary_Invalid = 0,3052 // kVBCppBinary_SizeOf = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 3) | 1,3053 kVBCppBinary_Multiplication = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 5) | 2,3054 kVBCppBinary_Division = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 5) | 4,3055 kVBCppBinary_Modulo = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 5) | 5,3056 kVBCppBinary_Addition = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 6) | 6,3057 kVBCppBinary_Subtraction = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 6) | 7,3058 kVBCppBinary_LeftShift = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 7) | 8,3059 kVBCppBinary_RightShift = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 7) | 9,3060 kVBCppBinary_LessThan = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 8) | 10,3061 kVBCppBinary_LessThanOrEqual = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 8) | 11,3062 kVBCppBinary_GreaterThan = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 8) | 12,3063 kVBCppBinary_GreaterThanOrEqual = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 8) | 13,3064 kVBCppBinary_EqualTo = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 9) | 14,3065 kVBCppBinary_NotEqualTo = VBCPPOP_L2R | VBCPPOP_PRECEDENCE( 9) | 15,3066 kVBCppBinary_BitwiseAnd = VBCPPOP_L2R | VBCPPOP_PRECEDENCE(10) | 16,3067 kVBCppBinary_BitwiseXor = VBCPPOP_L2R | VBCPPOP_PRECEDENCE(11) | 17,3068 kVBCppBinary_BitwiseOr = VBCPPOP_L2R | VBCPPOP_PRECEDENCE(12) | 18,3069 kVBCppBinary_LogicalAnd = VBCPPOP_L2R | VBCPPOP_PRECEDENCE(13) | 19,3070 kVBCppBinary_LogicalOr = VBCPPOP_L2R | VBCPPOP_PRECEDENCE(14) | 20,3071 kVBCppBinary_End3072 } VBCPPBINARYOP;3073 3074 /** The precedence of the ternary operator (expr ? true : false). */3075 #define VBCPPTERNAROP_PRECEDENCE VBCPPOP_PRECEDENCE(16)3076 3077 3078 typedef struct VBCPPEXPR *PVBCPPEXPR;3079 3080 /**3081 * Expression parsing structure.3082 */3083 typedef struct VBCPPEXPR3084 {3085 /** Parent expression. */3086 PVBCPPEXPR pParent;3087 /** Whether the expression is complete or not. */3088 bool fComplete;3089 /** The kind of expression. */3090 VBCPPEXPRKIND enmKind;3091 /** Content specific. */3092 union3093 {3094 struct3095 {3096 VBCPPUNARYOP enmOperator;3097 PVBCPPEXPR pArg;3098 } Unary;3099 3100 struct3101 {3102 VBCPPBINARYOP enmOperator;3103 PVBCPPEXPR pLeft;3104 PVBCPPEXPR pRight;3105 } Binary;3106 3107 struct3108 {3109 PVBCPPEXPR pExpr;3110 PVBCPPEXPR pTrue;3111 PVBCPPEXPR pFalse;3112 } Ternary;3113 3114 struct3115 {3116 int64_t s64;3117 } SignedValue;3118 3119 struct3120 {3121 uint64_t u64;3122 } UnsignedValue;3123 3124 } u;3125 } VBCPPEXPR;3126 3127 3128 3129 /**3130 * Operator return statuses.3131 */3132 typedef enum VBCPPEXPRRET3133 {3134 kExprRet_Error = -1,3135 kExprRet_Ok = 0,3136 kExprRet_UnaryOperator,3137 kExprRet_Value,3138 kExprRet_EndOfExpr,3139 kExprRet_End3140 } VBCPPEXPRRET;3141 3142 /**3143 * Expression parser context.3144 */3145 typedef struct VBCPPEXPRPARSER3146 {3147 /** The current expression posistion. */3148 const char *pszCur;3149 /** The root node. */3150 PVBCPPEXPR pRoot;3151 /** The current expression node. */3152 PVBCPPEXPR pCur;3153 /** Where to insert the next expression. */3154 PVBCPPEXPR *ppCur;3155 /** The expression. */3156 const char *pszExpr;3157 /** The number of undefined macros we've encountered while parsing. */3158 size_t cUndefined;3159 /** Pointer to the C preprocessor instance. */3160 PVBCPP pThis;3161 } VBCPPEXPRPARSER;3162 /** Pointer to an expression parser context. */3163 typedef VBCPPEXPRPARSER *PVBCPPEXPRPARSER;3164 3165 3166 3233 /** 3167 3234 * Recursively destroys the expression tree. … … 3199 3266 3200 3267 3201 static VBCPPEXPRRET vbcppExprParserError(PVBCPPEXPRPARSER pParser, const char *pszMsg, ...) 3268 /** 3269 * Report error during expression parsing. 3270 * 3271 * @returns kExprRet_Error 3272 * @param pParser The parser instance. 3273 * @param pszMsg The error message. 3274 * @param ... Format arguments. 3275 */ 3276 static VBCPPEXPRRET vbcppExprParseError(PVBCPPEXPRPARSER pParser, const char *pszMsg, ...) 3202 3277 { 3203 3278 va_list va; … … 3209 3284 3210 3285 3286 /** 3287 * Skip white space. 3288 * 3289 * @param pParser The parser instance. 3290 */ 3211 3291 static void vbcppExprParseSkipWhiteSpace(PVBCPPEXPRPARSER pParser) 3212 3292 { … … 3216 3296 3217 3297 3298 /** 3299 * Allocate a new 3300 * 3301 * @returns Pointer to the node. NULL+msg on failure. 3302 * @param pParser The parser instance. 3303 */ 3218 3304 static PVBCPPEXPR vbcppExprParseAllocNode(PVBCPPEXPRPARSER pParser) 3219 3305 { 3220 3306 PVBCPPEXPR pExpr = (PVBCPPEXPR)RTMemAllocZ(sizeof(*pExpr)); 3307 if (!pExpr) 3308 vbcppExprParseError(pParser, "out of memory (expression node)"); 3221 3309 return pExpr; 3222 3310 } 3223 3311 3224 3312 3225 static VBCPPEXPRRET vbcppExprParserBinaryOrEoeOrRparen(PVBCPPEXPRPARSER pParser) 3313 /** 3314 * Looks for right parentheses and/or end of expression. 3315 * 3316 * @returns Expression status. 3317 * @retval kExprRet_Ok 3318 * @retval kExprRet_Error with msg. 3319 * @retval kExprRet_EndOfExpr 3320 * @param pParser The parser instance. 3321 */ 3322 static VBCPPEXPRRET vbcppExprParseMaybeRParenOrEoe(PVBCPPEXPRPARSER pParser) 3226 3323 { 3227 3324 Assert(!pParser->ppCur); 3228 3229 /*3230 * Right parenthesis closes3231 */3232 char ch;3233 3325 for (;;) 3234 3326 { 3235 3327 vbcppExprParseSkipWhiteSpace(pParser); 3236 ch = *pParser->pszCur;3328 char ch = *pParser->pszCur; 3237 3329 if (ch == '\0') 3238 3330 return kExprRet_EndOfExpr; … … 3253 3345 break; 3254 3346 case kVBCppExprKind_Unary: 3255 AssertReturn(pCur->u.Unary.pArg, vbcppExprParse rError(pParser, "internal error"));3347 AssertReturn(pCur->u.Unary.pArg, vbcppExprParseError(pParser, "internal error")); 3256 3348 pCur->fComplete = true; 3257 3349 break; 3258 3350 case kVBCppExprKind_Binary: 3259 AssertReturn(pCur->u.Binary.pLeft, vbcppExprParse rError(pParser, "internal error"));3260 AssertReturn(pCur->u.Binary.pRight, vbcppExprParse rError(pParser, "internal error"));3351 AssertReturn(pCur->u.Binary.pLeft, vbcppExprParseError(pParser, "internal error")); 3352 AssertReturn(pCur->u.Binary.pRight, vbcppExprParseError(pParser, "internal error")); 3261 3353 pCur->fComplete = true; 3262 3354 break; 3263 3355 case kVBCppExprKind_Ternary: 3264 3356 #if 1 /** @todo Check out the ternary operator implementation. */ 3265 return vbcppExprParse rError(pParser, "The ternary operator is not implemented");3357 return vbcppExprParseError(pParser, "The ternary operator is not implemented"); 3266 3358 #else 3267 3359 Assert(pCur->u.Ternary.pExpr); 3268 3360 if (!pCur->u.Ternary.pTrue) 3269 return vbcppExprParse rError(pParser, "?!?!?");3361 return vbcppExprParseError(pParser, "?!?!?"); 3270 3362 if (!pCur->u.Ternary.pFalse) 3271 return vbcppExprParse rError(pParser, "?!?!?!?");3363 return vbcppExprParseError(pParser, "?!?!?!?"); 3272 3364 pCur->fComplete = true; 3273 3365 #endif 3274 3366 break; 3275 3367 default: 3276 return vbcppExprParse rError(pParser, "Internal error (enmKind=%d)", pCur->enmKind);3368 return vbcppExprParseError(pParser, "Internal error (enmKind=%d)", pCur->enmKind); 3277 3369 } 3278 3370 pCur = pCur->pParent; 3279 3371 } 3280 3372 if (!pCur) 3281 return vbcppExprParse rError(pParser, "Right parenthesis without a left one");3373 return vbcppExprParseError(pParser, "Right parenthesis without a left one"); 3282 3374 pCur->fComplete = true; 3283 3375 … … 3286 3378 && pCur->pParent) 3287 3379 { 3288 AssertReturn(pCur->u.Unary.pArg, vbcppExprParse rError(pParser, "internal error"));3380 AssertReturn(pCur->u.Unary.pArg, vbcppExprParseError(pParser, "internal error")); 3289 3381 pCur->fComplete = true; 3290 3382 pCur = pCur->pParent; … … 3292 3384 } 3293 3385 3386 return kExprRet_Ok; 3387 } 3388 3389 3390 /** 3391 * Parses an binary operator. 3392 * 3393 * @returns Expression status. 3394 * @retval kExprRet_Ok 3395 * @retval kExprRet_Error with msg. 3396 * @param pParser The parser instance. 3397 */ 3398 static VBCPPEXPRRET vbcppExprParseBinaryOperator(PVBCPPEXPRPARSER pParser) 3399 { 3294 3400 /* 3295 3401 * Binary or ternary operator should follow now. 3296 3402 */ 3297 3403 VBCPPBINARYOP enmOp; 3404 char ch = *pParser->pszCur; 3298 3405 switch (ch) 3299 3406 { 3300 3407 case '*': 3301 3408 if (pParser->pszCur[1] == '=') 3302 return vbcppExprParse rError(pParser, "The assignment by product operator is not valid in a preprocessor expression");3409 return vbcppExprParseError(pParser, "The assignment by product operator is not valid in a preprocessor expression"); 3303 3410 enmOp = kVBCppBinary_Multiplication; 3304 3411 break; 3305 3412 case '/': 3306 3413 if (pParser->pszCur[1] == '=') 3307 return vbcppExprParse rError(pParser, "The assignment by quotient operator is not valid in a preprocessor expression");3414 return vbcppExprParseError(pParser, "The assignment by quotient operator is not valid in a preprocessor expression"); 3308 3415 enmOp = kVBCppBinary_Division; 3309 3416 break; 3310 3417 case '%': 3311 3418 if (pParser->pszCur[1] == '=') 3312 return vbcppExprParse rError(pParser, "The assignment by remainder operator is not valid in a preprocessor expression");3419 return vbcppExprParseError(pParser, "The assignment by remainder operator is not valid in a preprocessor expression"); 3313 3420 enmOp = kVBCppBinary_Modulo; 3314 3421 break; 3315 3422 case '+': 3316 3423 if (pParser->pszCur[1] == '=') 3317 return vbcppExprParse rError(pParser, "The assignment by sum operator is not valid in a preprocessor expression");3424 return vbcppExprParseError(pParser, "The assignment by sum operator is not valid in a preprocessor expression"); 3318 3425 enmOp = kVBCppBinary_Addition; 3319 3426 break; 3320 3427 case '-': 3321 3428 if (pParser->pszCur[1] == '=') 3322 return vbcppExprParse rError(pParser, "The assignment by difference operator is not valid in a preprocessor expression");3429 return vbcppExprParseError(pParser, "The assignment by difference operator is not valid in a preprocessor expression"); 3323 3430 enmOp = kVBCppBinary_Subtraction; 3324 3431 break; … … 3334 3441 pParser->pszCur++; 3335 3442 if (pParser->pszCur[1] == '=') 3336 return vbcppExprParse rError(pParser, "The assignment by bitwise left shift operator is not valid in a preprocessor expression");3443 return vbcppExprParseError(pParser, "The assignment by bitwise left shift operator is not valid in a preprocessor expression"); 3337 3444 enmOp = kVBCppBinary_LeftShift; 3338 3445 } … … 3349 3456 pParser->pszCur++; 3350 3457 if (pParser->pszCur[1] == '=') 3351 return vbcppExprParse rError(pParser, "The assignment by bitwise right shift operator is not valid in a preprocessor expression");3458 return vbcppExprParseError(pParser, "The assignment by bitwise right shift operator is not valid in a preprocessor expression"); 3352 3459 enmOp = kVBCppBinary_LeftShift; 3353 3460 } … … 3355 3462 case '=': 3356 3463 if (pParser->pszCur[1] != '=') 3357 return vbcppExprParse rError(pParser, "The assignment operator is not valid in a preprocessor expression");3464 return vbcppExprParseError(pParser, "The assignment operator is not valid in a preprocessor expression"); 3358 3465 pParser->pszCur++; 3359 3466 enmOp = kVBCppBinary_EqualTo; … … 3362 3469 case '!': 3363 3470 if (pParser->pszCur[1] != '=') 3364 return vbcppExprParse rError(pParser, "Expected binary operator, found the unary operator logical NOT");3471 return vbcppExprParseError(pParser, "Expected binary operator, found the unary operator logical NOT"); 3365 3472 pParser->pszCur++; 3366 3473 enmOp = kVBCppBinary_NotEqualTo; … … 3369 3476 case '&': 3370 3477 if (pParser->pszCur[1] == '=') 3371 return vbcppExprParse rError(pParser, "The assignment by bitwise AND operator is not valid in a preprocessor expression");3478 return vbcppExprParseError(pParser, "The assignment by bitwise AND operator is not valid in a preprocessor expression"); 3372 3479 if (pParser->pszCur[1] == '&') 3373 3480 { … … 3380 3487 case '^': 3381 3488 if (pParser->pszCur[1] == '=') 3382 return vbcppExprParse rError(pParser, "The assignment by bitwise XOR operator is not valid in a preprocessor expression");3489 return vbcppExprParseError(pParser, "The assignment by bitwise XOR operator is not valid in a preprocessor expression"); 3383 3490 enmOp = kVBCppBinary_BitwiseXor; 3384 3491 break; 3385 3492 case '|': 3386 3493 if (pParser->pszCur[1] == '=') 3387 return vbcppExprParse rError(pParser, "The assignment by bitwise AND operator is not valid in a preprocessor expression");3494 return vbcppExprParseError(pParser, "The assignment by bitwise AND operator is not valid in a preprocessor expression"); 3388 3495 if (pParser->pszCur[1] == '|') 3389 3496 { … … 3395 3502 break; 3396 3503 case '~': 3397 return vbcppExprParse rError(pParser, "Expected binary operator, found the unary operator bitwise NOT");3504 return vbcppExprParseError(pParser, "Expected binary operator, found the unary operator bitwise NOT"); 3398 3505 3399 3506 case ':': 3400 3507 case '?': 3401 return vbcppExprParse rError(pParser, "The ternary operator is not yet implemented");3508 return vbcppExprParseError(pParser, "The ternary operator is not yet implemented"); 3402 3509 3403 3510 default: 3404 return vbcppExprParse rError(pParser, "Expected binary operator, found '%.20s'", pParser->pszCur);3511 return vbcppExprParseError(pParser, "Expected binary operator, found '%.20s'", pParser->pszCur); 3405 3512 } 3406 3513 pParser->pszCur++; … … 3433 3540 break; 3434 3541 } 3435 AssertReturn(pParent->u.Unary.pArg, vbcppExprParse rError(pParser, "internal error"));3542 AssertReturn(pParent->u.Unary.pArg, vbcppExprParseError(pParser, "internal error")); 3436 3543 pParent->fComplete = true; 3437 3544 } 3438 3545 else if (pParent->enmKind == kVBCppExprKind_Binary) 3439 3546 { 3440 AssertReturn(pParent->u.Binary.pLeft, vbcppExprParse rError(pParser, "internal error"));3441 AssertReturn(pParent->u.Binary.pRight, vbcppExprParse rError(pParser, "internal error"));3547 AssertReturn(pParent->u.Binary.pLeft, vbcppExprParseError(pParser, "internal error")); 3548 AssertReturn(pParent->u.Binary.pRight, vbcppExprParseError(pParser, "internal error")); 3442 3549 if ((pParent->u.Binary.enmOperator & VBCPPOP_PRECEDENCE_MASK) >= (enmOp & VBCPPOP_PRECEDENCE_MASK)) 3443 3550 { 3444 AssertReturn(pChild, vbcppExprParse rError(pParser, "internal error"));3551 AssertReturn(pChild, vbcppExprParseError(pParser, "internal error")); 3445 3552 3446 3553 if (pParent->u.Binary.pRight == pChild) … … 3448 3555 else 3449 3556 ppPlace = &pParent->u.Binary.pLeft; 3450 AssertReturn(*ppPlace == pChild, vbcppExprParse rError(pParser, "internal error"));3557 AssertReturn(*ppPlace == pChild, vbcppExprParseError(pParser, "internal error")); 3451 3558 break; 3452 3559 } … … 3455 3562 else if (pParent->enmKind == kVBCppExprKind_Ternary) 3456 3563 { 3457 return vbcppExprParse rError(pParser, "The ternary operator is not implemented");3564 return vbcppExprParseError(pParser, "The ternary operator is not implemented"); 3458 3565 } 3459 3566 else 3460 3567 AssertReturn( pParent->enmKind == kVBCppExprKind_SignedValue 3461 3568 || pParent->enmKind == kVBCppExprKind_UnsignedValue, 3462 vbcppExprParse rError(pParser, "internal error"));3569 vbcppExprParseError(pParser, "internal error")); 3463 3570 3464 3571 /* Up on level */ … … 3489 3596 3490 3597 3598 /** 3599 * Deals with right paretheses or/and end of expression, looks for binary 3600 * operators. 3601 * 3602 * @returns Expression status. 3603 * @retval kExprRet_Ok if binary operator was found processed. 3604 * @retval kExprRet_Error with msg. 3605 * @retval kExprRet_EndOfExpr 3606 * @param pParser The parser instance. 3607 */ 3608 static VBCPPEXPRRET vbcppExprParseBinaryOrEoeOrRparen(PVBCPPEXPRPARSER pParser) 3609 { 3610 VBCPPEXPRRET enmRet = vbcppExprParseMaybeRParenOrEoe(pParser); 3611 if (enmRet != kExprRet_Ok) 3612 return enmRet; 3613 return vbcppExprParseBinaryOperator(pParser); 3614 } 3615 3616 3617 /** 3618 * Parses an identifier in the expression, replacing it by 0. 3619 * 3620 * All known identifiers has already been replaced by their macro values, so 3621 * what's left are unknown macros. These are replaced by 0. 3622 * 3623 * @returns Expression status. 3624 * @retval kExprRet_Value 3625 * @retval kExprRet_Error with msg. 3626 * @param pParser The parser instance. 3627 */ 3491 3628 static VBCPPEXPRRET vbcppExprParseIdentifier(PVBCPPEXPRPARSER pParser) 3492 3629 { 3630 /** @todo don't increment if it's an actively undefined macro. Need to revise 3631 * the expression related code wrt selective preprocessing. */ 3493 3632 pParser->cUndefined++; 3494 3633 … … 3518 3657 vbcppExprParseSkipWhiteSpace(pParser); 3519 3658 if (*pParser->pszCur == '(') 3520 return vbcppExprParserError(pParser, "Unknown unary operator '%.*s'", cchMacro, pszMacro); 3521 3659 return vbcppExprParseError(pParser, "Unknown unary operator '%.*s'", cchMacro, pszMacro); 3522 3660 3523 3661 return kExprRet_Value; 3524 3525 } 3526 3527 3662 } 3663 3664 3665 /** 3666 * Parses an numeric constant in the expression. 3667 * 3668 * @returns Expression status. 3669 * @retval kExprRet_Value 3670 * @retval kExprRet_Error with msg. 3671 * @param pParser The parser instance. 3672 */ 3528 3673 static VBCPPEXPRRET vbcppExprParseNumber(PVBCPPEXPRPARSER pParser) 3529 3674 { … … 3538 3683 ch2 = *++pParser->pszCur; 3539 3684 if (!RT_C_IS_XDIGIT(ch2)) 3540 return vbcppExprParse rError(pParser, "Expected hex digit following '0x'");3685 return vbcppExprParseError(pParser, "Expected hex digit following '0x'"); 3541 3686 int rc = RTStrToUInt64Ex(pParser->pszCur, &pszNext, 16, &u64); 3542 3687 if ( RT_FAILURE(rc) 3543 3688 || rc == VWRN_NUMBER_TOO_BIG) 3544 return vbcppExprParse rError(pParser, "Invalid hex value '%.20s...' (%Rrc)", pParser->pszCur, rc);3689 return vbcppExprParseError(pParser, "Invalid hex value '%.20s...' (%Rrc)", pParser->pszCur, rc); 3545 3690 fSigned = false; 3546 3691 } … … 3550 3695 if ( RT_FAILURE(rc) 3551 3696 || rc == VWRN_NUMBER_TOO_BIG) 3552 return vbcppExprParse rError(pParser, "Invalid octal value '%.20s...' (%Rrc)", pParser->pszCur, rc);3697 return vbcppExprParseError(pParser, "Invalid octal value '%.20s...' (%Rrc)", pParser->pszCur, rc); 3553 3698 fSigned = u64 > (uint64_t)INT64_MAX ? false : true; 3554 3699 } … … 3558 3703 if ( RT_FAILURE(rc) 3559 3704 || rc == VWRN_NUMBER_TOO_BIG) 3560 return vbcppExprParse rError(pParser, "Invalid decimal value '%.20s...' (%Rrc)", pParser->pszCur, rc);3705 return vbcppExprParseError(pParser, "Invalid decimal value '%.20s...' (%Rrc)", pParser->pszCur, rc); 3561 3706 fSigned = u64 > (uint64_t)INT64_MAX ? false : true; 3562 3707 } … … 3584 3729 fSigned = false; 3585 3730 else 3586 return vbcppExprParse rError(pParser, "Invalid number suffix '%.*s'", cchSuffix, pszNext);3731 return vbcppExprParseError(pParser, "Invalid number suffix '%.*s'", cchSuffix, pszNext); 3587 3732 3588 3733 pszNext += cchSuffix; … … 3616 3761 3617 3762 3763 /** 3764 * Parses an character constant in the expression. 3765 * 3766 * @returns Expression status. 3767 * @retval kExprRet_Value 3768 * @retval kExprRet_Error with msg. 3769 * @param pParser The parser instance. 3770 */ 3618 3771 static VBCPPEXPRRET vbcppExprParseCharacterConstant(PVBCPPEXPRPARSER pParser) 3619 3772 { … … 3621 3774 char ch2 = *pParser->pszCur++; 3622 3775 if (ch2 == '\'') 3623 return vbcppExprParse rError(pParser, "Empty character constant");3776 return vbcppExprParseError(pParser, "Empty character constant"); 3624 3777 int64_t s64; 3625 3778 if (ch2 == '\\') … … 3633 3786 case 't': s64 = 0x09; break; 3634 3787 default: 3635 return vbcppExprParse rError(pParser, "Escape character '%c' is not implemented", ch2);3788 return vbcppExprParseError(pParser, "Escape character '%c' is not implemented", ch2); 3636 3789 } 3637 3790 } … … 3639 3792 s64 = ch2; 3640 3793 if (*pParser->pszCur != '\'') 3641 return vbcppExprParse rError(pParser, "Character constant contains more than one character");3794 return vbcppExprParseError(pParser, "Character constant contains more than one character"); 3642 3795 3643 3796 /* Create a signed value node. */ … … 3659 3812 3660 3813 3661 static VBCPPEXPRRET vbcppExprParseUnaryOrValueOrEoe(PVBCPPEXPRPARSER pParser) 3814 /** 3815 * Parses a unary operator or a value. 3816 * 3817 * @returns Expression status. 3818 * @retval kExprRet_Value if value was found and processed. 3819 * @retval kExprRet_UnaryOperator if an unary operator was found and processed. 3820 * @retval kExprRet_Error with msg. 3821 * @param pParser The parser instance. 3822 */ 3823 static VBCPPEXPRRET vbcppExprParseUnaryOrValue(PVBCPPEXPRPARSER pParser) 3662 3824 { 3663 3825 vbcppExprParseSkipWhiteSpace(pParser); 3664 3826 char ch = *pParser->pszCur; 3665 3827 if (ch == '\0') 3666 return vbcppExprParse rError(pParser, "Premature end of expression");3828 return vbcppExprParseError(pParser, "Premature end of expression"); 3667 3829 3668 3830 /* … … 3674 3836 return vbcppExprParseNumber(pParser); 3675 3837 if (ch == '"') 3676 return vbcppExprParse rError(pParser, "String litteral");3838 return vbcppExprParseError(pParser, "String litteral"); 3677 3839 if (vbcppIsCIdentifierLeadChar(ch)) 3678 3840 return vbcppExprParseIdentifier(pParser); … … 3686 3848 enmOperator = kVBCppUnaryOp_Pluss; 3687 3849 if (pParser->pszCur[1] == '+') 3688 return vbcppExprParse rError(pParser, "The prefix increment operator is not valid in a preprocessor expression");3850 return vbcppExprParseError(pParser, "The prefix increment operator is not valid in a preprocessor expression"); 3689 3851 } 3690 3852 else if (ch == '-') … … 3692 3854 enmOperator = kVBCppUnaryOp_Minus; 3693 3855 if (pParser->pszCur[1] == '-') 3694 return vbcppExprParse rError(pParser, "The prefix decrement operator is not valid in a preprocessor expression");3856 return vbcppExprParseError(pParser, "The prefix decrement operator is not valid in a preprocessor expression"); 3695 3857 } 3696 3858 else if (ch == '!') … … 3701 3863 enmOperator = kVBCppUnaryOp_Parenthesis; 3702 3864 else 3703 return vbcppExprParse rError(pParser, "Unknown token '%.*s'", 32, pParser->pszCur - 1);3865 return vbcppExprParseError(pParser, "Unknown token '%.*s'", 32, pParser->pszCur - 1); 3704 3866 pParser->pszCur++; 3705 3867 … … 3723 3885 3724 3886 3725 3887 /** 3888 * Parses an expanded preprocessor expression. 3889 * 3890 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg. 3891 * @param pThis The C preprocessor instance. 3892 * @param pszExpr The expression to parse. 3893 * @param cchExpr The length of the expression in case we need it. 3894 * @param ppExprTree Where to return the parse tree. 3895 * @param pcUndefined Where to return the number of unknown undefined 3896 * macros. Optional. 3897 */ 3726 3898 static RTEXITCODE vbcppExprParse(PVBCPP pThis, char *pszExpr, size_t cchExpr, PVBCPPEXPR *ppExprTree, size_t *pcUndefined) 3727 3899 { 3728 3900 RTEXITCODE rcExit = RTEXITCODE_FAILURE; 3901 NOREF(cchExpr); 3729 3902 3730 3903 /* … … 3750 3923 */ 3751 3924 do 3752 enmRet = vbcppExprParseUnaryOrValue OrEoe(&Parser);3925 enmRet = vbcppExprParseUnaryOrValue(&Parser); 3753 3926 while (enmRet == kExprRet_UnaryOperator); 3754 3927 if (enmRet == kExprRet_Error) 3755 3928 break; 3756 AssertBreakStmt(enmRet == kExprRet_Value, enmRet = vbcppExprParse rError(&Parser, "Expected value (enmRet=%d)", enmRet));3929 AssertBreakStmt(enmRet == kExprRet_Value, enmRet = vbcppExprParseError(&Parser, "Expected value (enmRet=%d)", enmRet)); 3757 3930 3758 3931 /* 3759 3932 * Non-unary operator, right parenthesis or end of expression is up next. 3760 3933 */ 3761 enmRet = vbcppExprParse rBinaryOrEoeOrRparen(&Parser);3934 enmRet = vbcppExprParseBinaryOrEoeOrRparen(&Parser); 3762 3935 if (enmRet == kExprRet_Error) 3763 3936 break; … … 3768 3941 break; 3769 3942 } 3770 AssertBreakStmt(enmRet == kExprRet_Ok, enmRet = vbcppExprParse rError(&Parser, "Expected value (enmRet=%d)", enmRet));3943 AssertBreakStmt(enmRet == kExprRet_Ok, enmRet = vbcppExprParseError(&Parser, "Expected value (enmRet=%d)", enmRet)); 3771 3944 } 3772 3945 … … 3784 3957 3785 3958 3959 /** 3960 * Checks if an expression value value is evaluates to @c true or @c false. 3961 * 3962 * @returns @c true or @c false. 3963 * @param pExpr The value expression. 3964 */ 3786 3965 static bool vbcppExprIsExprTrue(PVBCPPEXPR pExpr) 3787 3966 { 3788 3967 Assert(pExpr->enmKind == kVBCppExprKind_SignedValue || pExpr->enmKind == kVBCppExprKind_UnsignedValue); 3968 3789 3969 return pExpr->enmKind == kVBCppExprKind_SignedValue 3790 3970 ? pExpr->u.SignedValue.s64 != 0 … … 3793 3973 3794 3974 3975 /** 3976 * Evalutes a parse (sub-)tree. 3977 * 3978 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE+msg. 3979 * @param pThis The C preprocessor instance. 3980 * @param pRoot The root of the parse (sub-)tree. 3981 * @param pResult Where to store the result value. 3982 */ 3795 3983 static RTEXITCODE vbcppExprEvaluteTree(PVBCPP pThis, PVBCPPEXPR pRoot, PVBCPPEXPR pResult) 3796 3984 { … … 3865 4053 /* Evalute the right side. */ 3866 4054 VBCPPEXPR Result2; 3867 rcExit = vbcppExprEvaluteTree(pThis, pRoot->u.Binary.p Left, &Result2);4055 rcExit = vbcppExprEvaluteTree(pThis, pRoot->u.Binary.pRight, &Result2); 3868 4056 if (rcExit != RTEXITCODE_SUCCESS) 3869 4057 return rcExit; … … 4044 4232 static RTEXITCODE vbcppExprEval(PVBCPP pThis, char *pszExpr, size_t cchExpr, size_t cReplacements, VBCPPEVAL *penmResult) 4045 4233 { 4046 //Assert(strlen(pszExpr) == cchExpr);4234 Assert(strlen(pszExpr) == cchExpr); 4047 4235 size_t cUndefined; 4048 4236 PVBCPPEXPR pExprTree; … … 4199 4387 } 4200 4388 else if (ch == '\r' || ch == '\n') 4201 {4202 4389 break; /* done */ 4203 } 4204 else if (RT_C_IS_SPACE(ch) && RT_C_IS_SPACE(vbcppStrBufLastCh(pStrBuf))) 4390 else if ( RT_C_IS_SPACE(ch) 4391 && ( RT_C_IS_SPACE(vbcppStrBufLastCh(pStrBuf)) 4392 || vbcppStrBufLastCh(pStrBuf) == '\0') ) 4205 4393 { 4206 4394 unsigned ch2 = ScmStreamGetCh(pStrmInput); 4207 4395 Assert(ch == ch2); 4396 rcExit = RTEXITCODE_SUCCESS; 4208 4397 } 4209 4398 else … … 4217 4406 { 4218 4407 ScmStreamSeekByLine(pStrmInput, ScmStreamTellLine(pStrmInput) + 1); 4408 rcExit = RTEXITCODE_SUCCESS; 4219 4409 } 4220 4410 else
Note:
See TracChangeset
for help on using the changeset viewer.