VirtualBox

儲存庫 vbox 的更動 52371


忽略:
時間撮記:
2014-8-13 下午07:00:27 (10 年 以前)
作者:
vboxsync
訊息:

Storage/tstVDIo: Plug leaks, modifications and start turning it into a proper testcase for unit tests

位置:
trunk/src/VBox/Storage/testcase
檔案:
新增 1 筆資料
修改 12 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/Storage/testcase/VDMemDisk.cpp

    r36635 r52371  
    9090
    9191    RTAvlrU64Destroy(pMemDisk->pTreeSegments, vdMemDiskDestroy, NULL);
     92    RTMemFree(pMemDisk->pTreeSegments);
    9293    RTMemFree(pMemDisk);
    9394}
  • trunk/src/VBox/Storage/testcase/VDScript.cpp

    r44964 r52371  
    8989    VDSCRIPTTOKENKEYWORD_INVALID = 0,
    9090    VDSCRIPTTOKENKEYWORD_CONTINUE,
     91    VDSCRIPTTOKENKEYWORD_REGISTER,
     92    VDSCRIPTTOKENKEYWORD_RESTRICT,
     93    VDSCRIPTTOKENKEYWORD_VOLATILE,
     94    VDSCRIPTTOKENKEYWORD_TYPEDEF,
    9195    VDSCRIPTTOKENKEYWORD_DEFAULT,
     96    VDSCRIPTTOKENKEYWORD_EXTERN,
     97    VDSCRIPTTOKENKEYWORD_STATIC,
    9298    VDSCRIPTTOKENKEYWORD_RETURN,
    9399    VDSCRIPTTOKENKEYWORD_SWITCH,
     100    VDSCRIPTTOKENKEYWORD_STRUCT,
    94101    VDSCRIPTTOKENKEYWORD_WHILE,
    95102    VDSCRIPTTOKENKEYWORD_BREAK,
     103    VDSCRIPTTOKENKEYWORD_CONST,
    96104    VDSCRIPTTOKENKEYWORD_FALSE,
    97105    VDSCRIPTTOKENKEYWORD_TRUE,
    98106    VDSCRIPTTOKENKEYWORD_ELSE,
    99107    VDSCRIPTTOKENKEYWORD_CASE,
     108    VDSCRIPTTOKENKEYWORD_AUTO,
    100109    VDSCRIPTTOKENKEYWORD_FOR,
    101110    VDSCRIPTTOKENKEYWORD_IF,
     
    220229    {">=",  2},
    221230    {"<=",  2},
     231    {"->",  2},
    222232    {"=",   1},
    223233    {"+",   1},
     
    232242    {">",   1},
    233243    {"!",   1},
    234     {"~",   1}
     244    {"~",   1},
     245    {".",   1}
    235246};
    236247
     
    269280{
    270281    {"continue", 8, VDSCRIPTTOKENKEYWORD_CONTINUE},
     282    {"register", 8, VDSCRIPTTOKENKEYWORD_REGISTER},
     283    {"restrict", 8, VDSCRIPTTOKENKEYWORD_RESTRICT},
     284    {"voaltile", 8, VDSCRIPTTOKENKEYWORD_VOLATILE},
     285    {"typedef",  7, VDSCRIPTTOKENKEYWORD_TYPEDEF},
    271286    {"default",  7, VDSCRIPTTOKENKEYWORD_DEFAULT},
     287    {"extern",   6, VDSCRIPTTOKENKEYWORD_EXTERN},
     288    {"static",   6, VDSCRIPTTOKENKEYWORD_STATIC},
    272289    {"return",   6, VDSCRIPTTOKENKEYWORD_RETURN},
    273290    {"switch",   6, VDSCRIPTTOKENKEYWORD_SWITCH},
     291    {"struct",   6, VDSCRIPTTOKENKEYWORD_STRUCT},
    274292    {"while",    5, VDSCRIPTTOKENKEYWORD_WHILE},
    275293    {"break",    5, VDSCRIPTTOKENKEYWORD_BREAK},
     294    {"const",    5, VDSCRIPTTOKENKEYWORD_CONST},
    276295    {"false",    5, VDSCRIPTTOKENKEYWORD_FALSE},
    277296    {"true",     4, VDSCRIPTTOKENKEYWORD_TRUE},
    278297    {"else",     4, VDSCRIPTTOKENKEYWORD_ELSE},
    279298    {"case",     4, VDSCRIPTTOKENKEYWORD_CASE},
     299    {"auto",     4, VDSCRIPTTOKENKEYWORD_AUTO},
    280300    {"for",      3, VDSCRIPTTOKENKEYWORD_FOR},
    281301    {"if",       2, VDSCRIPTTOKENKEYWORD_IF},
     
    287307static int vdScriptParseExpression(PVDSCRIPTCTXINT pThis, PVDSCRIPTASTEXPR *ppAstNodeExpr);
    288308static int vdScriptParseAssignmentExpression(PVDSCRIPTCTXINT pThis, PVDSCRIPTASTEXPR *ppAstNodeExpr);
     309static int vdScriptParseCastExpression(PVDSCRIPTCTXINT pThis, PVDSCRIPTASTEXPR *ppAstNodeExpr);
     310static int vdScriptParseConstExpression(PVDSCRIPTCTXINT pThis, PVDSCRIPTASTEXPR *ppAstNodeExpr);
    289311
    290312/**
     
    520542    {
    521543        pToken->Class.NumConst.u64 *= _1G;
     544        vdScriptTokenizerSkipCh(pTokenizer);
     545    }
     546    else if (vdScriptTokenizerGetCh(pTokenizer) == 'T')
     547    {
     548        pToken->Class.NumConst.u64 *= _1T;
    522549        vdScriptTokenizerSkipCh(pTokenizer);
    523550    }
     
    10321059 *          postfix-expression ++
    10331060 *          postfix-expression --
     1061 *          postfix-expression .  identifier
     1062 *          postfix-expression -> identifier
     1063 * @note: Not supported so far are:
     1064 *          ( type-name ) { initializer-list }
     1065 *          ( type-name ) { initializer-list , }
    10341066 */
    10351067static int vdScriptParsePostfixExpression(PVDSCRIPTCTXINT pThis, PVDSCRIPTASTEXPR *ppAstNodeExpr)
     
    10671099                    pExprNew->pExpr = pExpr;
    10681100                    pExpr = pExprNew;
     1101                }
     1102                else
     1103                    rc = vdScriptParserError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Parser: Out of memory allocating expression AST node\n");
     1104            }
     1105            else if (vdScriptTokenizerSkipIfIsOperatorEqual(pThis->pTokenizer, "->"))
     1106            {
     1107                pExprNew = (PVDSCRIPTASTEXPR)vdScriptAstNodeAlloc(VDSCRIPTASTCLASS_EXPRESSION);
     1108                if (pExprNew)
     1109                {
     1110                    PVDSCRIPTASTIDE pIde = NULL;
     1111                    rc = vdScriptParseIde(pThis, &pIde);
     1112                    if (RT_SUCCESS(rc))
     1113                    {
     1114                        pExprNew->enmType = VDSCRIPTEXPRTYPE_POSTFIX_DEREFERENCE;
     1115                        pExprNew->Deref.pIde = pIde;
     1116                        pExprNew->Deref.pExpr = pExpr;
     1117                        pExpr = pExprNew;
     1118                    }
     1119                    else
     1120                        vdScriptAstNodeFree(&pExprNew->Core);
     1121                }
     1122                else
     1123                    rc = vdScriptParserError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Parser: Out of memory allocating expression AST node\n");
     1124            }
     1125            else if (vdScriptTokenizerSkipIfIsOperatorEqual(pThis->pTokenizer, "."))
     1126            {
     1127                pExprNew = (PVDSCRIPTASTEXPR)vdScriptAstNodeAlloc(VDSCRIPTASTCLASS_EXPRESSION);
     1128                if (pExprNew)
     1129                {
     1130                    PVDSCRIPTASTIDE pIde = NULL;
     1131                    rc = vdScriptParseIde(pThis, &pIde);
     1132                    if (RT_SUCCESS(rc))
     1133                    {
     1134                        pExprNew->enmType = VDSCRIPTEXPRTYPE_POSTFIX_DOT;
     1135                        pExprNew->Deref.pIde = pIde;
     1136                        pExprNew->Deref.pExpr = pExpr;
     1137                        pExpr = pExprNew;
     1138                    }
     1139                    else
     1140                        vdScriptAstNodeFree(&pExprNew->Core);
    10691141                }
    10701142                else
     
    11151187 *          ++ unary-expression
    11161188 *          -- unary-expression
    1117  *          + unary-expression
    1118  *          - unary-expression
    1119  *          ~ unary-expression
    1120  *          ! unary-expression
     1189 *          + cast-expression
     1190 *          - cast-expression
     1191 *          ~ cast-expression
     1192 *          ! cast-expression
     1193 *          & cast-expression
     1194 *          * cast-expression
    11211195 */
    11221196static int vdScriptParseUnaryExpression(PVDSCRIPTCTXINT pThis, PVDSCRIPTASTEXPR *ppAstNodeExpr)
     
    11281202    LogFlowFunc(("pThis=%p ppAstNodeExpr=%p\n"));
    11291203
     1204    /** @todo: Think about a more beautiful way of parsing this. */
    11301205    while (true)
    11311206    {
    11321207        bool fQuit = false;
     1208        bool fCastExprFollows = false;
    11331209        PVDSCRIPTASTEXPR pExprNew = NULL;
     1210        VDSCRIPTEXPRTYPE enmType = VDSCRIPTEXPRTYPE_INVALID;
    11341211
    11351212        if (vdScriptTokenizerSkipIfIsOperatorEqual(pThis->pTokenizer, "++"))
     1213            enmType = VDSCRIPTEXPRTYPE_UNARY_INCREMENT;
     1214        else if (vdScriptTokenizerSkipIfIsOperatorEqual(pThis->pTokenizer, "--"))
     1215            enmType = VDSCRIPTEXPRTYPE_UNARY_DECREMENT;
     1216        else if (vdScriptTokenizerSkipIfIsOperatorEqual(pThis->pTokenizer, "+"))
     1217        {
     1218            enmType = VDSCRIPTEXPRTYPE_UNARY_POSSIGN;
     1219            fCastExprFollows = true;
     1220        }
     1221        else if (vdScriptTokenizerSkipIfIsOperatorEqual(pThis->pTokenizer, "-"))
     1222        {
     1223            enmType = VDSCRIPTEXPRTYPE_UNARY_NEGSIGN;
     1224            fCastExprFollows = true;
     1225        }
     1226        else if (vdScriptTokenizerSkipIfIsOperatorEqual(pThis->pTokenizer, "~"))
     1227        {
     1228            enmType = VDSCRIPTEXPRTYPE_UNARY_INVERT;
     1229            fCastExprFollows = true;
     1230        }
     1231        else if (vdScriptTokenizerSkipIfIsOperatorEqual(pThis->pTokenizer, "!"))
     1232        {
     1233            enmType = VDSCRIPTEXPRTYPE_UNARY_NEGATE;
     1234            fCastExprFollows = true;
     1235        }
     1236        else if (vdScriptTokenizerSkipIfIsOperatorEqual(pThis->pTokenizer, "&"))
     1237        {
     1238            enmType = VDSCRIPTEXPRTYPE_UNARY_REFERENCE;
     1239            fCastExprFollows = true;
     1240        }
     1241        else if (vdScriptTokenizerSkipIfIsOperatorEqual(pThis->pTokenizer, "*"))
     1242        {
     1243            enmType = VDSCRIPTEXPRTYPE_UNARY_DEREFERENCE;
     1244            fCastExprFollows = true;
     1245        }
     1246
     1247        if (enmType != VDSCRIPTEXPRTYPE_INVALID)
    11361248        {
    11371249            pExprNew = (PVDSCRIPTASTEXPR)vdScriptAstNodeAlloc(VDSCRIPTASTCLASS_EXPRESSION);
    11381250            if (pExprNew)
    1139                 pExprNew->enmType = VDSCRIPTEXPRTYPE_UNARY_INCREMENT;
     1251                pExprNew->enmType = enmType;
    11401252            else
    11411253                rc = vdScriptParserError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Parser: Out of memory allocating expression AST node\n");
    1142         }
    1143         else if (vdScriptTokenizerSkipIfIsOperatorEqual(pThis->pTokenizer, "--"))
    1144         {
    1145             pExprNew = (PVDSCRIPTASTEXPR)vdScriptAstNodeAlloc(VDSCRIPTASTCLASS_EXPRESSION);
    1146             if (pExprNew)
    1147                 pExprNew->enmType = VDSCRIPTEXPRTYPE_UNARY_DECREMENT;
    1148             else
    1149                 rc = vdScriptParserError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Parser: Out of memory allocating expression AST node\n");
    1150         }
    1151         else if (vdScriptTokenizerSkipIfIsOperatorEqual(pThis->pTokenizer, "+"))
    1152         {
    1153             pExprNew = (PVDSCRIPTASTEXPR)vdScriptAstNodeAlloc(VDSCRIPTASTCLASS_EXPRESSION);
    1154             if (pExprNew)
    1155                 pExprNew->enmType = VDSCRIPTEXPRTYPE_UNARY_POSSIGN;
    1156             else
    1157                 rc = vdScriptParserError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Parser: Out of memory allocating expression AST node\n");
    1158         }
    1159         else if (vdScriptTokenizerSkipIfIsOperatorEqual(pThis->pTokenizer, "-"))
    1160         {
    1161             pExprNew = (PVDSCRIPTASTEXPR)vdScriptAstNodeAlloc(VDSCRIPTASTCLASS_EXPRESSION);
    1162             if (pExprNew)
    1163                 pExprNew->enmType = VDSCRIPTEXPRTYPE_UNARY_NEGSIGN;
    1164             else
    1165                 rc = vdScriptParserError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Parser: Out of memory allocating expression AST node\n");
    1166         }
    1167         else if (vdScriptTokenizerSkipIfIsOperatorEqual(pThis->pTokenizer, "~"))
    1168         {
    1169             pExprNew = (PVDSCRIPTASTEXPR)vdScriptAstNodeAlloc(VDSCRIPTASTCLASS_EXPRESSION);
    1170             if (pExprNew)
    1171                 pExprNew->enmType = VDSCRIPTEXPRTYPE_UNARY_INVERT;
    1172             else
    1173                 rc = vdScriptParserError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Parser: Out of memory allocating expression AST node\n");
    1174         }
    1175         else if (vdScriptTokenizerSkipIfIsOperatorEqual(pThis->pTokenizer, "!"))
    1176         {
    1177             pExprNew = (PVDSCRIPTASTEXPR)vdScriptAstNodeAlloc(VDSCRIPTASTCLASS_EXPRESSION);
    1178             if (pExprNew)
    1179                 pExprNew->enmType = VDSCRIPTEXPRTYPE_UNARY_NEGATE;
    1180             else
    1181                 rc = vdScriptParserError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Parser: Out of memory allocating expression AST node\n");
     1254
     1255            if (   RT_SUCCESS(rc)
     1256                && fCastExprFollows)
     1257            {
     1258                PVDSCRIPTASTEXPR pCastExpr = NULL;
     1259
     1260                rc = vdScriptParseCastExpression(pThis, &pCastExpr);
     1261                if (RT_SUCCESS(rc))
     1262                    pExprNew->pExpr = pCastExpr;
     1263                else
     1264                    vdScriptAstNodeFree(&pExprNew->Core);
     1265                fQuit = true;
     1266            }
    11821267        }
    11831268        else
     
    12171302
    12181303/**
    1219  * Parse a multiplicative expression.
     1304 * Parse a storage class specifier.
     1305 *
     1306 * @returns nothing.
     1307 * @param   pThis                The script context.
     1308 * @param   penmStorageClass     Where to return the parsed storage classe.
     1309 *                               Contains VDSCRIPTASTSTORAGECLASS_INVALID if no
     1310 *                               valid storage class specifier was found.
     1311 *
     1312 * @note Syntax:
     1313 *      typedef
     1314 *      extern
     1315 *      static
     1316 *      auto
     1317 *      register
     1318 */
     1319static void vdScriptParseStorageClassSpecifier(PVDSCRIPTCTXINT pThis, PVDSCRIPTASTSTORAGECLASS penmStorageClass)
     1320{
     1321    *penmStorageClass = VDSCRIPTASTSTORAGECLASS_INVALID;
     1322
     1323    if (vdScriptTokenizerSkipIfIsKeywordEqual(pThis->pTokenizer, VDSCRIPTTOKENKEYWORD_TYPEDEF))
     1324        *penmStorageClass = VDSCRIPTASTSTORAGECLASS_TYPEDEF;
     1325    else if (vdScriptTokenizerSkipIfIsKeywordEqual(pThis->pTokenizer, VDSCRIPTTOKENKEYWORD_EXTERN))
     1326        *penmStorageClass = VDSCRIPTASTSTORAGECLASS_EXTERN;
     1327    else if (vdScriptTokenizerSkipIfIsKeywordEqual(pThis->pTokenizer, VDSCRIPTTOKENKEYWORD_STATIC))
     1328        *penmStorageClass = VDSCRIPTASTSTORAGECLASS_STATIC;
     1329    else if (vdScriptTokenizerSkipIfIsKeywordEqual(pThis->pTokenizer, VDSCRIPTTOKENKEYWORD_AUTO))
     1330        *penmStorageClass = VDSCRIPTASTSTORAGECLASS_AUTO;
     1331    else if (vdScriptTokenizerSkipIfIsKeywordEqual(pThis->pTokenizer, VDSCRIPTTOKENKEYWORD_REGISTER))
     1332        *penmStorageClass = VDSCRIPTASTSTORAGECLASS_REGISTER;
     1333}
     1334
     1335/**
     1336 * Parse a type qualifier.
     1337 *
     1338 * @returns nothing.
     1339 * @param   pThis                The script context.
     1340 * @param   penmTypeQualifier    Where to return the parsed type qualifier.
     1341 *                               Contains VDSCRIPTASTTYPEQUALIFIER_INVALID if no
     1342 *                               valid type qualifier was found.
     1343 *
     1344 * @note Syntax:
     1345 *      const
     1346 *      restrict
     1347 *      volatile
     1348 */
     1349static void vdScriptParseTypeQualifier(PVDSCRIPTCTXINT pThis, PVDSCRIPTASTTYPEQUALIFIER penmTypeQualifier)
     1350{
     1351    *penmTypeQualifier = VDSCRIPTASTTYPEQUALIFIER_INVALID;
     1352
     1353    if (vdScriptTokenizerSkipIfIsKeywordEqual(pThis->pTokenizer, VDSCRIPTTOKENKEYWORD_CONST))
     1354        *penmTypeQualifier = VDSCRIPTASTTYPEQUALIFIER_CONST;
     1355    else if (vdScriptTokenizerSkipIfIsKeywordEqual(pThis->pTokenizer, VDSCRIPTTOKENKEYWORD_RESTRICT))
     1356        *penmTypeQualifier = VDSCRIPTASTTYPEQUALIFIER_RESTRICT;
     1357    else if (vdScriptTokenizerSkipIfIsKeywordEqual(pThis->pTokenizer, VDSCRIPTTOKENKEYWORD_VOLATILE))
     1358        *penmTypeQualifier = VDSCRIPTASTTYPEQUALIFIER_VOLATILE;
     1359}
     1360
     1361#if 0
     1362/**
     1363 * Parse a struct or union specifier.
     1364 *
     1365 * @returns VBox status code.
     1366 * @param   pThis                The script context.
     1367 * @param   ppAstTypeSpec        Where to store the type specifier AST node on success.
     1368 * @param   enmTypeSpecifier     The type specifier to identify whete this is a struct or a union.
     1369 */
     1370static int vdScriptParseStructOrUnionSpecifier(PVDSCRIPTCTXINT pThis, , enmTypeSpecifier)
     1371{
     1372    int rc = VINF_SUCCESS;
     1373
     1374    return rc;
     1375}
     1376
     1377/**
     1378 * Parse a type specifier.
     1379 *
     1380 * @returns VBox status code.
     1381 * @param   pThis                The script context.
     1382 * @param   ppAstTypeSpec        Where to store the type specifier AST node on success.
     1383 *
     1384 * @note Syntax:
     1385 *      struct-or-union-specifier
     1386 *      enum-specifier
     1387 *      typedef-name (identifier: includes void, bool, uint8_t, int8_t, ... for basic integer types)
     1388 */
     1389static int vdScriptParseTypeSpecifier(PVDSCRIPTCTXINT pThis, )
     1390{
     1391    int rc = VINF_SUCCESS;
     1392
     1393    if (vdScriptTokenizerSkipIfIsKeywordEqual(pThis->pTokenizer, VDSCRIPTTOKENKEYWORD_STRUCT))
     1394        rc = vdScriptParseStructOrUnionSpecifier(pThis, , VDSCRIPTASTTYPESPECIFIER_STRUCT);
     1395    else if (vdScriptTokenizerSkipIfIsKeywordEqual(pThis->pTokenizer, VDSCRIPTTOKENKEYWORD_UNION))
     1396        rc = vdScriptParseStructOrUnionSpecifier(pThis, , VDSCRIPTASTTYPESPECIFIER_UNION);
     1397    else
     1398    {
     1399        PVDSCRIPTASTIDE pIde = NULL;
     1400
     1401        rc = vdScriptParseIde(pThis, &pIde);
     1402        if (RT_SUCCESS(rc))
     1403        {
     1404            AssertMsgFailed(("TODO\n")); /* Parse identifier. */
     1405        }
     1406    }
     1407
     1408    return rc;
     1409}
     1410#endif
     1411
     1412/**
     1413 * Parse a cast expression.
    12201414 *
    12211415 * @returns VBox status code.
     
    12241418 *
    12251419 * @note Syntax:
     1420 *      cast-expression:
     1421 *          unary-expression
     1422 *          ( type-name ) cast-expression
     1423 */
     1424static int vdScriptParseCastExpression(PVDSCRIPTCTXINT pThis, PVDSCRIPTASTEXPR *ppAstNodeExpr)
     1425{
     1426    int rc = VINF_SUCCESS;
     1427    PVDSCRIPTASTEXPR pExpr = NULL;
     1428
     1429    LogFlowFunc(("pThis=%p ppAstNodeExpr=%p\n"));
     1430
     1431#if 0
     1432    if (vdScriptTokenizerSkipIfIsPunctuatorEqual(pThis->pTokenizer, '('))
     1433    {
     1434        PVDSCRIPTASTTYPE pTypeName = NULL;
     1435        rc = vdScriptParseTypeName(pThis, &pTypeName);
     1436        if (   RT_SUCCESS(rc)
     1437            && vdScriptTokenizerSkipIfIsPunctuatorEqual(pThis->pTokenizer, ')'))
     1438        {
     1439            PVDSCRIPTASTEXPR pExpr = (PVDSCRIPTASTEXPR)vdScriptAstNodeAlloc(VDSCRIPTASTCLASS_EXPRESSION);
     1440            if (pExpr)
     1441            {
     1442                pExpr->enmType = VDSCRIPTEXPRTYPE_CAST;
     1443                rc = vdScriptParseCastExpression(pThis, &pExpr->Cast.pExpr); /** @todo: Kill recursion. */
     1444                if (RT_SUCCESS(rc))
     1445                    pExpr->Cast.pTypeName = pTypeName;
     1446                else
     1447                    vdScriptAstNodeFree(&pExpr->Core);
     1448            }
     1449            else
     1450                rc = vdScriptParserError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Parser: Out of memory allocating expression AST node\n");
     1451
     1452            if (RT_FAILURE(rc))
     1453                vdScriptAstNodeFree(&pTypeName->Core);
     1454        }
     1455        else if (RT_SUCCESS(rc))
     1456            rc = vdScriptParserError(pThis, VERR_INVALID_PARAMETER, RT_SRC_POS, "Parser: Expected \")\", got ...\n");
     1457    }
     1458    else
     1459#endif
     1460        rc = vdScriptParseUnaryExpression(pThis, ppAstNodeExpr);
     1461
     1462    return rc;
     1463}
     1464
     1465/**
     1466 * Parse a multiplicative expression.
     1467 *
     1468 * @returns VBox status code.
     1469 * @param   pThis                The script context.
     1470 * @param   ppAstNodeExpr        Where to store the expression AST node on success.
     1471 *
     1472 * @note Syntax:
    12261473 *      multiplicative-expression:
    1227  *          unary-expression
    1228  *          multiplicative-expression * unary-expression
    1229  *          multiplicative-expression / unary-expression
    1230  *          multiplicative-expression % unary-expression
     1474 *          cast-expression
     1475 *          multiplicative-expression * cast-expression
     1476 *          multiplicative-expression / cast-expression
     1477 *          multiplicative-expression % cast-expression
    12311478 */
    12321479static int vdScriptParseMultiplicativeExpression(PVDSCRIPTCTXINT pThis, PVDSCRIPTASTEXPR *ppAstNodeExpr)
     
    12371484    LogFlowFunc(("pThis=%p ppAstNodeExpr=%p\n"));
    12381485
    1239     rc = vdScriptParseUnaryExpression(pThis, &pExpr);
     1486    rc = vdScriptParseCastExpression(pThis, &pExpr);
    12401487    if (RT_SUCCESS(rc))
    12411488    {
    1242         PVDSCRIPTASTEXPR pExprNew = NULL;
    12431489        while (RT_SUCCESS(rc))
    12441490        {
     1491            VDSCRIPTEXPRTYPE enmType = VDSCRIPTEXPRTYPE_INVALID;
     1492            PVDSCRIPTASTEXPR pExprNew = NULL;
     1493
    12451494            if (vdScriptTokenizerSkipIfIsOperatorEqual(pThis->pTokenizer, "*"))
    1246             {
    1247                 pExprNew = (PVDSCRIPTASTEXPR)vdScriptAstNodeAlloc(VDSCRIPTASTCLASS_EXPRESSION);
    1248                 if (pExprNew)
    1249                     pExprNew->enmType = VDSCRIPTEXPRTYPE_MULTIPLICATION;
    1250                 else
    1251                     rc = vdScriptParserError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Parser: Out of memory allocating expression AST node\n");
    1252             }
     1495                enmType = VDSCRIPTEXPRTYPE_MULTIPLICATION;
    12531496            else if (vdScriptTokenizerSkipIfIsOperatorEqual(pThis->pTokenizer, "/"))
    1254             {
    1255                 pExprNew = (PVDSCRIPTASTEXPR)vdScriptAstNodeAlloc(VDSCRIPTASTCLASS_EXPRESSION);
    1256                 if (pExprNew)
    1257                     pExprNew->enmType = VDSCRIPTEXPRTYPE_DIVISION;
    1258                 else
    1259                     rc = vdScriptParserError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Parser: Out of memory allocating expression AST node\n");
    1260             }
     1497                enmType = VDSCRIPTEXPRTYPE_DIVISION;
    12611498            else if (vdScriptTokenizerSkipIfIsOperatorEqual(pThis->pTokenizer, "%"))
    1262             {
    1263                 pExprNew = (PVDSCRIPTASTEXPR)vdScriptAstNodeAlloc(VDSCRIPTASTCLASS_EXPRESSION);
    1264                 if (pExprNew)
    1265                     pExprNew->enmType = VDSCRIPTEXPRTYPE_MODULUS;
    1266                 else
    1267                     rc = vdScriptParserError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Parser: Out of memory allocating expression AST node\n");
    1268             }
     1499                enmType = VDSCRIPTEXPRTYPE_MODULUS;
    12691500            else
    12701501                break;
    12711502
     1503            pExprNew = (PVDSCRIPTASTEXPR)vdScriptAstNodeAlloc(VDSCRIPTASTCLASS_EXPRESSION);
     1504            if (pExprNew)
     1505                pExprNew->enmType = enmType;
     1506            else
     1507            {
     1508                rc = vdScriptParserError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Parser: Out of memory allocating expression AST node\n");
     1509                break;
     1510            }
     1511
    12721512            pExprNew->BinaryOp.pLeftExpr = pExpr;
    12731513            pExpr = pExprNew;
    1274             rc = vdScriptParseUnaryExpression(pThis, &pExprNew);
     1514            rc = vdScriptParseCastExpression(pThis, &pExprNew);
    12751515            if (RT_SUCCESS(rc))
    12761516                pExpr->BinaryOp.pRightExpr = pExprNew;
     
    18162056{
    18172057    return vdScriptParseLogicalOrExpression(pThis, ppAstNodeExpr);
     2058}
     2059
     2060/**
     2061 * Parse a constant expression.
     2062 *
     2063 * @returns VBox status code.
     2064 * @param   pThis                The script context.
     2065 * @param   ppAstNodeExpr        Where to store the expression AST node on success.
     2066 *
     2067 * @note Syntax:
     2068 *      constant-expression:
     2069 *          conditional-expression
     2070 */
     2071static int vdScriptParseConstExpression(PVDSCRIPTCTXINT pThis, PVDSCRIPTASTEXPR *ppAstNodeExpr)
     2072{
     2073    return vdScriptParseCondExpression(pThis, ppAstNodeExpr);
    18182074}
    18192075
     
    26452901    RTStrSpaceDestroy(&pThis->hStrSpaceFn, vdScriptCtxDestroyFnSpace, NULL);
    26462902
    2647     /** @todo: Go through the list and destroy all ASTs. */
     2903    /* Go through list of function ASTs and destroy them. */
     2904    PVDSCRIPTASTCORE pIter;
     2905    PVDSCRIPTASTCORE pIterNext;
     2906    RTListForEachSafe(&pThis->ListAst, pIter, pIterNext, VDSCRIPTASTCORE, ListNode)
     2907    {
     2908        RTListNodeRemove(&pIter->ListNode);
     2909        RTListInit(&pIter->ListNode);
     2910        vdScriptAstNodeFree(pIter);
     2911    }
     2912
    26482913    RTMemFree(pThis);
    26492914}
  • trunk/src/VBox/Storage/testcase/VDScript.h

    r44941 r52371  
    4343    VDSCRIPTTYPE_STRING,
    4444    VDSCRIPTTYPE_BOOL,
     45    VDSCRIPTTYPE_POINTER,
    4546    /** As usual, the 32bit blowup hack. */
    4647    VDSCRIPTTYPE_32BIT_HACK = 0x7fffffff
     
    7172        const char *psz;
    7273        bool        f;
     74        void       *p;
    7375    };
    7476} VDSCRIPTARG;
     
    103105
    104106/**
     107 * @{
     108 */
     109/** The address space stays assigned to a variable
     110 * even if the pointer is casted to another type.
     111 */
     112#define VDSCRIPT_AS_FLAGS_TRANSITIVE RT_BIT(0)
     113/** @} */
     114
     115/**
     116 * Address space read callback
     117 *
     118 * @returns VBox status code.
     119 * @param   pvUser         Opaque user data given on registration.
     120 * @param   Address        The address to read from, address is stored in the member for
     121 *                         base type given on registration.
     122 * @param   pvBuf          Where to store the read bits.
     123 * @param   cbRead         How much to read.
     124 */
     125typedef DECLCALLBACK(int) FNVDSCRIPTASREAD(void *pvUser, VDSCRIPTARG Address, void *pvBuf, size_t cbRead);
     126/** Pointer to a read callback. */
     127typedef FNVDSCRIPTASREAD *PFNVDSCRIPTASREAD;
     128
     129/**
     130 * Address space write callback
     131 *
     132 * @returns VBox status code.
     133 * @param   pvUser         Opaque user data given on registration.
     134 * @param   Address        The address to write to, address is stored in the member for
     135 *                         base type given on registration.
     136 * @param   pvBuf          Data to write.
     137 * @param   cbWrite        How much to write.
     138 */
     139typedef DECLCALLBACK(int) FNVDSCRIPTASWRITE(void *pvUser, VDSCRIPTARG Address, const void *pvBuf, size_t cbWrite);
     140/** Pointer to a write callback. */
     141typedef FNVDSCRIPTASWRITE *PFNVDSCRIPTASWRITE;
     142
     143/**
    105144 * Create a new scripting context.
    106145 *
     
    151190                                  PVDSCRIPTARG paArgs, unsigned cArgs);
    152191
     192/**
     193 * Registers a new address space provider.
     194 *
     195 * @returns VBox status code.
     196 * @param   hScriptCtx     The script context handle.
     197 * @param   pszType        The type string.
     198 * @param   enmBaseType    The base integer type to use for the address space.
     199 *                         Bool and String are not supported of course.
     200 * @param   pfnRead        The read callback for the registered address space.
     201 * @param   pfnWrite       The write callback for the registered address space.
     202 * @param   pvUser         Opaque user data to pass to the read and write callbacks.
     203 * @param   fFlags         Flags, see VDSCRIPT_AS_FLAGS_*.
     204 *
     205 * @note This will automatically register a new type with the identifier given in pszType
     206 *       used for the pointer. Every variable with this type is automatically treated as a pointer.
     207 *
     208 * @note If the transitive flag is set the address space stays assigned even if the pointer value
     209 *       is casted to another pointer type.
     210 *       In the following example the pointer pStruct will use the registered address space for RTGCPHYS
     211 *       and dereferencing the pointer causes the read/write callbacks to be triggered.
     212 *
     213 *       ...
     214 *       Struct *pStruct = (Struct *)(RTGCPHYS)0x12345678;
     215 *       pStruct->count++;
     216 *       ...
     217 */
     218DECLHIDDEN(int) VDScriptCtxAsRegister(VDSCRIPTCTX hScriptCtx, const char *pszType, VDSCRIPTTYPE enmBaseType,
     219                                      PFNVDSCRIPTASREAD pfnRead, PFNVDSCRIPTASWRITE pfnWrite, void *pvUser,
     220                                      uint32_t fFlags);
     221
    153222#endif /* _VDScript_h__ */
  • trunk/src/VBox/Storage/testcase/VDScriptAst.cpp

    r44941 r52371  
    7373            break;
    7474        }
     75        case VDSCRIPTEXPRTYPE_POSTFIX_DEREFERENCE:
     76        case VDSCRIPTEXPRTYPE_POSTFIX_DOT:
     77        {
     78            RTListAppend(pList, &pExpr->Deref.pIde->Core.ListNode);
     79            RTListAppend(pList, &pExpr->Deref.pExpr->Core.ListNode);
     80            break;
     81        }
    7582        case VDSCRIPTEXPRTYPE_POSTFIX_INCREMENT:
    7683        case VDSCRIPTEXPRTYPE_POSTFIX_DECREMENT:
     
    8188        case VDSCRIPTEXPRTYPE_UNARY_INVERT:
    8289        case VDSCRIPTEXPRTYPE_UNARY_NEGATE:
     90        case VDSCRIPTEXPRTYPE_UNARY_REFERENCE:
     91        case VDSCRIPTEXPRTYPE_UNARY_DEREFERENCE:
    8392        {
    8493            RTListAppend(pList, &pExpr->pExpr->Core.ListNode);
     
    154163            while (!RTListIsEmpty(&pStmt->Compound.ListStmts))
    155164            {
    156                 PVDSCRIPTASTCORE pNode = RTListGetFirst(&pStmt->Compound.ListDecls, VDSCRIPTASTCORE, ListNode);
     165                PVDSCRIPTASTCORE pNode = RTListGetFirst(&pStmt->Compound.ListStmts, VDSCRIPTASTCORE, ListNode);
    157166                RTListNodeRemove(&pNode->ListNode);
    158167                RTListAppend(pList, &pNode->ListNode);
     
    273282                break;
    274283            case VDSCRIPTASTCLASS_DECLARATION:
    275                 break;
     284            case VDSCRIPTASTCLASS_TYPENAME:
     285            {
     286                AssertMsgFailed(("TODO\n"));
     287                break;
     288            }
    276289            case VDSCRIPTASTCLASS_STATEMENT:
    277290            {
     
    314327        case VDSCRIPTASTCLASS_EXPRESSION:
    315328            cbAlloc = sizeof(VDSCRIPTASTEXPR);
     329            break;
     330        case VDSCRIPTASTCLASS_TYPENAME:
     331            cbAlloc = sizeof(VDSCRIPTASTTYPENAME);
    316332            break;
    317333        case VDSCRIPTASTCLASS_IDENTIFIER:
  • trunk/src/VBox/Storage/testcase/VDScriptAst.h

    r44941 r52371  
    5454    /** Expression node. */
    5555    VDSCRIPTASTCLASS_EXPRESSION,
     56    /** Type name node. */
     57    VDSCRIPTASTCLASS_TYPENAME,
     58    /** Type specifier node. */
     59    VDSCRIPTASTCLASS_TYPESPECIFIER,
    5660    /** 32bit blowup. */
    5761    VDSCRIPTASTCLASS_32BIT_HACK = 0x7fffffff
     
    9498/** Pointer to an identifer node. */
    9599typedef VDSCRIPTASTIDE *PVDSCRIPTASTIDE;
     100
     101/**
     102 * Type specifier.
     103 */
     104typedef enum VDSCRIPTASTTYPESPECIFIER
     105{
     106    /** Invalid type specifier. */
     107    VDSCRIPTASTTYPESPECIFIER_INVALID = 0,
     108    /** Union type specifier. */
     109    VDSCRIPTASTTYPESPECIFIER_UNION,
     110    /** Struct type specifier. */
     111    VDSCRIPTASTTYPESPECIFIER_STRUCT,
     112    /** Identifier of a typedefed type. */
     113    VDSCRIPTASTTYPESPECIFIER_IDE,
     114    /** 32bit hack. */
     115    VDSCRIPTASTTYPESPECIFIER_32BIT_HACK = 0x7fffffff
     116} VDSCRIPTASTTYPESPECIFIER;
     117/** Pointer to a typespecifier. */
     118typedef VDSCRIPTASTTYPESPECIFIER *PVDSCRIPTASTTYPESPECIFIER;
     119
     120/**
     121 * AST type specifier.
     122 */
     123typedef struct VDSCRIPTASTTYPESPEC
     124{
     125    /** Core structure. */
     126    VDSCRIPTASTCORE          Core;
     127    /** Specifier type. */
     128    VDSCRIPTASTTYPESPECIFIER enmType;
     129    /** Type dependent data .*/
     130    union
     131    {
     132        /** Pointer to an identifier for typedefed types. */
     133        PVDSCRIPTASTIDE      pIde;
     134        /** struct or union specifier. */
     135        struct
     136        {
     137            /** Pointer to the identifier, optional. */
     138            PVDSCRIPTASTIDE  pIde;
     139            /** Declaration list - VDSCRIPTAST. */
     140            RTLISTANCHOR     ListDecl;
     141        } StructUnion;
     142    };
     143} VDSCRIPTASTTYPESPEC;
     144/** Pointer to an AST type specifier. */
     145typedef VDSCRIPTASTTYPESPEC *PVDSCRIPTASTTYPESPEC;
     146
     147/**
     148 * Storage clase specifier.
     149 */
     150typedef enum VDSCRIPTASTSTORAGECLASS
     151{
     152    /** Invalid storage class sepcifier. */
     153    VDSCRIPTASTSTORAGECLASS_INVALID = 0,
     154    /** A typedef type. */
     155    VDSCRIPTASTSTORAGECLASS_TYPEDEF,
     156    /** An external declared object. */
     157    VDSCRIPTASTSTORAGECLASS_EXTERN,
     158    /** A static declared object. */
     159    VDSCRIPTASTSTORAGECLASS_STATIC,
     160    /** Auto object. */
     161    VDSCRIPTASTSTORAGECLASS_AUTO,
     162    /** Object should be stored in a register. */
     163    VDSCRIPTASTSTORAGECLASS_REGISTER,
     164    /** 32bit hack. */
     165    VDSCRIPTASTSTORAGECLASS_32BIT_HACK = 0x7fffffff
     166} VDSCRIPTASTSTORAGECLASS;
     167/** Pointer to a storage class. */
     168typedef VDSCRIPTASTSTORAGECLASS *PVDSCRIPTASTSTORAGECLASS;
     169
     170/**
     171 * Type qualifier.
     172 */
     173typedef enum VDSCRIPTASTTYPEQUALIFIER
     174{
     175    /** Invalid type qualifier. */
     176    VDSCRIPTASTTYPEQUALIFIER_INVALID = 0,
     177    /** Const type qualifier. */
     178    VDSCRIPTASTTYPEQUALIFIER_CONST,
     179    /** Restrict type qualifier. */
     180    VDSCRIPTASTTYPEQUALIFIER_RESTRICT,
     181    /** Volatile type qualifier. */
     182    VDSCRIPTASTTYPEQUALIFIER_VOLATILE,
     183    /** 32bit hack. */
     184    VDSCRIPTASTTYPEQUALIFIER_32BIT_HACK = 0x7fffffff
     185} VDSCRIPTASTTYPEQUALIFIER;
     186/** Pointer to a type qualifier. */
     187typedef VDSCRIPTASTTYPEQUALIFIER *PVDSCRIPTASTTYPEQUALIFIER;
     188
     189/**
     190 * AST type name node.
     191 */
     192typedef struct VDSCRIPTASTTYPENAME
     193{
     194    /** Core structure. */
     195    VDSCRIPTASTCORE    Core;
     196} VDSCRIPTASTTYPENAME;
     197/** Pointer to a type name node. */
     198typedef VDSCRIPTASTTYPENAME *PVDSCRIPTASTTYPENAME;
    96199
    97200/**
     
    130233    /** Postfix function call expression. */
    131234    VDSCRIPTEXPRTYPE_POSTFIX_FNCALL,
     235    /** Postfix dereference expression. */
     236    VDSCRIPTEXPRTYPE_POSTFIX_DEREFERENCE,
     237    /** Dot operator (@todo: Is there a better name for it?). */
     238    VDSCRIPTEXPRTYPE_POSTFIX_DOT,
    132239    /** Unary increment expression. */
    133240    VDSCRIPTEXPRTYPE_UNARY_INCREMENT,
     
    142249    /** Unary negate expression. */
    143250    VDSCRIPTEXPRTYPE_UNARY_NEGATE,
     251    /** Unary reference expression. */
     252    VDSCRIPTEXPRTYPE_UNARY_REFERENCE,
     253    /** Unary dereference expression. */
     254    VDSCRIPTEXPRTYPE_UNARY_DEREFERENCE,
     255    /** Cast expression. */
     256    VDSCRIPTEXPRTYPE_CAST,
    144257    /** Multiplicative expression. */
    145258    VDSCRIPTEXPRTYPE_MULTIPLICATION,
     
    246359            PVDSCRIPTASTEXPR pRightExpr;
    247360        } BinaryOp;
     361        /** Dereference or dot operation. */
     362        struct
     363        {
     364            /** The identifier to access. */
     365            PVDSCRIPTASTIDE  pIde;
     366            /** Postfix expression coming after this. */
     367            PVDSCRIPTASTEXPR pExpr;
     368        } Deref;
     369        /** Cast expression. */
     370        struct
     371        {
     372            /** Type name. */
     373            PVDSCRIPTASTTYPENAME pTypeName;
     374            /** Following cast expression. */
     375            PVDSCRIPTASTEXPR     pExpr;
     376        } Cast;
    248377    };
    249378} VDSCRIPTASTEXPR;
  • trunk/src/VBox/Storage/testcase/tstVDCompact.vd

    r44943 r52371  
    2222    /* Create disk containers, read verification is on. */
    2323    createdisk("disk", true);
    24     create("disk", "base", "tstCompact.disk", "dynamic", strBackend, 200M, false);
     24    create("disk", "base", "tstCompact.disk", "dynamic", strBackend, 200M, false, false);
    2525
    2626    /* Fill the disk with random data. */
     
    4646}
    4747
     48void tstSnapshotCompact(string strMsg, string strBackend)
     49{
     50    print(strMsg);
     51
     52    /* Create disk containers, read verification is on. */
     53    createdisk("disk", true);
     54    create("disk", "base", "tstCompact.disk", "dynamic", strBackend, 200M, false, false);
     55
     56    /* Fill the disk with random data. */
     57    io("disk", false, 1, "seq", 64K, 0, 100M, 100M, 100, "none");
     58
     59    create("test", "diff", "tst2.disk", "dynamic", strBackend, 200M, false /* fIgnoreFlush */, true /* fHonorSame */);
     60
     61    io("disk", false, 1, "seq", 64K, 100M, 200M, 100M, 100, "none");
     62    io("disk", false, 1, "seq", 64K, 100M, 150M, 50M, 100, "zero");
     63
     64    create("disk", "diff", "tst3.disk", "dynamic", strBackend, 200M, false /* fIgnoreFlush */, true /* fHonorSame */);
     65    merge("disk", 1, 2);
     66
     67    compact("disk", 1);
     68
     69    close("disk", "single", true);
     70    destroydisk("disk");
     71}
     72
    4873void main()
    4974{
     
    5782    tstCompact("Testing VHD", "VHD");
    5883
     84    tstSnapshotCompact("Testing Snapshot VDI", "VDI");
     85    tstSnapshotCompact("Testing Snapshot VHD", "VHD");
     86
    5987    /* Destroy RNG and pattern */
    6088    iopatterndestroy("zero");
  • trunk/src/VBox/Storage/testcase/tstVDCopy.vd

    r44943 r52371  
    2424    print("Creating Source Disk");
    2525    createdisk("source", false);
    26     create("source", "base", "source_base.vdi", "dynamic", "VDI", 1G, false);
     26    create("source", "base", "source_base.vdi", "dynamic", "VDI", 1G, false, false);
    2727    io("source", false, 1, "rnd", 64K, 0, 512M, 256M, 100, "none");
    2828
    2929    print("Creating first diff");
    30     create("source", "diff", "source_diff1.vdi", "dynamic", "VDI", 1G, false);
     30    create("source", "diff", "source_diff1.vdi", "dynamic", "VDI", 1G, false, false);
    3131    io("source", false, 1, "rnd", 64K, 512M, 1G, 256M, 50, "none");
    3232
    3333    print("Creating second diff");
    34     create("source", "diff", "source_diff2.vdi", "dynamic", "VDI", 1G, false);
     34    create("source", "diff", "source_diff2.vdi", "dynamic", "VDI", 1G, false, false);
    3535    io("source", false, 1, "rnd", 1M, 0, 1G, 45M, 100, "none");
    3636
    3737    print("Creating third diff");
    38     create("source", "diff", "source_diff3.vdi", "dynamic", "VDI", 1G, false);
     38    create("source", "diff", "source_diff3.vdi", "dynamic", "VDI", 1G, false, false);
    3939    io("source", false, 1, "rnd", 1M, 0, 1G, 45M, 100, "none");
    4040
    4141    print("Creating fourth diff");
    42     create("source", "diff", "source_diff4.vdi", "dynamic", "VDI", 1G, false);
     42    create("source", "diff", "source_diff4.vdi", "dynamic", "VDI", 1G, false, false);
    4343    io("source", false, 1, "rnd", 1M, 0, 1G, 45M, 100, "none");
    4444
     
    5757    copy("source", "dest", 4, "VDI", "dest_diff1.vdi", false, 0, 3, 3);
    5858
    59     print("Comparing_Disks");
     59    print("Comparing disks");
    6060    comparedisks("source", "dest");
    6161
  • trunk/src/VBox/Storage/testcase/tstVDDiscard.vd

    r44943 r52371  
    2626    createdisk("disk", true /* fVerify */);
    2727    /* Create the disk. */
    28     create("disk", "base", "tstCompact.vdi", "dynamic", "VDI", 2G, false /* fIgnoreFlush */);
     28    create("disk", "base", "tstCompact.vdi", "dynamic", "VDI", 2G, false /* fIgnoreFlush */, false);
    2929    /* Fill the disk with random data */
    30     io("disk", false, 1, "seq", 64K, 0, 2G, 2G, 100, "none");
     30    io("disk", false, 1, "seq", 64K, 0, 200M, 200M, 100, "none");
    3131    /* Read the data to verify it once. */
    32     io("disk", false, 1, "seq", 64K, 0, 2G, 2G,   0, "none");
     32    io("disk", false, 1, "seq", 64K, 0, 200M, 200M,   0, "none");
    3333    close("disk", "single", false);
    3434
    35     open("disk", "tstCompact.vdi", "VDI", true, false, false, true, false);
     35    open("disk", "tstCompact.vdi", "VDI", true, false, false, true, false, false);
    3636    printfilesize("disk", 0);
    3737    discard("disk", true, "6,0M,512K,1M,512K,2M,512K,3M,512K,4M,512K,5M,512K");
  • trunk/src/VBox/Storage/testcase/tstVDIo.cpp

    r52111 r52371  
    66
    77/*
    8  * Copyright (C) 2011-2013 Oracle Corporation
     8 * Copyright (C) 2011-2014 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3333#include <iprt/rand.h>
    3434#include <iprt/critsect.h>
     35#include <iprt/test.h>
    3536
    3637#include "VDMemDisk.h"
     
    4041#include "VDScript.h"
    4142#include "BuiltinTests.h"
     43
     44/** forward declaration for the global test data pointer. */
     45typedef struct VDTESTGLOB *PVDTESTGLOB;
    4246
    4347/**
     
    100104    /** Logical CHS geometry. */
    101105    VDGEOMETRY     LogicalGeom;
     106    /** Global test data. */
     107    PVDTESTGLOB    pTestGlob;
    102108} VDDISK, *PVDDISK;
    103109
     
    142148    /** Current storage backend to use. */
    143149    char            *pszIoBackend;
    144 } VDTESTGLOB, *PVDTESTGLOB;
     150    /** Testcase handle. */
     151    RTTEST           hTest;
     152} VDTESTGLOB;
    145153
    146154/**
     
    256264    VDSCRIPTTYPE_STRING,
    257265    VDSCRIPTTYPE_UINT64,
     266    VDSCRIPTTYPE_BOOL,
    258267    VDSCRIPTTYPE_BOOL
    259268};
     
    269278    VDSCRIPTTYPE_BOOL,   /* readonly */
    270279    VDSCRIPTTYPE_BOOL,   /* discard */
    271     VDSCRIPTTYPE_BOOL    /* ignoreflush */
     280    VDSCRIPTTYPE_BOOL,   /* ignoreflush */
     281    VDSCRIPTTYPE_BOOL,   /* honorsame */
    272282};
    273283
     
    533543    bool fDynamic = true;
    534544    bool fIgnoreFlush = false;
     545    bool fHonorSame = false;
    535546    PVDIOBACKEND pIoBackend = NULL;
    536547
     
    558569    cbSize = paScriptArgs[5].u64;
    559570    fIgnoreFlush = paScriptArgs[6].f;
     571    fHonorSame = paScriptArgs[7].f;
    560572
    561573    if (RT_SUCCESS(rc))
     
    572584            if (fIgnoreFlush)
    573585                fOpenFlags |= VD_OPEN_FLAGS_IGNORE_FLUSH;
     586
     587            if (fHonorSame)
     588                fOpenFlags |= VD_OPEN_FLAGS_HONOR_SAME;
    574589
    575590            if (fBase)
     
    601616    bool fDiscard  = false;
    602617    bool fIgnoreFlush = false;
     618    bool fHonorSame = false;
    603619
    604620    pcszDisk = paScriptArgs[0].psz;
     
    609625    fAsyncIo = paScriptArgs[5].f;
    610626    fDiscard = paScriptArgs[6].f;
     627    fIgnoreFlush = paScriptArgs[7].f;
     628    fHonorSame = paScriptArgs[8].f;
    611629
    612630    if (RT_SUCCESS(rc))
     
    627645            if (fIgnoreFlush)
    628646                fOpenFlags |= VD_OPEN_FLAGS_IGNORE_FLUSH;
     647            if (fHonorSame)
     648                fOpenFlags |= VD_OPEN_FLAGS_HONOR_SAME;
    629649
    630650            rc = VDOpen(pDisk->pVD, pcszBackend, pcszImage, fOpenFlags, pGlob->pInterfacesImages);
     
    713733        VDIOTEST IoTest;
    714734
     735        RTTestSub(pGlob->hTest, "Basic I/O");
    715736        rc = tstVDIoTestInit(&IoTest, pGlob, fRandomAcc, cbIo, cbBlkSize, offStart, offEnd, uWriteChance, pPattern);
    716737        if (RT_SUCCESS(rc))
     
    771792                                                if (VDMemDiskCmp(pDisk->pMemDiskVerify, paIoReq[idx].off, paIoReq[idx].cbReq, &SgBuf))
    772793                                                {
    773                                                     RTPrintf("Corrupted disk at offset %llu!\n", paIoReq[idx].off);
     794                                                    RTTestFailed(pGlob->hTest, "Corrupted disk at offset %llu!\n", paIoReq[idx].off);
    774795                                                    rc = VERR_INVALID_STATE;
    775796                                                }
     
    850871                                                                     &paIoReq[idx].SgBuf))
    851872                                                    {
    852                                                         RTPrintf("Corrupted disk at offset %llu!\n", paIoReq[idx].off);
     873                                                        RTTestFailed(pGlob->hTest, "Corrupted disk at offset %llu!\n", paIoReq[idx].off);
    853874                                                        rc = VERR_INVALID_STATE;
    854875                                                    }
     
    924945                NanoTS = RTTimeNanoTS() - NanoTS;
    925946                uint64_t SpeedKBs = (uint64_t)(cbIo / (NanoTS / 1000000000.0) / 1024);
    926                 RTPrintf("I/O Test: Throughput %lld kb/s\n", SpeedKBs);
     947                RTTestValue(pGlob->hTest, "Throughput", SpeedKBs, RTTESTUNIT_KILOBYTES_PER_SEC);
     948
     949                for (unsigned i = 0; i < cMaxTasksOutstanding; i++)
     950                {
     951                    if (paIoReq[i].pvBufRead)
     952                        RTMemFree(paIoReq[i].pvBufRead);
     953                }
    927954
    928955                RTSemEventDestroy(EventSem);
     
    17461773        if (pDisk)
    17471774        {
     1775            pDisk->pTestGlob = pGlob;
    17481776            pDisk->pszName = RTStrDup(pcszDisk);
    17491777            if (pDisk->pszName)
     
    18461874            cbDisk2 = VDGetSize(pDisk2->pVD, VD_LAST_IMAGE);
    18471875
     1876            RTTestSub(pGlob->hTest, "Comparing two disks for equal content");
    18481877            if (cbDisk1 != cbDisk2)
    1849                 RTPrintf("Disks differ in size %llu vs %llu\n", cbDisk1, cbDisk2);
     1878                RTTestFailed(pGlob->hTest, "Disks differ in size %llu vs %llu\n", cbDisk1, cbDisk2);
    18501879            else
    18511880            {
     
    18621891                        if (memcmp(pbBuf1, pbBuf2, cbRead))
    18631892                        {
    1864                             RTPrintf("Disks differ at offset %llu\n", uOffCur);
     1893                            RTTestFailed(pGlob->hTest, "Disks differ at offset %llu\n", uOffCur);
    18651894                            rc = VERR_DEV_IO_ERROR;
    18661895                            break;
     
    18691898                    else
    18701899                    {
    1871                         RTPrintf("Reading one disk at offset %llu failed\n", uOffCur);
     1900                        RTTestFailed(pGlob->hTest, "Reading one disk at offset %llu failed\n", uOffCur);
    18721901                        break;
    18731902                    }
     
    25172546                if (VDMemDiskCmp(pDisk->pMemDiskVerify, pIoReq->off, pIoReq->cbReq,
    25182547                                 &pIoReq->SgBuf))
    2519                     RTPrintf("Corrupted disk at offset %llu!\n", pIoReq->off);
     2548                    RTTestFailed(pDisk->pTestGlob->hTest, "Corrupted disk at offset %llu!\n", pIoReq->off);
    25202549                RTCritSectLeave(&pDisk->CritSectVerify);
    25212550            }
     
    26972726    AssertRC(rc);
    26982727
    2699     /* Init I/O backend. */
    2700     rc = VDIoBackendCreate(&GlobTest.pIoBackend);
     2728    rc = RTTestCreate("tstVDIo", &GlobTest.hTest);
    27012729    if (RT_SUCCESS(rc))
    27022730    {
    2703         VDSCRIPTCTX hScriptCtx = NULL;
    2704         rc = VDScriptCtxCreate(&hScriptCtx);
     2731        /* Init I/O backend. */
     2732        rc = VDIoBackendCreate(&GlobTest.pIoBackend);
    27052733        if (RT_SUCCESS(rc))
    27062734        {
    2707             rc = VDScriptCtxCallbacksRegister(hScriptCtx, g_aScriptActions, g_cScriptActions, &GlobTest);
    2708             AssertRC(rc);
    2709 
    2710             rc = VDScriptCtxLoadScript(hScriptCtx, pszScript);
    2711             if (RT_FAILURE(rc))
     2735            VDSCRIPTCTX hScriptCtx = NULL;
     2736            rc = VDScriptCtxCreate(&hScriptCtx);
     2737            if (RT_SUCCESS(rc))
    27122738            {
    2713                 RTPrintf("Loading the script failed rc=%Rrc\n", rc);
     2739                RTTEST_CHECK_RC_OK(GlobTest.hTest,
     2740                                   VDScriptCtxCallbacksRegister(hScriptCtx, g_aScriptActions, g_cScriptActions, &GlobTest));
     2741
     2742                RTTestBanner(GlobTest.hTest);
     2743                rc = VDScriptCtxLoadScript(hScriptCtx, pszScript);
     2744                if (RT_FAILURE(rc))
     2745                {
     2746                    RTPrintf("Loading the script failed rc=%Rrc\n", rc);
     2747                }
     2748                else
     2749                    rc = VDScriptCtxCallFn(hScriptCtx, "main", NULL, 0);
     2750                VDScriptCtxDestroy(hScriptCtx);
    27142751            }
    2715             else
    2716                 rc = VDScriptCtxCallFn(hScriptCtx, "main", NULL, 0);
    2717             VDScriptCtxDestroy(hScriptCtx);
    2718         }
    2719         VDIoBackendDestroy(GlobTest.pIoBackend);
    2720     }
    2721     else
    2722         RTPrintf("Creating the I/O backend failed rc=%Rrc\n");
     2752            VDIoBackendDestroy(GlobTest.pIoBackend);
     2753        }
     2754        else
     2755            RTPrintf("Creating the I/O backend failed rc=%Rrc\n");
     2756
     2757        RTTestSummaryAndDestroy(GlobTest.hTest);
     2758    }
     2759    else
     2760        RTStrmPrintf(g_pStdErr, "tstVDIo: fatal error: RTTestCreate failed with rc=%Rrc\n", rc);
    27232761
    27242762    RTStrFree(GlobTest.pszIoBackend);
     
    27462784        AssertPtr(pszScript);
    27472785        tstVDIoScriptExec(pszScript);
     2786        RTStrFree(pszScript);
    27482787    }
    27492788    else
  • trunk/src/VBox/Storage/testcase/tstVDIo.vd

    r52111 r52371  
    2020    print(strMessage);
    2121    createdisk("test", true /* fVerify */);
    22     create("test", "base", "tst.disk", "dynamic", strBackend, 200M, false /* fIgnoreFlush */);
     22    create("test", "base", "tst.disk", "dynamic", strBackend, 200M, false /* fIgnoreFlush */, false);
    2323    io("test", true, 32, "seq", 64K, 0, 200M, 200M, 100, "none");
    2424    io("test", false, 1, "seq", 64K, 0, 200M, 200M, 100, "none");
    2525    io("test", true, 32, "seq", 64K, 0, 200M, 200M,   0, "none");
    2626    io("test", false, 1, "seq", 64K, 0, 200M, 200M,   0, "none");
    27     create("test", "diff", "tst2.disk", "dynamic", strBackend, 200M, false /* fIgnoreFlush */);
     27    create("test", "diff", "tst2.disk", "dynamic", strBackend, 200M, false /* fIgnoreFlush */, false);
    2828    io("test", true, 32, "rnd", 64K, 0, 200M, 200M,  50, "none");
    2929    io("test", false, 1, "rnd", 64K, 0, 200M, 200M,  50, "none");
    30     create("test", "diff", "tst3.disk", "dynamic", strBackend, 200M, false /* fIgnoreFlush */);
     30    create("test", "diff", "tst3.disk", "dynamic", strBackend, 200M, false /* fIgnoreFlush */, false);
    3131    io("test", true, 32, "rnd", 64K, 0, 200M, 200M,  50, "none");
    3232    io("test", false, 1, "rnd", 64K, 0, 200M, 200M,  50, "none");
  • trunk/src/VBox/Storage/testcase/tstVDResize.vd

    r44943 r52371  
    1818void main()
    1919{
    20         /* Init I/O RNG for generating random data for writes. */
    21         iorngcreate(10M, "manual", 1234567890);
     20    /* Init I/O RNG for generating random data for writes. */
     21    iorngcreate(10M, "manual", 1234567890);
    2222
    23         print("Testing VDI");
    24         createdisk("test", true);
    25         create("test", "base", "tst.vdi", "dynamic", "VDI", 1T, false);
    26         io("test", false, 1, "seq", 64K, 255G, 257G, 2G, 100, "none");
    27         resize("test", 1331200M);
    28         io("test", false, 1, "seq", 64K, 255G, 257G, 2G,   0, "none");
    29         destroydisk("test");
     23    print("Testing VDI");
     24    createdisk("test", true);
     25    create("test", "base", "tst.vdi", "dynamic", "VDI", 1T, false, false);
     26    io("test", false, 1, "seq", 64K, 255G, 257G, 2G, 100, "none");
     27    resize("test", 1331200M);
     28    io("test", false, 1, "seq", 64K, 255G, 257G, 2G,   0, "none");
     29    destroydisk("test");
    3030
    31         iorngdestroy();
     31    iorngdestroy();
    3232}
     33
  • trunk/src/VBox/Storage/testcase/tstVDShareable.vd

    r44943 r52371  
    2626
    2727    /* Create the disk and close it. */
    28     create("shared1", "base", "tstShared.vdi", "fixed", "VDI", 20M, false);
     28    create("shared1", "base", "tstShared.vdi", "fixed", "VDI", 20M, false, false);
    2929    close("shared1", "all", false);
    3030
    3131    /* Open the disk with sharing enabled. */
    32     open("shared1", "tstShared.vdi", "VDI", true /* fAsync */, true /* fShareable */, false, false, false);
    33     open("shared2", "tstShared.vdi", "VDI", true /* fAsync */, true /* fShareable */, false, false, false);
     32    open("shared1", "tstShared.vdi", "VDI", true /* fAsync */, true /* fShareable */, false, false, false, false);
     33    open("shared2", "tstShared.vdi", "VDI", true /* fAsync */, true /* fShareable */, false, false, false, false);
    3434
    3535    /* Write to one disk and verify that the other disk can see the content. */
     
    4646
    4747    /* Open and delete. */
    48     open("shared1", "tstShared.vdi", "VDI", false /* fAsync */, false /* fShareable */, false, false, false);
     48    open("shared1", "tstShared.vdi", "VDI", false /* fAsync */, false /* fShareable */, false, false, false, false);
    4949    close("shared1", "single", true);
    5050
     
    5454    iorngdestroy();
    5555}
     56
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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