- Timestamp:
- Sep 4, 2008 5:37:47 AM (16 years ago)
- Location:
- trunk/src/kmk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/Makefile.am
r1716 r1722 126 126 -DCONFIG_WITH_NANOTS \ 127 127 -DCONFIG_WITH_SET_CONDITIONALS \ 128 -DCONFIG_WITH_IF_CONDITIONALS \ 128 129 -DCONFIG_WITH_DATE \ 129 130 -DCONFIG_WITH_FILE_SIZE \ -
trunk/src/kmk/Makefile.kmk
r1719 r1722 159 159 CONFIG_WITH_NANOTS \ 160 160 CONFIG_WITH_SET_CONDITIONALS \ 161 CONFIG_WITH_IF_CONDITIONALS \ 161 162 CONFIG_WITH_DATE \ 162 163 CONFIG_WITH_FILE_SIZE \ -
trunk/src/kmk/ifcond.c
r1721 r1722 89 89 /** A simple string that doesn't need expanding. */ 90 90 kIfCondVar_SimpleString, 91 /** A quoted string in need of expanding (perhaps). */ 92 kIfCondVar_QuotedString, 93 /** A simple quoted string that doesn't need expanding. */ 94 kIfCondVar_QuotedSimpleString, 91 95 /** The end of the valid variable types. */ 92 96 kIfCondVar_End … … 415 419 416 420 /** 421 * Checks if the variable contains a string that was quoted 422 * in the expression. 423 * 424 * @returns 1 if if was a quoted string, otherwise 0. 425 * @param pVar The variable. 426 */ 427 static int ifcond_var_was_quoted(PCIFCONDVAR pVar) 428 { 429 return pVar->enmType >= kIfCondVar_QuotedString; 430 } 431 432 433 /** 417 434 * Deletes a variable. 418 435 * … … 440 457 static void ifcond_var_init_substring(PIFCONDVAR pVar, const char *psz, size_t cch, IFCONDVARTYPE enmType) 441 458 { 442 if ( enmType != kIfCondVar_SimpleString 443 && memchr(psz, '$', cch)) 444 pVar->enmType = kIfCondVar_String; 445 else 446 pVar->enmType = kIfCondVar_SimpleString; 459 /* convert string needing expanding into simple ones if possible. */ 460 if ( enmType == kIfCondVar_String 461 && !memchr(psz, '$', cch)) 462 enmType = kIfCondVar_SimpleString; 463 else if ( enmType == kIfCondVar_QuotedString 464 && !memchr(psz, '$', cch)) 465 enmType = kIfCondVar_QuotedSimpleString; 466 467 pVar->enmType = enmType; 447 468 pVar->uVal.psz = xmalloc(cch + 1); 448 469 memcpy(pVar->uVal.psz, psz, cch); … … 514 535 515 536 case kIfCondVar_String: 537 case kIfCondVar_QuotedString: 516 538 { 517 539 char *psz; … … 522 544 pVar->uVal.psz = psz; 523 545 524 pVar->enmType = kIfCondVar_SimpleString; 546 pVar->enmType = pVar->enmType == kIfCondVar_String 547 ? kIfCondVar_SimpleString 548 : kIfCondVar_QuotedSimpleString; 525 549 break; 526 550 } 527 551 528 552 case kIfCondVar_SimpleString: 553 case kIfCondVar_QuotedSimpleString: 529 554 /* nothing to do. */ 530 555 break; … … 548 573 case kIfCondVar_Num: 549 574 ifcond_var_make_simple_string(pVar); 575 break; 550 576 551 577 case kIfCondVar_String: 552 578 case kIfCondVar_SimpleString: 579 case kIfCondVar_QuotedString: 580 case kIfCondVar_QuotedSimpleString: 553 581 /* nothing to do. */ 554 582 break; … … 615 643 } 616 644 645 case kIfCondVar_QuotedString: 646 case kIfCondVar_QuotedSimpleString: 647 ifcond_error(pThis, "Cannot convert a quoted string to a number"); 648 return kIfCondRet_Error; 649 617 650 default: 618 651 assert(0); 652 return kIfCondRet_Error; 653 } 654 655 return kIfCondRet_Ok; 656 } 657 658 659 /** 660 * Try to turn the variable into a number. 661 * 662 * @returns status code. 663 * @param pVar The variable. 664 */ 665 static IFCONDRET ifcond_var_try_make_num(PIFCONDVAR pVar) 666 { 667 switch (pVar->enmType) 668 { 669 case kIfCondVar_Num: 670 /* nothing to do. */ 671 break; 672 673 case kIfCondVar_String: 674 ifcond_var_make_simple_string(pVar); 675 /* fall thru */ 676 case kIfCondVar_SimpleString: 677 { 678 IFCONDINT64 i; 679 IFCONDRET rc = ifcond_string_to_num(NULL, &i, pVar->uVal.psz, 1 /* fQuiet */); 680 if (rc < kIfCondRet_Ok) 681 return rc; 682 ifcond_var_assign_num(pVar, i); 683 break; 684 } 685 686 default: 687 assert(0); 688 case kIfCondVar_QuotedString: 689 case kIfCondVar_QuotedSimpleString: 690 /* can't do this */ 619 691 return kIfCondRet_Error; 620 692 } … … 685 757 } 686 758 759 case kIfCondVar_QuotedString: 760 ifcond_var_make_simple_string(pVar); 761 /* fall thru */ 762 case kIfCondVar_QuotedSimpleString: 763 /* 764 * Use GNU make boolean logic (not empty string means true). 765 * No stripping here, the string is quoted. 766 */ 767 ifcond_var_assign_bool(pVar, *pVar->uVal.psz != '\0'); 768 break; 769 687 770 default: 688 771 assert(0); … … 705 788 706 789 707 /** 708 * Logical NOT. 709 * 710 * @returns Status code. 711 * @param pThis The instance. 712 */ 713 static IFCONDRET ifcond_op_logical_not(PIFCOND pThis) 790 791 /** 792 * Tries to make the variables the same type. 793 * 794 * This will not convert numbers to strings, unless one of them 795 * is a quoted string. 796 * 797 * this will try convert both to numbers if neither is quoted. Both 798 * conversions will have to suceed for this to be commited. 799 * 800 * All strings will be simplified. 801 * 802 * @returns status code. Done complaining on failure. 803 * 804 * @param pThis The evaluator instance. 805 * @param pVar1 The first variable. 806 * @param pVar2 The second variable. 807 */ 808 static IFCONDRET ifcond_var_unify_types(PIFCOND pThis, PIFCONDVAR pVar1, PIFCONDVAR pVar2, const char *pszOp) 809 { 810 /* 811 * Try make the variables the same type before comparing. 812 */ 813 if ( !ifcond_var_was_quoted(pVar1) 814 && !ifcond_var_was_quoted(pVar2)) 815 { 816 if ( ifcond_var_is_string(pVar1) 817 || ifcond_var_is_string(pVar2)) 818 { 819 if (!ifcond_var_is_string(pVar1)) 820 ifcond_var_try_make_num(pVar2); 821 else if (!ifcond_var_is_string(pVar2)) 822 ifcond_var_try_make_num(pVar1); 823 else 824 { 825 /* 826 * Both are strings, simplify them then see if both can be made into numbers. 827 */ 828 IFCONDINT64 iVar1; 829 IFCONDINT64 iVar2; 830 831 ifcond_var_make_simple_string(pVar1); 832 ifcond_var_make_simple_string(pVar2); 833 834 if ( ifcond_string_to_num(NULL, &iVar1, pVar1->uVal.psz, 1 /* fQuiet */) >= kIfCondRet_Ok 835 && ifcond_string_to_num(NULL, &iVar2, pVar2->uVal.psz, 1 /* fQuiet */) >= kIfCondRet_Ok) 836 { 837 ifcond_var_assign_num(pVar1, iVar1); 838 ifcond_var_assign_num(pVar2, iVar2); 839 } 840 } 841 } 842 } 843 else 844 { 845 ifcond_var_make_simple_string(pVar1); 846 ifcond_var_make_simple_string(pVar2); 847 } 848 849 /* 850 * Complain if they aren't the same type now. 851 */ 852 if (ifcond_var_is_string(pVar1) != ifcond_var_is_string(pVar2)) 853 { 854 ifcond_error(pThis, "Unable to unify types for \"%s\"", pszOp); 855 return kIfCondRet_Error; 856 } 857 return kIfCondRet_Ok; 858 } 859 860 861 /** 862 * Is variable defined, unary. 863 * 864 * @returns Status code. 865 * @param pThis The instance. 866 */ 867 static IFCONDRET ifcond_op_defined(PIFCOND pThis) 868 { 869 PIFCONDVAR pVar = &pThis->aVars[pThis->iVar]; 870 struct variable *pMakeVar; 871 assert(pThis->iVar >= 0); 872 873 ifcond_var_make_simple_string(pVar); 874 pMakeVar = lookup_variable(pVar->uVal.psz, strlen(pVar->uVal.psz)); 875 ifcond_var_assign_bool(pVar, pMakeVar && *pMakeVar->value != '\0'); 876 877 return kIfCondRet_Ok; 878 } 879 880 881 /** 882 * Is target defined, unary. 883 * 884 * @returns Status code. 885 * @param pThis The instance. 886 */ 887 static IFCONDRET ifcond_op_target(PIFCOND pThis) 888 { 889 PIFCONDVAR pVar = &pThis->aVars[pThis->iVar]; 890 struct file *pFile = NULL; 891 assert(pThis->iVar >= 0); 892 893 /* 894 * Because of secondary target expansion, lookup the unexpanded 895 * name first. 896 */ 897 #ifdef CONFIG_WITH_2ND_TARGET_EXPANSION 898 if ( pVar->enmType == kIfCondVar_String 899 || pVar->enmType == kIfCondVar_QuotedString) 900 { 901 pFile = lookup_file(pVar->uVal.psz); 902 if ( pFile 903 && !pFile->need_2nd_target_expansion) 904 pFile = NULL; 905 } 906 if (pFile) 907 #endif 908 { 909 ifcond_var_make_simple_string(pVar); 910 pFile = lookup_file(pVar->uVal.psz); 911 } 912 913 /* 914 * Always inspect the head of a multiple target rule 915 * and look for a file with commands. 916 */ 917 #ifdef CONFIG_WITH_EXPLICIT_MULTITARGET 918 if (pFile && pFile->multi_head) 919 pFile = pFile->multi_head; 920 #endif 921 922 while (pFile && !pFile->cmds) 923 pFile = pFile->prev; 924 925 ifcond_var_assign_bool(pVar, pFile != NULL && pFile->is_target); 926 927 return kIfCondRet_Ok; 928 } 929 930 931 /** 932 * Pluss (dummy / make_integer) 933 * 934 * @returns Status code. 935 * @param pThis The instance. 936 */ 937 static IFCONDRET ifcond_op_pluss(PIFCOND pThis) 714 938 { 715 939 PIFCONDVAR pVar = &pThis->aVars[pThis->iVar]; 716 940 assert(pThis->iVar >= 0); 717 941 942 return ifcond_var_make_num(pThis, pVar); 943 } 944 945 946 947 /** 948 * Minus (negate) 949 * 950 * @returns Status code. 951 * @param pThis The instance. 952 */ 953 static IFCONDRET ifcond_op_minus(PIFCOND pThis) 954 { 955 IFCONDRET rc; 956 PIFCONDVAR pVar = &pThis->aVars[pThis->iVar]; 957 assert(pThis->iVar >= 0); 958 959 rc = ifcond_var_make_num(pThis, pVar); 960 if (rc >= kIfCondRet_Ok) 961 pVar->uVal.i = -pVar->uVal.i; 962 963 return rc; 964 } 965 966 967 968 /** 969 * Bitwise NOT. 970 * 971 * @returns Status code. 972 * @param pThis The instance. 973 */ 974 static IFCONDRET ifcond_op_bitwise_not(PIFCOND pThis) 975 { 976 IFCONDRET rc; 977 PIFCONDVAR pVar = &pThis->aVars[pThis->iVar]; 978 assert(pThis->iVar >= 0); 979 980 rc = ifcond_var_make_num(pThis, pVar); 981 if (rc >= kIfCondRet_Ok) 982 pVar->uVal.i = ~pVar->uVal.i; 983 984 return rc; 985 } 986 987 988 /** 989 * Logical NOT. 990 * 991 * @returns Status code. 992 * @param pThis The instance. 993 */ 994 static IFCONDRET ifcond_op_logical_not(PIFCOND pThis) 995 { 996 PIFCONDVAR pVar = &pThis->aVars[pThis->iVar]; 997 assert(pThis->iVar >= 0); 998 718 999 ifcond_var_assign_bool(pVar, !ifcond_var_make_bool(pVar)); 719 1000 … … 722 1003 723 1004 724 ///// 725 726 727 /** 728 * Not equal. 729 * 730 * @returns Status code. 731 * @param pThis The instance. 732 */ 733 static IFCONDRET ifcond_op_equal(PIFCOND pThis) 734 { 1005 /** 1006 * Multiplication. 1007 * 1008 * @returns Status code. 1009 * @param pThis The instance. 1010 */ 1011 static IFCONDRET ifcond_op_multiply(PIFCOND pThis) 1012 { 1013 IFCONDRET rc = kIfCondRet_Ok; 735 1014 PIFCONDVAR pVar1 = &pThis->aVars[pThis->iVar - 1]; 736 1015 PIFCONDVAR pVar2 = &pThis->aVars[pThis->iVar]; 737 1016 assert(pThis->iVar >= 1); 738 1017 1018 rc = ifcond_var_make_num(pThis, pVar1); 1019 if (rc >= kIfCondRet_Ok) 1020 { 1021 rc = ifcond_var_make_num(pThis, pVar2); 1022 if (rc >= kIfCondRet_Ok) 1023 pVar1->uVal.i %= pVar2->uVal.i; 1024 } 1025 1026 ifcond_pop_and_delete_var(pThis); 1027 return rc; 1028 } 1029 1030 1031 1032 /** 1033 * Division. 1034 * 1035 * @returns Status code. 1036 * @param pThis The instance. 1037 */ 1038 static IFCONDRET ifcond_op_divide(PIFCOND pThis) 1039 { 1040 IFCONDRET rc = kIfCondRet_Ok; 1041 PIFCONDVAR pVar1 = &pThis->aVars[pThis->iVar - 1]; 1042 PIFCONDVAR pVar2 = &pThis->aVars[pThis->iVar]; 1043 assert(pThis->iVar >= 1); 1044 1045 rc = ifcond_var_make_num(pThis, pVar1); 1046 if (rc >= kIfCondRet_Ok) 1047 { 1048 rc = ifcond_var_make_num(pThis, pVar2); 1049 if (rc >= kIfCondRet_Ok) 1050 pVar1->uVal.i /= pVar2->uVal.i; 1051 } 1052 1053 ifcond_pop_and_delete_var(pThis); 1054 return rc; 1055 } 1056 1057 1058 1059 /** 1060 * Modulus. 1061 * 1062 * @returns Status code. 1063 * @param pThis The instance. 1064 */ 1065 static IFCONDRET ifcond_op_modulus(PIFCOND pThis) 1066 { 1067 IFCONDRET rc = kIfCondRet_Ok; 1068 PIFCONDVAR pVar1 = &pThis->aVars[pThis->iVar - 1]; 1069 PIFCONDVAR pVar2 = &pThis->aVars[pThis->iVar]; 1070 assert(pThis->iVar >= 1); 1071 1072 rc = ifcond_var_make_num(pThis, pVar1); 1073 if (rc >= kIfCondRet_Ok) 1074 { 1075 rc = ifcond_var_make_num(pThis, pVar2); 1076 if (rc >= kIfCondRet_Ok) 1077 pVar1->uVal.i %= pVar2->uVal.i; 1078 } 1079 1080 ifcond_pop_and_delete_var(pThis); 1081 return rc; 1082 } 1083 1084 1085 1086 /** 1087 * Addition (numeric). 1088 * 1089 * @returns Status code. 1090 * @param pThis The instance. 1091 */ 1092 static IFCONDRET ifcond_op_add(PIFCOND pThis) 1093 { 1094 IFCONDRET rc = kIfCondRet_Ok; 1095 PIFCONDVAR pVar1 = &pThis->aVars[pThis->iVar - 1]; 1096 PIFCONDVAR pVar2 = &pThis->aVars[pThis->iVar]; 1097 assert(pThis->iVar >= 1); 1098 1099 rc = ifcond_var_make_num(pThis, pVar1); 1100 if (rc >= kIfCondRet_Ok) 1101 { 1102 rc = ifcond_var_make_num(pThis, pVar2); 1103 if (rc >= kIfCondRet_Ok) 1104 pVar1->uVal.i += pVar2->uVal.i; 1105 } 1106 1107 ifcond_pop_and_delete_var(pThis); 1108 return rc; 1109 } 1110 1111 1112 /** 1113 * Subtract (numeric). 1114 * 1115 * @returns Status code. 1116 * @param pThis The instance. 1117 */ 1118 static IFCONDRET ifcond_op_sub(PIFCOND pThis) 1119 { 1120 IFCONDRET rc = kIfCondRet_Ok; 1121 PIFCONDVAR pVar1 = &pThis->aVars[pThis->iVar - 1]; 1122 PIFCONDVAR pVar2 = &pThis->aVars[pThis->iVar]; 1123 assert(pThis->iVar >= 1); 1124 1125 rc = ifcond_var_make_num(pThis, pVar1); 1126 if (rc >= kIfCondRet_Ok) 1127 { 1128 rc = ifcond_var_make_num(pThis, pVar2); 1129 if (rc >= kIfCondRet_Ok) 1130 pVar1->uVal.i -= pVar2->uVal.i; 1131 } 1132 1133 ifcond_pop_and_delete_var(pThis); 1134 return rc; 1135 } 1136 1137 /** 1138 * Bitwise left shift. 1139 * 1140 * @returns Status code. 1141 * @param pThis The instance. 1142 */ 1143 static IFCONDRET ifcond_op_shift_left(PIFCOND pThis) 1144 { 1145 IFCONDRET rc = kIfCondRet_Ok; 1146 PIFCONDVAR pVar1 = &pThis->aVars[pThis->iVar - 1]; 1147 PIFCONDVAR pVar2 = &pThis->aVars[pThis->iVar]; 1148 assert(pThis->iVar >= 1); 1149 1150 rc = ifcond_var_make_num(pThis, pVar1); 1151 if (rc >= kIfCondRet_Ok) 1152 { 1153 rc = ifcond_var_make_num(pThis, pVar2); 1154 if (rc >= kIfCondRet_Ok) 1155 pVar1->uVal.i <<= pVar2->uVal.i; 1156 } 1157 1158 ifcond_pop_and_delete_var(pThis); 1159 return rc; 1160 } 1161 1162 1163 /** 1164 * Bitwise right shift. 1165 * 1166 * @returns Status code. 1167 * @param pThis The instance. 1168 */ 1169 static IFCONDRET ifcond_op_shift_right(PIFCOND pThis) 1170 { 1171 IFCONDRET rc = kIfCondRet_Ok; 1172 PIFCONDVAR pVar1 = &pThis->aVars[pThis->iVar - 1]; 1173 PIFCONDVAR pVar2 = &pThis->aVars[pThis->iVar]; 1174 assert(pThis->iVar >= 1); 1175 1176 rc = ifcond_var_make_num(pThis, pVar1); 1177 if (rc >= kIfCondRet_Ok) 1178 { 1179 rc = ifcond_var_make_num(pThis, pVar2); 1180 if (rc >= kIfCondRet_Ok) 1181 pVar1->uVal.i >>= pVar2->uVal.i; 1182 } 1183 1184 ifcond_pop_and_delete_var(pThis); 1185 return rc; 1186 } 1187 1188 1189 /** 1190 * Less than or equal 1191 * 1192 * @returns Status code. 1193 * @param pThis The instance. 1194 */ 1195 static IFCONDRET ifcond_op_less_or_equal_than(PIFCOND pThis) 1196 { 1197 IFCONDRET rc = kIfCondRet_Ok; 1198 PIFCONDVAR pVar1 = &pThis->aVars[pThis->iVar - 1]; 1199 PIFCONDVAR pVar2 = &pThis->aVars[pThis->iVar]; 1200 assert(pThis->iVar >= 1); 1201 1202 rc = ifcond_var_unify_types(pThis, pVar1, pVar2, "<="); 1203 if (rc >= kIfCondRet_Ok) 1204 { 1205 if (!ifcond_var_is_string(pVar1)) 1206 ifcond_var_assign_bool(pVar1, pVar1->uVal.i <= pVar2->uVal.i); 1207 else 1208 ifcond_var_assign_bool(pVar1, strcmp(pVar1->uVal.psz, pVar2->uVal.psz) <= 0); 1209 } 1210 1211 ifcond_pop_and_delete_var(pThis); 1212 return rc; 1213 } 1214 1215 1216 /** 1217 * Less than. 1218 * 1219 * @returns Status code. 1220 * @param pThis The instance. 1221 */ 1222 static IFCONDRET ifcond_op_less_than(PIFCOND pThis) 1223 { 1224 IFCONDRET rc = kIfCondRet_Ok; 1225 PIFCONDVAR pVar1 = &pThis->aVars[pThis->iVar - 1]; 1226 PIFCONDVAR pVar2 = &pThis->aVars[pThis->iVar]; 1227 assert(pThis->iVar >= 1); 1228 1229 rc = ifcond_var_unify_types(pThis, pVar1, pVar2, "<"); 1230 if (rc >= kIfCondRet_Ok) 1231 { 1232 if (!ifcond_var_is_string(pVar1)) 1233 ifcond_var_assign_bool(pVar1, pVar1->uVal.i < pVar2->uVal.i); 1234 else 1235 ifcond_var_assign_bool(pVar1, strcmp(pVar1->uVal.psz, pVar2->uVal.psz) < 0); 1236 } 1237 1238 ifcond_pop_and_delete_var(pThis); 1239 return rc; 1240 } 1241 1242 1243 /** 1244 * Greater or equal than 1245 * 1246 * @returns Status code. 1247 * @param pThis The instance. 1248 */ 1249 static IFCONDRET ifcond_op_greater_or_equal_than(PIFCOND pThis) 1250 { 1251 IFCONDRET rc = kIfCondRet_Ok; 1252 PIFCONDVAR pVar1 = &pThis->aVars[pThis->iVar - 1]; 1253 PIFCONDVAR pVar2 = &pThis->aVars[pThis->iVar]; 1254 assert(pThis->iVar >= 1); 1255 1256 rc = ifcond_var_unify_types(pThis, pVar1, pVar2, ">="); 1257 if (rc >= kIfCondRet_Ok) 1258 { 1259 if (!ifcond_var_is_string(pVar1)) 1260 ifcond_var_assign_bool(pVar1, pVar1->uVal.i >= pVar2->uVal.i); 1261 else 1262 ifcond_var_assign_bool(pVar1, strcmp(pVar1->uVal.psz, pVar2->uVal.psz) >= 0); 1263 } 1264 1265 ifcond_pop_and_delete_var(pThis); 1266 return rc; 1267 } 1268 1269 1270 /** 1271 * Greater than. 1272 * 1273 * @returns Status code. 1274 * @param pThis The instance. 1275 */ 1276 static IFCONDRET ifcond_op_greater_than(PIFCOND pThis) 1277 { 1278 IFCONDRET rc = kIfCondRet_Ok; 1279 PIFCONDVAR pVar1 = &pThis->aVars[pThis->iVar - 1]; 1280 PIFCONDVAR pVar2 = &pThis->aVars[pThis->iVar]; 1281 assert(pThis->iVar >= 1); 1282 1283 rc = ifcond_var_unify_types(pThis, pVar1, pVar2, ">"); 1284 if (rc >= kIfCondRet_Ok) 1285 { 1286 if (!ifcond_var_is_string(pVar1)) 1287 ifcond_var_assign_bool(pVar1, pVar1->uVal.i > pVar2->uVal.i); 1288 else 1289 ifcond_var_assign_bool(pVar1, strcmp(pVar1->uVal.psz, pVar2->uVal.psz) > 0); 1290 } 1291 1292 ifcond_pop_and_delete_var(pThis); 1293 return rc; 1294 } 1295 1296 1297 /** 1298 * Equal. 1299 * 1300 * @returns Status code. 1301 * @param pThis The instance. 1302 */ 1303 static IFCONDRET ifcond_op_equal(PIFCOND pThis) 1304 { 1305 IFCONDRET rc = kIfCondRet_Ok; 1306 PIFCONDVAR pVar1 = &pThis->aVars[pThis->iVar - 1]; 1307 PIFCONDVAR pVar2 = &pThis->aVars[pThis->iVar]; 1308 assert(pThis->iVar >= 1); 1309 739 1310 /* 740 * If it's the same type, things are simple.1311 * The same type? 741 1312 */ 742 1313 if (ifcond_var_is_string(pVar1) == ifcond_var_is_string(pVar2)) 743 1314 { 744 if (ifcond_var_is_string(pVar1)) 1315 if (!ifcond_var_is_string(pVar1)) 1316 /* numbers are simple */ 1317 ifcond_var_assign_bool(pVar1, pVar1->uVal.i == pVar2->uVal.i); 1318 else 745 1319 { 1320 /* try a normal string compare. */ 746 1321 ifcond_var_make_simple_string(pVar1); 747 1322 ifcond_var_make_simple_string(pVar2); 748 ifcond_var_assign_bool(pVar1, !strcmp(pVar1->uVal.psz, pVar2->uVal.psz)); 1323 if (!strcmp(pVar1->uVal.psz, pVar2->uVal.psz)) 1324 ifcond_var_assign_bool(pVar1, 1); 1325 /* try convert and compare as number instead. */ 1326 else if ( ifcond_var_try_make_num(pVar1) >= kIfCondRet_Ok 1327 && ifcond_var_try_make_num(pVar2) >= kIfCondRet_Ok) 1328 ifcond_var_assign_bool(pVar1, pVar1->uVal.i == pVar2->uVal.i); 1329 /* ok, they really aren't equal. */ 1330 else 1331 ifcond_var_assign_bool(pVar1, 0); 749 1332 } 750 else751 ifcond_var_assign_bool(pVar1, pVar1->uVal.i == pVar2->uVal.i);752 1333 } 753 1334 else … … 757 1338 * 1. Convert the string to a valid number and compare the numbers. 758 1339 * 2. Convert an empty string to a 'false' boolean value and compare 759 * numerically. This one is a bit questionable, so it's currently 760 * not enabled. 1340 * numerically. This one is a bit questionable, so we don't try this. 761 1341 */ 762 IFCONDINT64 iVal1; 763 PIFCONDVAR pVarRet = pVar1; 764 765 /* switch so pVar1 is the string. */ 766 if (!ifcond_var_is_string(pVar1)) 767 { 768 pVar1 = pVar2; 769 pVar2 = pVarRet; 770 } 771 772 ifcond_var_make_simple_string(pVar1); 773 if (ifcond_string_to_num(NULL, &iVal1, pVar1->uVal.psz, 1 /* fQuiet */) >= kIfCondRet_Ok) 774 ifcond_var_assign_bool(pVar1, iVal1 == pVar2->uVal.i); 1342 if ( ifcond_var_try_make_num(pVar1) >= kIfCondRet_Ok 1343 && ifcond_var_try_make_num(pVar2) >= kIfCondRet_Ok) 1344 ifcond_var_assign_bool(pVar1, pVar1->uVal.i == pVar2->uVal.i); 775 1345 else 776 1346 { 777 #if 0 /* bogus consept */ 778 const char *psz = pVar1->uVal.psz; 779 while (isspace((unsigned char)*psz)) 780 psz++; 781 if (!*psz) 782 ifcond_var_assign_bool(pVar1, iVal1 == pVar2->uVal.i); 783 else 784 #endif 785 { 786 ifcond_error(pThis, "Cannot compare strings and numbers"); 787 return kIfCondRet_Error; 788 } 1347 ifcond_error(pThis, "Cannot compare strings and numbers"); 1348 rc = kIfCondRet_Error; 789 1349 } 790 1350 } … … 818 1378 static IFCONDRET ifcond_op_bitwise_and(PIFCOND pThis) 819 1379 { 820 IFCONDRET rc; 1380 PIFCONDVAR pVar1 = &pThis->aVars[pThis->iVar - 1]; 1381 PIFCONDVAR pVar2 = &pThis->aVars[pThis->iVar]; 1382 IFCONDRET rc; 821 1383 assert(pThis->iVar >= 1); 822 1384 823 rc = ifcond_var_make_num(pThis, &pThis->aVars[pThis->iVar - 1]);1385 rc = ifcond_var_make_num(pThis, pVar1); 824 1386 if (rc >= kIfCondRet_Ok) 825 1387 { 826 rc = ifcond_var_make_num(pThis, &pThis->aVars[pThis->iVar]);1388 rc = ifcond_var_make_num(pThis, pVar2); 827 1389 if (rc >= kIfCondRet_Ok) 828 p This->aVars[pThis->iVar - 1].uVal.i &= pThis->aVars[pThis->iVar].uVal.i;1390 pVar1->uVal.i &= pVar2->uVal.i; 829 1391 } 830 1392 … … 842 1404 static IFCONDRET ifcond_op_bitwise_xor(PIFCOND pThis) 843 1405 { 844 IFCONDRET rc; 1406 PIFCONDVAR pVar1 = &pThis->aVars[pThis->iVar - 1]; 1407 PIFCONDVAR pVar2 = &pThis->aVars[pThis->iVar]; 1408 IFCONDRET rc; 845 1409 assert(pThis->iVar >= 1); 846 1410 847 rc = ifcond_var_make_num(pThis, &pThis->aVars[pThis->iVar - 1]);1411 rc = ifcond_var_make_num(pThis, pVar1); 848 1412 if (rc >= kIfCondRet_Ok) 849 1413 { 850 rc = ifcond_var_make_num(pThis, &pThis->aVars[pThis->iVar]);1414 rc = ifcond_var_make_num(pThis, pVar2); 851 1415 if (rc >= kIfCondRet_Ok) 852 p This->aVars[pThis->iVar - 1].uVal.i ^= pThis->aVars[pThis->iVar].uVal.i;1416 pVar1->uVal.i ^= pVar2->uVal.i; 853 1417 } 854 1418 … … 866 1430 static IFCONDRET ifcond_op_bitwise_or(PIFCOND pThis) 867 1431 { 868 IFCONDRET rc; 1432 PIFCONDVAR pVar1 = &pThis->aVars[pThis->iVar - 1]; 1433 PIFCONDVAR pVar2 = &pThis->aVars[pThis->iVar]; 1434 IFCONDRET rc; 869 1435 assert(pThis->iVar >= 1); 870 1436 871 rc = ifcond_var_make_num(pThis, &pThis->aVars[pThis->iVar - 1]);1437 rc = ifcond_var_make_num(pThis, pVar1); 872 1438 if (rc >= kIfCondRet_Ok) 873 1439 { 874 rc = ifcond_var_make_num(pThis, &pThis->aVars[pThis->iVar]);1440 rc = ifcond_var_make_num(pThis, pVar2); 875 1441 if (rc >= kIfCondRet_Ok) 876 p This->aVars[pThis->iVar - 1].uVal.i |= pThis->aVars[pThis->iVar].uVal.i;1442 pVar1->uVal.i |= pVar2->uVal.i; 877 1443 } 878 1444 … … 890 1456 static IFCONDRET ifcond_op_logical_and(PIFCOND pThis) 891 1457 { 1458 PIFCONDVAR pVar1 = &pThis->aVars[pThis->iVar - 1]; 1459 PIFCONDVAR pVar2 = &pThis->aVars[pThis->iVar]; 892 1460 assert(pThis->iVar >= 1); 893 if ( ifcond_var_make_bool(&pThis->aVars[pThis->iVar - 1]) 894 && ifcond_var_make_bool(&pThis->aVars[pThis->iVar])) 895 ifcond_var_assign_bool(&pThis->aVars[pThis->iVar - 1], 1); 1461 1462 if ( ifcond_var_make_bool(pVar1) 1463 && ifcond_var_make_bool(pVar2)) 1464 ifcond_var_assign_bool(pVar1, 1); 896 1465 else 897 ifcond_var_assign_bool( &pThis->aVars[pThis->iVar - 1], 0);1466 ifcond_var_assign_bool(pVar1, 0); 898 1467 899 1468 ifcond_pop_and_delete_var(pThis); … … 910 1479 static IFCONDRET ifcond_op_logical_or(PIFCOND pThis) 911 1480 { 1481 PIFCONDVAR pVar1 = &pThis->aVars[pThis->iVar - 1]; 1482 PIFCONDVAR pVar2 = &pThis->aVars[pThis->iVar]; 912 1483 assert(pThis->iVar >= 1); 913 if ( ifcond_var_make_bool(&pThis->aVars[pThis->iVar - 1]) 914 || ifcond_var_make_bool(&pThis->aVars[pThis->iVar])) 915 ifcond_var_assign_bool(&pThis->aVars[pThis->iVar - 1], 1); 1484 1485 if ( ifcond_var_make_bool(pVar1) 1486 || ifcond_var_make_bool(pVar2)) 1487 ifcond_var_assign_bool(pVar1, 1); 916 1488 else 917 ifcond_var_assign_bool( &pThis->aVars[pThis->iVar - 1], 0);1489 ifcond_var_assign_bool(pVar1, 0); 918 1490 919 1491 ifcond_pop_and_delete_var(pThis); … … 980 1552 #define IFCOND_OP(szOp, iPrecedence, cArgs, pfn) { szOp, sizeof(szOp) - 1, '\0', iPrecedence, cArgs, pfn } 981 1553 /* Name, iPrecedence, cArgs, pfn */ 982 #if 0983 1554 IFCOND_OP("defined", 90, 1, ifcond_op_defined), 1555 IFCOND_OP("target", 90, 1, ifcond_op_target), 984 1556 IFCOND_OP("+", 80, 1, ifcond_op_pluss), 985 1557 IFCOND_OP("-", 80, 1, ifcond_op_minus), … … 987 1559 IFCOND_OP("*", 75, 2, ifcond_op_multiply), 988 1560 IFCOND_OP("/", 75, 2, ifcond_op_divide), 989 IFCOND_OP("%", 75, 2, ifcond_op_mod ),1561 IFCOND_OP("%", 75, 2, ifcond_op_modulus), 990 1562 IFCOND_OP("+", 70, 2, ifcond_op_add), 991 1563 IFCOND_OP("-", 70, 2, ifcond_op_sub), … … 996 1568 IFCOND_OP(">=", 60, 2, ifcond_op_greater_or_equal_than), 997 1569 IFCOND_OP(">", 60, 2, ifcond_op_greater_than), 998 #endif999 1570 IFCOND_OP("==", 55, 2, ifcond_op_equal), 1000 1571 IFCOND_OP("!=", 55, 2, ifcond_op_not_equal), … … 1265 1836 while (*psz && *psz != '"') 1266 1837 psz++; 1267 ifcond_var_init_substring(&pThis->aVars[++pThis->iVar], pszStart, psz - pszStart, kIfCondVar_ String);1838 ifcond_var_init_substring(&pThis->aVars[++pThis->iVar], pszStart, psz - pszStart, kIfCondVar_QuotedString); 1268 1839 } 1269 1840 else if (*psz == '\'') … … 1272 1843 while (*psz && *psz != '\'') 1273 1844 psz++; 1274 ifcond_var_init_substring(&pThis->aVars[++pThis->iVar], pszStart, psz - pszStart, kIfCondVar_ SimpleString);1845 ifcond_var_init_substring(&pThis->aVars[++pThis->iVar], pszStart, psz - pszStart, kIfCondVar_QuotedSimpleString); 1275 1846 } 1276 1847 else -
trunk/src/kmk/testcase-ifcond.kmk
r1720 r1722 25 25 # 26 26 27 27 28 #DEPTH = ../.. 28 29 #include $(PATH_KBUILD)/header.kmk … … 62 63 endif 63 64 64 if 0 || 0 || 0 || 0 || 0 || 0 || 0 65 $(error ) 66 else 67 $(warning works) 68 endif 69 70 if 0 || 0 || 0 || 1 || 0 || 0 || 0 65 if 0 || 0 || 0 || 0 || 0 || 0 || 0 66 $(error ) 67 else 68 $(warning works) 69 endif 70 71 if 0 || 0 || 0 || 1 || 0 || 0 || 0 71 72 $(warning works) 72 73 else … … 101 102 $(error ) 102 103 endif 104 105 106 # 107 # Equal and Not Equal. 108 # 109 if 1 == 1 110 $(warning works) 111 else 112 $(error ) 113 endif 114 115 if 2 == 3 116 $(error ) 117 else 118 $(warning works) 119 endif 120 121 if 2 != 3 122 $(warning works) 123 else 124 $(error ) 125 endif 126 127 128 # 129 # XOR 130 # 131 if 1 ^ 1 132 $(error ) 133 else 134 $(warning works) 135 endif 136 137 if 2 ^ 1 == 3 138 $(warning works) 139 else 140 $(error ) 141 endif 142 143 if 7 == 2 ^ 1 ^ 4 144 $(warning works) 145 else 146 $(error ) 147 endif 148 149 150 # 151 # Logical NOT 152 # 153 if !1 154 $(error ) 155 else 156 $(warning works) 157 endif 158 159 if !42 == 0 160 $(warning works) 161 else 162 $(error ) 163 endif 164 165 if !0 == 1 166 $(warning works) 167 else 168 $(error ) 169 endif 170 171 if !!0 == 0 172 $(warning works) 173 else 174 $(error ) 175 endif 176 177 178 # 179 # Greater than 180 # 181 if 1 > 0 182 $(warning works) 183 else 184 $(error ) 185 endif 186 187 if 1024 > 1023 188 $(warning works) 189 else 190 $(error ) 191 endif 192 193 if 999 > 1023 194 $(error ) 195 else 196 $(warning works) 197 endif 198 199 200 # 201 # Greater or equal than 202 # 203 if 20 > 0 204 $(warning works) 205 else 206 $(error ) 207 endif 208 209 if 20 >= 20 210 $(warning works) 211 else 212 $(error ) 213 endif 214 215 if 19 >= 20 216 $(error ) 217 else 218 $(warning works) 219 endif 220 221 222 # 223 # target() 224 # 225 trg_deps_only: foobar 226 trg_with_cmds: foobar 227 echo $@ 228 229 if target trg_with_cmds 230 $(warning works) 231 else 232 $(error works) 233 endif 234 235 if target trg_deps_only 236 $(error works) 237 else 238 $(warning works) 239 endif 240 241 if target foobar 242 $(error works) 243 else 244 $(warning works) 245 endif 246 247 248 # 249 # defined() 250 # 251 var_defined := 1 252 var_not_defined := 253 254 if defined var_defined 255 $(warning works) 256 else 257 $(error works) 258 endif 259 260 if defined(var_defined) 261 $(warning works) 262 else 263 $(error works) 264 endif 265 266 if defined (var_defined) 267 $(warning works) 268 else 269 $(error works) 270 endif 271 272 if defined (var_not_defined) 273 $(error works) 274 else 275 $(warning works) 276 endif 277 103 278 104 279
Note:
See TracChangeset
for help on using the changeset viewer.