VirtualBox

Changeset 3398 in kBuild for trunk


Ignore:
Timestamp:
Jul 2, 2020 9:16:27 AM (5 years ago)
Author:
bird
Message:

kmk/expreval.c: Extended the expressions with version string comparison operators: vle, vlt, vgt, vge, veq, vne

File:
1 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/src/kmk/expreval.c

    r3141 r3398  
    4141#include "debug.h"
    4242#include "hash.h"
     43#include "version_compare.h"
    4344#include <ctype.h>
    4445#ifndef _MSC_VER
     
    181182/** Operator start character map.
    182183 * This indicates which characters that are starting operators and which aren't. */
    183 static char g_auchOpStartCharMap[256];
     184static unsigned char g_auchOpStartCharMap[256];
    184185/** Whether we've initialized the map. */
    185186static int g_fExprInitializedMap = 0;
     
    12391240
    12401241/**
    1241  * Less than or equal
     1242 * Less than or equal, version string.
     1243 *
     1244 * @returns Status code.
     1245 * @param   pThis       The instance.
     1246 */
     1247static EXPRRET expr_op_ver_less_or_equal_than(PEXPR pThis)
     1248{
     1249    EXPRRET     rc = kExprRet_Ok;
     1250    PEXPRVAR    pVar1 = &pThis->aVars[pThis->iVar - 1];
     1251    PEXPRVAR    pVar2 = &pThis->aVars[pThis->iVar];
     1252
     1253    rc = expr_var_unify_types(pThis, pVar1, pVar2, "vle");
     1254    if (rc >= kExprRet_Ok)
     1255    {
     1256        if (!expr_var_is_string(pVar1))
     1257            expr_var_assign_bool(pVar1, pVar1->uVal.i <= pVar2->uVal.i);
     1258        else
     1259            expr_var_assign_bool(pVar1, version_compare(pVar1->uVal.psz, pVar2->uVal.psz) <= 0);
     1260    }
     1261
     1262    expr_pop_and_delete_var(pThis);
     1263    return rc;
     1264}
     1265
     1266
     1267/**
     1268 * Less than or equal.
    12421269 *
    12431270 * @returns Status code.
     
    12651292
    12661293/**
     1294 * Less than, version string.
     1295 *
     1296 * @returns Status code.
     1297 * @param   pThis       The instance.
     1298 */
     1299static EXPRRET expr_op_ver_less_than(PEXPR pThis)
     1300{
     1301    EXPRRET     rc = kExprRet_Ok;
     1302    PEXPRVAR    pVar1 = &pThis->aVars[pThis->iVar - 1];
     1303    PEXPRVAR    pVar2 = &pThis->aVars[pThis->iVar];
     1304
     1305    rc = expr_var_unify_types(pThis, pVar1, pVar2, "vlt");
     1306    if (rc >= kExprRet_Ok)
     1307    {
     1308        if (!expr_var_is_string(pVar1))
     1309            expr_var_assign_bool(pVar1, pVar1->uVal.i < pVar2->uVal.i);
     1310        else
     1311            expr_var_assign_bool(pVar1, version_compare(pVar1->uVal.psz, pVar2->uVal.psz) < 0);
     1312    }
     1313
     1314    expr_pop_and_delete_var(pThis);
     1315    return rc;
     1316}
     1317
     1318
     1319/**
    12671320 * Less than.
    12681321 *
     
    12911344
    12921345/**
    1293  * Greater or equal than
     1346 * Greater or equal than, version string.
     1347 *
     1348 * @returns Status code.
     1349 * @param   pThis       The instance.
     1350 */
     1351static EXPRRET expr_op_ver_greater_or_equal_than(PEXPR pThis)
     1352{
     1353    EXPRRET     rc = kExprRet_Ok;
     1354    PEXPRVAR    pVar1 = &pThis->aVars[pThis->iVar - 1];
     1355    PEXPRVAR    pVar2 = &pThis->aVars[pThis->iVar];
     1356
     1357    rc = expr_var_unify_types(pThis, pVar1, pVar2, "vge");
     1358    if (rc >= kExprRet_Ok)
     1359    {
     1360        if (!expr_var_is_string(pVar1))
     1361            expr_var_assign_bool(pVar1, pVar1->uVal.i >= pVar2->uVal.i);
     1362        else
     1363            expr_var_assign_bool(pVar1, version_compare(pVar1->uVal.psz, pVar2->uVal.psz) >= 0);
     1364    }
     1365
     1366    expr_pop_and_delete_var(pThis);
     1367    return rc;
     1368}
     1369
     1370
     1371/**
     1372 * Greater or equal than.
    12941373 *
    12951374 * @returns Status code.
     
    13171396
    13181397/**
     1398 * Greater than, version string.
     1399 *
     1400 * @returns Status code.
     1401 * @param   pThis       The instance.
     1402 */
     1403static EXPRRET expr_op_ver_greater_than(PEXPR pThis)
     1404{
     1405    EXPRRET     rc = kExprRet_Ok;
     1406    PEXPRVAR    pVar1 = &pThis->aVars[pThis->iVar - 1];
     1407    PEXPRVAR    pVar2 = &pThis->aVars[pThis->iVar];
     1408
     1409    rc = expr_var_unify_types(pThis, pVar1, pVar2, "vgt");
     1410    if (rc >= kExprRet_Ok)
     1411    {
     1412        if (!expr_var_is_string(pVar1))
     1413            expr_var_assign_bool(pVar1, pVar1->uVal.i > pVar2->uVal.i);
     1414        else
     1415            expr_var_assign_bool(pVar1, version_compare(pVar1->uVal.psz, pVar2->uVal.psz) > 0);
     1416    }
     1417
     1418    expr_pop_and_delete_var(pThis);
     1419    return rc;
     1420}
     1421
     1422
     1423/**
    13191424 * Greater than.
    13201425 *
     
    13431448
    13441449/**
    1345  * Equal.
    1346  *
    1347  * @returns Status code.
    1348  * @param   pThis       The instance.
    1349  */
    1350 static EXPRRET expr_op_equal(PEXPR pThis)
     1450 * Equal, version strings.
     1451 *
     1452 * @returns Status code.
     1453 * @param   pThis       The instance.
     1454 */
     1455static EXPRRET expr_op_ver_equal(PEXPR pThis)
    13511456{
    13521457    EXPRRET     rc = kExprRet_Ok;
    13531458    PEXPRVAR    pVar1 = &pThis->aVars[pThis->iVar - 1];
    13541459    PEXPRVAR    pVar2 = &pThis->aVars[pThis->iVar];
     1460    int const   fIsString1 = expr_var_is_string(pVar1);
    13551461
    13561462    /*
    13571463     * The same type?
    13581464     */
    1359     if (expr_var_is_string(pVar1) == expr_var_is_string(pVar2))
    1360     {
    1361         if (!expr_var_is_string(pVar1))
     1465    if (fIsString1 == expr_var_is_string(pVar2))
     1466    {
     1467        if (!fIsString1)
     1468            /* numbers are simple */
     1469            expr_var_assign_bool(pVar1, pVar1->uVal.i == pVar2->uVal.i);
     1470        else
     1471        {
     1472            /* try a normal string compare. */
     1473            expr_var_make_simple_string(pVar1);
     1474            expr_var_make_simple_string(pVar2);
     1475            if (!version_compare(pVar1->uVal.psz, pVar2->uVal.psz))
     1476                expr_var_assign_bool(pVar1, 1);
     1477            /* try convert and compare as number instead. */
     1478            else if (   expr_var_try_make_num(pVar1) >= kExprRet_Ok
     1479                     && expr_var_try_make_num(pVar2) >= kExprRet_Ok)
     1480                expr_var_assign_bool(pVar1, pVar1->uVal.i == pVar2->uVal.i);
     1481            /* ok, they really aren't equal. */
     1482            else
     1483                expr_var_assign_bool(pVar1, 0);
     1484        }
     1485    }
     1486    else
     1487    {
     1488        /*
     1489         * If the type differs, there are now two options:
     1490         *  1. Try convert the string to a valid number and compare the numbers.
     1491         *  2. Convert the non-string to a number and compare the strings.
     1492         */
     1493        if (   expr_var_try_make_num(pVar1) >= kExprRet_Ok
     1494            && expr_var_try_make_num(pVar2) >= kExprRet_Ok)
     1495            expr_var_assign_bool(pVar1, pVar1->uVal.i == pVar2->uVal.i);
     1496        else
     1497        {
     1498            expr_var_make_simple_string(pVar1);
     1499            expr_var_make_simple_string(pVar2);
     1500            expr_var_assign_bool(pVar1, version_compare(pVar1->uVal.psz, pVar2->uVal.psz) == 0);
     1501        }
     1502    }
     1503
     1504    expr_pop_and_delete_var(pThis);
     1505    return rc;
     1506}
     1507
     1508
     1509/**
     1510 * Not equal, version string.
     1511 *
     1512 * @returns Status code.
     1513 * @param   pThis       The instance.
     1514 */
     1515static EXPRRET expr_op_ver_not_equal(PEXPR pThis)
     1516{
     1517    EXPRRET rc = expr_op_ver_equal(pThis);
     1518    if (rc >= kExprRet_Ok)
     1519        rc = expr_op_logical_not(pThis);
     1520    return rc;
     1521}
     1522
     1523
     1524/**
     1525 * Equal.
     1526 *
     1527 * @returns Status code.
     1528 * @param   pThis       The instance.
     1529 */
     1530static EXPRRET expr_op_equal(PEXPR pThis)
     1531{
     1532    EXPRRET     rc = kExprRet_Ok;
     1533    PEXPRVAR    pVar1 = &pThis->aVars[pThis->iVar - 1];
     1534    PEXPRVAR    pVar2 = &pThis->aVars[pThis->iVar];
     1535    int const   fIsString1 = expr_var_is_string(pVar1);
     1536
     1537    /*
     1538     * The same type?
     1539     */
     1540    if (fIsString1 == expr_var_is_string(pVar2))
     1541    {
     1542        if (!fIsString1)
    13621543            /* numbers are simple */
    13631544            expr_var_assign_bool(pVar1, pVar1->uVal.i == pVar2->uVal.i);
     
    16151796    EXPR_OP(">=",          60,      2,    expr_op_greater_or_equal_than),
    16161797    EXPR_OP(">",           60,      2,    expr_op_greater_than),
     1798    EXPR_OP("vle",         60,      2,    expr_op_ver_less_or_equal_than),
     1799    EXPR_OP("vlt",         60,      2,    expr_op_ver_less_than),
     1800    EXPR_OP("vge",         60,      2,    expr_op_ver_greater_or_equal_than),
     1801    EXPR_OP("vgt",         60,      2,    expr_op_ver_greater_than),
    16171802    EXPR_OP("==",          55,      2,    expr_op_equal),
     1803    EXPR_OP("veq",         55,      2,    expr_op_ver_equal),
    16181804    EXPR_OP("!=",          55,      2,    expr_op_not_equal),
     1805    EXPR_OP("vne",         55,      2,    expr_op_ver_not_equal),
    16191806    EXPR_OP("!",           80,      1,    expr_op_logical_not),
    16201807    EXPR_OP("^",           45,      2,    expr_op_bitwise_xor),
     
    16231810    EXPR_OP("||",          30,      2,    expr_op_logical_or),
    16241811    EXPR_OP("|",           40,      2,    expr_op_bitwise_or),
    1625             { "(", 1, ')',   10,      1,    expr_op_left_parenthesis },
    1626             { ")", 1, '(',   10,      0,    expr_op_right_parenthesis },
    1627  /*         { "?", 1, ':',    5,      2,    expr_op_question },
    1628             { ":", 1, '?',    5,      2,    expr_op_colon }, -- too weird for now. */
     1812          { "(", 1, ')',   10,      1,    expr_op_left_parenthesis },
     1813          { ")", 1, '(',   10,      0,    expr_op_right_parenthesis },
     1814 /*       { "?", 1, ':',    5,      2,    expr_op_question },
     1815          { ":", 1, '?',    5,      2,    expr_op_colon }, -- too weird for now. */
    16291816#undef EXPR_OP
    16301817};
     
    16941881    {
    16951882        /* compare the string... */
     1883        if (g_aExprOps[i].szOp[0] != ch)
     1884            continue;
    16961885        switch (g_aExprOps[i].cchOp)
    16971886        {
    16981887            case 1:
    1699                 if (g_aExprOps[i].szOp[0] != ch)
    1700                     continue;
    17011888                break;
    17021889            case 2:
    1703                 if (    g_aExprOps[i].szOp[0] != ch
    1704                     ||  g_aExprOps[i].szOp[1] != psz[1])
     1890                if (g_aExprOps[i].szOp[1] != psz[1])
    17051891                    continue;
    17061892                break;
    17071893            default:
    1708                 if (    g_aExprOps[i].szOp[0] != ch
    1709                     ||  strncmp(&g_aExprOps[i].szOp[1], psz + 1, g_aExprOps[i].cchOp - 1))
     1894                if (strncmp(&g_aExprOps[i].szOp[1], psz + 1, g_aExprOps[i].cchOp - 1))
    17101895                    continue;
    17111896                break;
Note: See TracChangeset for help on using the changeset viewer.

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