- Timestamp:
- Jul 2, 2020 9:16:27 AM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/src/kmk/expreval.c ¶
r3141 r3398 41 41 #include "debug.h" 42 42 #include "hash.h" 43 #include "version_compare.h" 43 44 #include <ctype.h> 44 45 #ifndef _MSC_VER … … 181 182 /** Operator start character map. 182 183 * This indicates which characters that are starting operators and which aren't. */ 183 static char g_auchOpStartCharMap[256];184 static unsigned char g_auchOpStartCharMap[256]; 184 185 /** Whether we've initialized the map. */ 185 186 static int g_fExprInitializedMap = 0; … … 1239 1240 1240 1241 /** 1241 * Less than or equal 1242 * Less than or equal, version string. 1243 * 1244 * @returns Status code. 1245 * @param pThis The instance. 1246 */ 1247 static 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. 1242 1269 * 1243 1270 * @returns Status code. … … 1265 1292 1266 1293 /** 1294 * Less than, version string. 1295 * 1296 * @returns Status code. 1297 * @param pThis The instance. 1298 */ 1299 static 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 /** 1267 1320 * Less than. 1268 1321 * … … 1291 1344 1292 1345 /** 1293 * Greater or equal than 1346 * Greater or equal than, version string. 1347 * 1348 * @returns Status code. 1349 * @param pThis The instance. 1350 */ 1351 static 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. 1294 1373 * 1295 1374 * @returns Status code. … … 1317 1396 1318 1397 /** 1398 * Greater than, version string. 1399 * 1400 * @returns Status code. 1401 * @param pThis The instance. 1402 */ 1403 static 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 /** 1319 1424 * Greater than. 1320 1425 * … … 1343 1448 1344 1449 /** 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 */ 1455 static EXPRRET expr_op_ver_equal(PEXPR pThis) 1351 1456 { 1352 1457 EXPRRET rc = kExprRet_Ok; 1353 1458 PEXPRVAR pVar1 = &pThis->aVars[pThis->iVar - 1]; 1354 1459 PEXPRVAR pVar2 = &pThis->aVars[pThis->iVar]; 1460 int const fIsString1 = expr_var_is_string(pVar1); 1355 1461 1356 1462 /* 1357 1463 * The same type? 1358 1464 */ 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 */ 1515 static 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 */ 1530 static 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) 1362 1543 /* numbers are simple */ 1363 1544 expr_var_assign_bool(pVar1, pVar1->uVal.i == pVar2->uVal.i); … … 1615 1796 EXPR_OP(">=", 60, 2, expr_op_greater_or_equal_than), 1616 1797 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), 1617 1802 EXPR_OP("==", 55, 2, expr_op_equal), 1803 EXPR_OP("veq", 55, 2, expr_op_ver_equal), 1618 1804 EXPR_OP("!=", 55, 2, expr_op_not_equal), 1805 EXPR_OP("vne", 55, 2, expr_op_ver_not_equal), 1619 1806 EXPR_OP("!", 80, 1, expr_op_logical_not), 1620 1807 EXPR_OP("^", 45, 2, expr_op_bitwise_xor), … … 1623 1810 EXPR_OP("||", 30, 2, expr_op_logical_or), 1624 1811 EXPR_OP("|", 40, 2, expr_op_bitwise_or), 1625 1626 1627 /* 1628 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. */ 1629 1816 #undef EXPR_OP 1630 1817 }; … … 1694 1881 { 1695 1882 /* compare the string... */ 1883 if (g_aExprOps[i].szOp[0] != ch) 1884 continue; 1696 1885 switch (g_aExprOps[i].cchOp) 1697 1886 { 1698 1887 case 1: 1699 if (g_aExprOps[i].szOp[0] != ch)1700 continue;1701 1888 break; 1702 1889 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]) 1705 1891 continue; 1706 1892 break; 1707 1893 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)) 1710 1895 continue; 1711 1896 break;
Note:
See TracChangeset
for help on using the changeset viewer.