VirtualBox

Changeset 1722 in kBuild for trunk


Ignore:
Timestamp:
Sep 4, 2008 5:37:47 AM (16 years ago)
Author:
bird
Message:

kmk: The rest of the if operators.

Location:
trunk/src/kmk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/Makefile.am

    r1716 r1722  
    126126        -DCONFIG_WITH_NANOTS \
    127127        -DCONFIG_WITH_SET_CONDITIONALS \
     128        -DCONFIG_WITH_IF_CONDITIONALS \
    128129        -DCONFIG_WITH_DATE \
    129130        -DCONFIG_WITH_FILE_SIZE \
  • trunk/src/kmk/Makefile.kmk

    r1719 r1722  
    159159        CONFIG_WITH_NANOTS \
    160160        CONFIG_WITH_SET_CONDITIONALS \
     161        CONFIG_WITH_IF_CONDITIONALS \
    161162        CONFIG_WITH_DATE \
    162163        CONFIG_WITH_FILE_SIZE \
  • trunk/src/kmk/ifcond.c

    r1721 r1722  
    8989    /** A simple string that doesn't need expanding. */
    9090    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,
    9195    /** The end of the valid variable types. */
    9296    kIfCondVar_End
     
    415419
    416420/**
     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 */
     427static int ifcond_var_was_quoted(PCIFCONDVAR pVar)
     428{
     429    return pVar->enmType >= kIfCondVar_QuotedString;
     430}
     431
     432
     433/**
    417434 * Deletes a variable.
    418435 *
     
    440457static void ifcond_var_init_substring(PIFCONDVAR pVar, const char *psz, size_t cch, IFCONDVARTYPE enmType)
    441458{
    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;
    447468    pVar->uVal.psz = xmalloc(cch + 1);
    448469    memcpy(pVar->uVal.psz, psz, cch);
     
    514535
    515536        case kIfCondVar_String:
     537        case kIfCondVar_QuotedString:
    516538        {
    517539            char *psz;
     
    522544            pVar->uVal.psz = psz;
    523545
    524             pVar->enmType = kIfCondVar_SimpleString;
     546            pVar->enmType = pVar->enmType == kIfCondVar_String
     547                          ? kIfCondVar_SimpleString
     548                          : kIfCondVar_QuotedSimpleString;
    525549            break;
    526550        }
    527551
    528552        case kIfCondVar_SimpleString:
     553        case kIfCondVar_QuotedSimpleString:
    529554            /* nothing to do. */
    530555            break;
     
    548573        case kIfCondVar_Num:
    549574            ifcond_var_make_simple_string(pVar);
     575            break;
    550576
    551577        case kIfCondVar_String:
    552578        case kIfCondVar_SimpleString:
     579        case kIfCondVar_QuotedString:
     580        case kIfCondVar_QuotedSimpleString:
    553581            /* nothing to do. */
    554582            break;
     
    615643        }
    616644
     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
    617650        default:
    618651            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 */
     665static 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 */
    619691            return kIfCondRet_Error;
    620692    }
     
    685757        }
    686758
     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
    687770        default:
    688771            assert(0);
     
    705788
    706789
    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 */
     808static 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 */
     867static 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 */
     887static 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 */
     937static IFCONDRET ifcond_op_pluss(PIFCOND pThis)
    714938{
    715939    PIFCONDVAR pVar = &pThis->aVars[pThis->iVar];
    716940    assert(pThis->iVar >= 0);
    717941
     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 */
     953static 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 */
     974static 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 */
     994static IFCONDRET ifcond_op_logical_not(PIFCOND pThis)
     995{
     996    PIFCONDVAR pVar = &pThis->aVars[pThis->iVar];
     997    assert(pThis->iVar >= 0);
     998
    718999    ifcond_var_assign_bool(pVar, !ifcond_var_make_bool(pVar));
    7191000
     
    7221003
    7231004
    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 */
     1011static IFCONDRET ifcond_op_multiply(PIFCOND pThis)
     1012{
     1013    IFCONDRET   rc = kIfCondRet_Ok;
    7351014    PIFCONDVAR  pVar1 = &pThis->aVars[pThis->iVar - 1];
    7361015    PIFCONDVAR  pVar2 = &pThis->aVars[pThis->iVar];
    7371016    assert(pThis->iVar >= 1);
    7381017
     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 */
     1038static 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 */
     1065static 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 */
     1092static 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 */
     1118static 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 */
     1143static 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 */
     1169static 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 */
     1195static 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 */
     1222static 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 */
     1249static 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 */
     1276static 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 */
     1303static 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
    7391310    /*
    740      * If it's the same type, things are simple.
     1311     * The same type?
    7411312     */
    7421313    if (ifcond_var_is_string(pVar1) == ifcond_var_is_string(pVar2))
    7431314    {
    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
    7451319        {
     1320            /* try a normal string compare. */
    7461321            ifcond_var_make_simple_string(pVar1);
    7471322            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);
    7491332        }
    750         else
    751             ifcond_var_assign_bool(pVar1, pVar1->uVal.i == pVar2->uVal.i);
    7521333    }
    7531334    else
     
    7571338         *  1. Convert the string to a valid number and compare the numbers.
    7581339         *  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.
    7611341         */
    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);
    7751345        else
    7761346        {
    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;
    7891349        }
    7901350    }
     
    8181378static IFCONDRET ifcond_op_bitwise_and(PIFCOND pThis)
    8191379{
    820     IFCONDRET rc;
     1380    PIFCONDVAR  pVar1 = &pThis->aVars[pThis->iVar - 1];
     1381    PIFCONDVAR  pVar2 = &pThis->aVars[pThis->iVar];
     1382    IFCONDRET   rc;
    8211383    assert(pThis->iVar >= 1);
    8221384
    823     rc = ifcond_var_make_num(pThis, &pThis->aVars[pThis->iVar - 1]);
     1385    rc = ifcond_var_make_num(pThis, pVar1);
    8241386    if (rc >= kIfCondRet_Ok)
    8251387    {
    826         rc = ifcond_var_make_num(pThis, &pThis->aVars[pThis->iVar]);
     1388        rc = ifcond_var_make_num(pThis, pVar2);
    8271389        if (rc >= kIfCondRet_Ok)
    828             pThis->aVars[pThis->iVar - 1].uVal.i &= pThis->aVars[pThis->iVar].uVal.i;
     1390            pVar1->uVal.i &= pVar2->uVal.i;
    8291391    }
    8301392
     
    8421404static IFCONDRET ifcond_op_bitwise_xor(PIFCOND pThis)
    8431405{
    844     IFCONDRET rc;
     1406    PIFCONDVAR  pVar1 = &pThis->aVars[pThis->iVar - 1];
     1407    PIFCONDVAR  pVar2 = &pThis->aVars[pThis->iVar];
     1408    IFCONDRET   rc;
    8451409    assert(pThis->iVar >= 1);
    8461410
    847     rc = ifcond_var_make_num(pThis, &pThis->aVars[pThis->iVar - 1]);
     1411    rc = ifcond_var_make_num(pThis, pVar1);
    8481412    if (rc >= kIfCondRet_Ok)
    8491413    {
    850         rc = ifcond_var_make_num(pThis, &pThis->aVars[pThis->iVar]);
     1414        rc = ifcond_var_make_num(pThis, pVar2);
    8511415        if (rc >= kIfCondRet_Ok)
    852             pThis->aVars[pThis->iVar - 1].uVal.i ^= pThis->aVars[pThis->iVar].uVal.i;
     1416            pVar1->uVal.i ^= pVar2->uVal.i;
    8531417    }
    8541418
     
    8661430static IFCONDRET ifcond_op_bitwise_or(PIFCOND pThis)
    8671431{
    868     IFCONDRET rc;
     1432    PIFCONDVAR  pVar1 = &pThis->aVars[pThis->iVar - 1];
     1433    PIFCONDVAR  pVar2 = &pThis->aVars[pThis->iVar];
     1434    IFCONDRET   rc;
    8691435    assert(pThis->iVar >= 1);
    8701436
    871     rc = ifcond_var_make_num(pThis, &pThis->aVars[pThis->iVar - 1]);
     1437    rc = ifcond_var_make_num(pThis, pVar1);
    8721438    if (rc >= kIfCondRet_Ok)
    8731439    {
    874         rc = ifcond_var_make_num(pThis, &pThis->aVars[pThis->iVar]);
     1440        rc = ifcond_var_make_num(pThis, pVar2);
    8751441        if (rc >= kIfCondRet_Ok)
    876             pThis->aVars[pThis->iVar - 1].uVal.i |= pThis->aVars[pThis->iVar].uVal.i;
     1442            pVar1->uVal.i |= pVar2->uVal.i;
    8771443    }
    8781444
     
    8901456static IFCONDRET ifcond_op_logical_and(PIFCOND pThis)
    8911457{
     1458    PIFCONDVAR  pVar1 = &pThis->aVars[pThis->iVar - 1];
     1459    PIFCONDVAR  pVar2 = &pThis->aVars[pThis->iVar];
    8921460    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);
    8961465    else
    897         ifcond_var_assign_bool(&pThis->aVars[pThis->iVar - 1], 0);
     1466        ifcond_var_assign_bool(pVar1, 0);
    8981467
    8991468    ifcond_pop_and_delete_var(pThis);
     
    9101479static IFCONDRET ifcond_op_logical_or(PIFCOND pThis)
    9111480{
     1481    PIFCONDVAR  pVar1 = &pThis->aVars[pThis->iVar - 1];
     1482    PIFCONDVAR  pVar2 = &pThis->aVars[pThis->iVar];
    9121483    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);
    9161488    else
    917         ifcond_var_assign_bool(&pThis->aVars[pThis->iVar - 1], 0);
     1489        ifcond_var_assign_bool(pVar1, 0);
    9181490
    9191491    ifcond_pop_and_delete_var(pThis);
     
    9801552#define IFCOND_OP(szOp, iPrecedence, cArgs, pfn)  {  szOp, sizeof(szOp) - 1, '\0', iPrecedence, cArgs, pfn }
    9811553    /*        Name, iPrecedence,  cArgs,    pfn    */
    982 #if 0
    9831554    IFCOND_OP("defined",     90,      1,    ifcond_op_defined),
     1555    IFCOND_OP("target",      90,      1,    ifcond_op_target),
    9841556    IFCOND_OP("+",           80,      1,    ifcond_op_pluss),
    9851557    IFCOND_OP("-",           80,      1,    ifcond_op_minus),
     
    9871559    IFCOND_OP("*",           75,      2,    ifcond_op_multiply),
    9881560    IFCOND_OP("/",           75,      2,    ifcond_op_divide),
    989     IFCOND_OP("%",           75,      2,    ifcond_op_mod),
     1561    IFCOND_OP("%",           75,      2,    ifcond_op_modulus),
    9901562    IFCOND_OP("+",           70,      2,    ifcond_op_add),
    9911563    IFCOND_OP("-",           70,      2,    ifcond_op_sub),
     
    9961568    IFCOND_OP(">=",          60,      2,    ifcond_op_greater_or_equal_than),
    9971569    IFCOND_OP(">",           60,      2,    ifcond_op_greater_than),
    998 #endif
    9991570    IFCOND_OP("==",          55,      2,    ifcond_op_equal),
    10001571    IFCOND_OP("!=",          55,      2,    ifcond_op_not_equal),
     
    12651836            while (*psz && *psz != '"')
    12661837                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);
    12681839        }
    12691840        else if (*psz == '\'')
     
    12721843            while (*psz && *psz != '\'')
    12731844                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);
    12751846        }
    12761847        else
  • trunk/src/kmk/testcase-ifcond.kmk

    r1720 r1722  
    2525#
    2626
     27
    2728#DEPTH = ../..
    2829#include $(PATH_KBUILD)/header.kmk
     
    6263endif
    6364
    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 
     65if 0 || 0 || 0 || 0 || 0 || 0 || 0
     66$(error )
     67else
     68$(warning works)
     69endif
     70
     71if 0 || 0 || 0 || 1 || 0 || 0 || 0
    7172$(warning works)
    7273else
     
    101102$(error )
    102103endif
     104
     105
     106#
     107# Equal and Not Equal.
     108#
     109if 1 == 1
     110$(warning works)
     111else
     112$(error )
     113endif
     114
     115if 2 == 3
     116$(error )
     117else
     118$(warning works)
     119endif
     120
     121if 2 != 3
     122$(warning works)
     123else
     124$(error )
     125endif
     126
     127
     128#
     129# XOR
     130#
     131if 1 ^ 1
     132$(error )
     133else
     134$(warning works)
     135endif
     136
     137if 2 ^ 1 == 3
     138$(warning works)
     139else
     140$(error )
     141endif
     142
     143if 7 == 2 ^ 1 ^ 4
     144$(warning works)
     145else
     146$(error )
     147endif
     148
     149
     150#
     151# Logical NOT
     152#
     153if !1
     154$(error )
     155else
     156$(warning works)
     157endif
     158
     159if !42 == 0
     160$(warning works)
     161else
     162$(error )
     163endif
     164
     165if !0 == 1
     166$(warning works)
     167else
     168$(error )
     169endif
     170
     171if !!0 == 0
     172$(warning works)
     173else
     174$(error )
     175endif
     176
     177
     178#
     179# Greater than
     180#
     181if 1 > 0
     182$(warning works)
     183else
     184$(error )
     185endif
     186
     187if 1024 > 1023
     188$(warning works)
     189else
     190$(error )
     191endif
     192
     193if 999 > 1023
     194$(error )
     195else
     196$(warning works)
     197endif
     198
     199
     200#
     201# Greater or equal than
     202#
     203if 20 > 0
     204$(warning works)
     205else
     206$(error )
     207endif
     208
     209if 20 >= 20
     210$(warning works)
     211else
     212$(error )
     213endif
     214
     215if 19 >= 20
     216$(error )
     217else
     218$(warning works)
     219endif
     220
     221
     222#
     223# target()
     224#
     225trg_deps_only: foobar
     226trg_with_cmds: foobar
     227        echo $@
     228
     229if target trg_with_cmds
     230$(warning works)
     231else
     232$(error works)
     233endif
     234
     235if target trg_deps_only
     236$(error works)
     237else
     238$(warning works)
     239endif
     240
     241if target foobar
     242$(error works)
     243else
     244$(warning works)
     245endif
     246
     247
     248#
     249# defined()
     250#
     251var_defined := 1
     252var_not_defined :=
     253
     254if defined var_defined
     255$(warning works)
     256else
     257$(error works)
     258endif
     259
     260if defined(var_defined)
     261$(warning works)
     262else
     263$(error works)
     264endif
     265
     266if defined (var_defined)
     267$(warning works)
     268else
     269$(error works)
     270endif
     271
     272if defined (var_not_defined)
     273$(error works)
     274else
     275$(warning works)
     276endif
     277
    103278
    104279
Note: See TracChangeset for help on using the changeset viewer.

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