comparison src/eval.c @ 18966:6bd715870e32 v8.2.0044

patch 8.2.0044: expression type is used inconsistently Commit: https://github.com/vim/vim/commit/07a3db89b8953bd0964895badb3b662f7514bc10 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Dec 25 18:14:14 2019 +0100 patch 8.2.0044: expression type is used inconsistently Problem: Expression type is used inconsistently. Solution: Add "ETYPE_IS" and "ETYPE_ISNOT" as separate enum values. Rename "TYPE_" to "ETYPE_" to avoid confusion.
author Bram Moolenaar <Bram@vim.org>
date Wed, 25 Dec 2019 18:15:04 +0100
parents 25ebc35e104f
children 24941a950cc7
comparison
equal deleted inserted replaced
18965:0eb2333df312 18966:6bd715870e32
1995 eval4(char_u **arg, typval_T *rettv, int evaluate) 1995 eval4(char_u **arg, typval_T *rettv, int evaluate)
1996 { 1996 {
1997 typval_T var2; 1997 typval_T var2;
1998 char_u *p; 1998 char_u *p;
1999 int i; 1999 int i;
2000 exptype_T type = TYPE_UNKNOWN; 2000 exptype_T type = ETYPE_UNKNOWN;
2001 int type_is = FALSE; // TRUE for "is" and "isnot"
2002 int len = 2; 2001 int len = 2;
2003 int ic; 2002 int ic;
2004 2003
2005 /* 2004 /*
2006 * Get the first variable. 2005 * Get the first variable.
2010 2009
2011 p = *arg; 2010 p = *arg;
2012 switch (p[0]) 2011 switch (p[0])
2013 { 2012 {
2014 case '=': if (p[1] == '=') 2013 case '=': if (p[1] == '=')
2015 type = TYPE_EQUAL; 2014 type = ETYPE_EQUAL;
2016 else if (p[1] == '~') 2015 else if (p[1] == '~')
2017 type = TYPE_MATCH; 2016 type = ETYPE_MATCH;
2018 break; 2017 break;
2019 case '!': if (p[1] == '=') 2018 case '!': if (p[1] == '=')
2020 type = TYPE_NEQUAL; 2019 type = ETYPE_NEQUAL;
2021 else if (p[1] == '~') 2020 else if (p[1] == '~')
2022 type = TYPE_NOMATCH; 2021 type = ETYPE_NOMATCH;
2023 break; 2022 break;
2024 case '>': if (p[1] != '=') 2023 case '>': if (p[1] != '=')
2025 { 2024 {
2026 type = TYPE_GREATER; 2025 type = ETYPE_GREATER;
2027 len = 1; 2026 len = 1;
2028 } 2027 }
2029 else 2028 else
2030 type = TYPE_GEQUAL; 2029 type = ETYPE_GEQUAL;
2031 break; 2030 break;
2032 case '<': if (p[1] != '=') 2031 case '<': if (p[1] != '=')
2033 { 2032 {
2034 type = TYPE_SMALLER; 2033 type = ETYPE_SMALLER;
2035 len = 1; 2034 len = 1;
2036 } 2035 }
2037 else 2036 else
2038 type = TYPE_SEQUAL; 2037 type = ETYPE_SEQUAL;
2039 break; 2038 break;
2040 case 'i': if (p[1] == 's') 2039 case 'i': if (p[1] == 's')
2041 { 2040 {
2042 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 2041 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't')
2043 len = 5; 2042 len = 5;
2044 i = p[len]; 2043 i = p[len];
2045 if (!isalnum(i) && i != '_') 2044 if (!isalnum(i) && i != '_')
2046 { 2045 type = len == 2 ? ETYPE_IS : ETYPE_ISNOT;
2047 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL;
2048 type_is = TRUE;
2049 }
2050 } 2046 }
2051 break; 2047 break;
2052 } 2048 }
2053 2049
2054 /* 2050 /*
2055 * If there is a comparative operator, use it. 2051 * If there is a comparative operator, use it.
2056 */ 2052 */
2057 if (type != TYPE_UNKNOWN) 2053 if (type != ETYPE_UNKNOWN)
2058 { 2054 {
2059 // extra question mark appended: ignore case 2055 // extra question mark appended: ignore case
2060 if (p[len] == '?') 2056 if (p[len] == '?')
2061 { 2057 {
2062 ic = TRUE; 2058 ic = TRUE;
2081 clear_tv(rettv); 2077 clear_tv(rettv);
2082 return FAIL; 2078 return FAIL;
2083 } 2079 }
2084 if (evaluate) 2080 if (evaluate)
2085 { 2081 {
2086 int ret = typval_compare(rettv, &var2, type, type_is, ic); 2082 int ret = typval_compare(rettv, &var2, type, ic);
2087 2083
2088 clear_tv(&var2); 2084 clear_tv(&var2);
2089 return ret; 2085 return ret;
2090 } 2086 }
2091 } 2087 }
6161 int 6157 int
6162 typval_compare( 6158 typval_compare(
6163 typval_T *typ1, // first operand 6159 typval_T *typ1, // first operand
6164 typval_T *typ2, // second operand 6160 typval_T *typ2, // second operand
6165 exptype_T type, // operator 6161 exptype_T type, // operator
6166 int type_is, // TRUE for "is" and "isnot"
6167 int ic) // ignore case 6162 int ic) // ignore case
6168 { 6163 {
6169 int i; 6164 int i;
6170 varnumber_T n1, n2; 6165 varnumber_T n1, n2;
6171 char_u *s1, *s2; 6166 char_u *s1, *s2;
6172 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 6167 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
6168 int type_is = type == ETYPE_IS || type == ETYPE_ISNOT;
6173 6169
6174 if (type_is && typ1->v_type != typ2->v_type) 6170 if (type_is && typ1->v_type != typ2->v_type)
6175 { 6171 {
6176 // For "is" a different type always means FALSE, for "notis" 6172 // For "is" a different type always means FALSE, for "notis"
6177 // it means TRUE. 6173 // it means TRUE.
6178 n1 = (type == TYPE_NEQUAL); 6174 n1 = (type == ETYPE_ISNOT);
6179 } 6175 }
6180 else if (typ1->v_type == VAR_BLOB || typ2->v_type == VAR_BLOB) 6176 else if (typ1->v_type == VAR_BLOB || typ2->v_type == VAR_BLOB)
6181 { 6177 {
6182 if (type_is) 6178 if (type_is)
6183 { 6179 {
6184 n1 = (typ1->v_type == typ2->v_type 6180 n1 = (typ1->v_type == typ2->v_type
6185 && typ1->vval.v_blob == typ2->vval.v_blob); 6181 && typ1->vval.v_blob == typ2->vval.v_blob);
6186 if (type == TYPE_NEQUAL) 6182 if (type == ETYPE_ISNOT)
6187 n1 = !n1; 6183 n1 = !n1;
6188 } 6184 }
6189 else if (typ1->v_type != typ2->v_type 6185 else if (typ1->v_type != typ2->v_type
6190 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 6186 || (type != ETYPE_EQUAL && type != ETYPE_NEQUAL))
6191 { 6187 {
6192 if (typ1->v_type != typ2->v_type) 6188 if (typ1->v_type != typ2->v_type)
6193 emsg(_("E977: Can only compare Blob with Blob")); 6189 emsg(_("E977: Can only compare Blob with Blob"));
6194 else 6190 else
6195 emsg(_(e_invalblob)); 6191 emsg(_(e_invalblob));
6198 } 6194 }
6199 else 6195 else
6200 { 6196 {
6201 // Compare two Blobs for being equal or unequal. 6197 // Compare two Blobs for being equal or unequal.
6202 n1 = blob_equal(typ1->vval.v_blob, typ2->vval.v_blob); 6198 n1 = blob_equal(typ1->vval.v_blob, typ2->vval.v_blob);
6203 if (type == TYPE_NEQUAL) 6199 if (type == ETYPE_NEQUAL)
6204 n1 = !n1; 6200 n1 = !n1;
6205 } 6201 }
6206 } 6202 }
6207 else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST) 6203 else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST)
6208 { 6204 {
6209 if (type_is) 6205 if (type_is)
6210 { 6206 {
6211 n1 = (typ1->v_type == typ2->v_type 6207 n1 = (typ1->v_type == typ2->v_type
6212 && typ1->vval.v_list == typ2->vval.v_list); 6208 && typ1->vval.v_list == typ2->vval.v_list);
6213 if (type == TYPE_NEQUAL) 6209 if (type == ETYPE_ISNOT)
6214 n1 = !n1; 6210 n1 = !n1;
6215 } 6211 }
6216 else if (typ1->v_type != typ2->v_type 6212 else if (typ1->v_type != typ2->v_type
6217 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 6213 || (type != ETYPE_EQUAL && type != ETYPE_NEQUAL))
6218 { 6214 {
6219 if (typ1->v_type != typ2->v_type) 6215 if (typ1->v_type != typ2->v_type)
6220 emsg(_("E691: Can only compare List with List")); 6216 emsg(_("E691: Can only compare List with List"));
6221 else 6217 else
6222 emsg(_("E692: Invalid operation for List")); 6218 emsg(_("E692: Invalid operation for List"));
6226 else 6222 else
6227 { 6223 {
6228 // Compare two Lists for being equal or unequal. 6224 // Compare two Lists for being equal or unequal.
6229 n1 = list_equal(typ1->vval.v_list, typ2->vval.v_list, 6225 n1 = list_equal(typ1->vval.v_list, typ2->vval.v_list,
6230 ic, FALSE); 6226 ic, FALSE);
6231 if (type == TYPE_NEQUAL) 6227 if (type == ETYPE_NEQUAL)
6232 n1 = !n1; 6228 n1 = !n1;
6233 } 6229 }
6234 } 6230 }
6235 6231
6236 else if (typ1->v_type == VAR_DICT || typ2->v_type == VAR_DICT) 6232 else if (typ1->v_type == VAR_DICT || typ2->v_type == VAR_DICT)
6237 { 6233 {
6238 if (type_is) 6234 if (type_is)
6239 { 6235 {
6240 n1 = (typ1->v_type == typ2->v_type 6236 n1 = (typ1->v_type == typ2->v_type
6241 && typ1->vval.v_dict == typ2->vval.v_dict); 6237 && typ1->vval.v_dict == typ2->vval.v_dict);
6242 if (type == TYPE_NEQUAL) 6238 if (type == ETYPE_ISNOT)
6243 n1 = !n1; 6239 n1 = !n1;
6244 } 6240 }
6245 else if (typ1->v_type != typ2->v_type 6241 else if (typ1->v_type != typ2->v_type
6246 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 6242 || (type != ETYPE_EQUAL && type != ETYPE_NEQUAL))
6247 { 6243 {
6248 if (typ1->v_type != typ2->v_type) 6244 if (typ1->v_type != typ2->v_type)
6249 emsg(_("E735: Can only compare Dictionary with Dictionary")); 6245 emsg(_("E735: Can only compare Dictionary with Dictionary"));
6250 else 6246 else
6251 emsg(_("E736: Invalid operation for Dictionary")); 6247 emsg(_("E736: Invalid operation for Dictionary"));
6255 else 6251 else
6256 { 6252 {
6257 // Compare two Dictionaries for being equal or unequal. 6253 // Compare two Dictionaries for being equal or unequal.
6258 n1 = dict_equal(typ1->vval.v_dict, typ2->vval.v_dict, 6254 n1 = dict_equal(typ1->vval.v_dict, typ2->vval.v_dict,
6259 ic, FALSE); 6255 ic, FALSE);
6260 if (type == TYPE_NEQUAL) 6256 if (type == ETYPE_NEQUAL)
6261 n1 = !n1; 6257 n1 = !n1;
6262 } 6258 }
6263 } 6259 }
6264 6260
6265 else if (typ1->v_type == VAR_FUNC || typ2->v_type == VAR_FUNC 6261 else if (typ1->v_type == VAR_FUNC || typ2->v_type == VAR_FUNC
6266 || typ1->v_type == VAR_PARTIAL || typ2->v_type == VAR_PARTIAL) 6262 || typ1->v_type == VAR_PARTIAL || typ2->v_type == VAR_PARTIAL)
6267 { 6263 {
6268 if (type != TYPE_EQUAL && type != TYPE_NEQUAL) 6264 if (type != ETYPE_EQUAL && type != ETYPE_NEQUAL)
6269 { 6265 {
6270 emsg(_("E694: Invalid operation for Funcrefs")); 6266 emsg(_("E694: Invalid operation for Funcrefs"));
6271 clear_tv(typ1); 6267 clear_tv(typ1);
6272 return FAIL; 6268 return FAIL;
6273 } 6269 }
6289 else 6285 else
6290 n1 = FALSE; 6286 n1 = FALSE;
6291 } 6287 }
6292 else 6288 else
6293 n1 = tv_equal(typ1, typ2, ic, FALSE); 6289 n1 = tv_equal(typ1, typ2, ic, FALSE);
6294 if (type == TYPE_NEQUAL) 6290 if (type == ETYPE_NEQUAL || type == ETYPE_ISNOT)
6295 n1 = !n1; 6291 n1 = !n1;
6296 } 6292 }
6297 6293
6298 #ifdef FEAT_FLOAT 6294 #ifdef FEAT_FLOAT
6299 /* 6295 /*
6300 * If one of the two variables is a float, compare as a float. 6296 * If one of the two variables is a float, compare as a float.
6301 * When using "=~" or "!~", always compare as string. 6297 * When using "=~" or "!~", always compare as string.
6302 */ 6298 */
6303 else if ((typ1->v_type == VAR_FLOAT || typ2->v_type == VAR_FLOAT) 6299 else if ((typ1->v_type == VAR_FLOAT || typ2->v_type == VAR_FLOAT)
6304 && type != TYPE_MATCH && type != TYPE_NOMATCH) 6300 && type != ETYPE_MATCH && type != ETYPE_NOMATCH)
6305 { 6301 {
6306 float_T f1, f2; 6302 float_T f1, f2;
6307 6303
6308 f1 = tv_get_float(typ1); 6304 f1 = tv_get_float(typ1);
6309 f2 = tv_get_float(typ2); 6305 f2 = tv_get_float(typ2);
6310 n1 = FALSE; 6306 n1 = FALSE;
6311 switch (type) 6307 switch (type)
6312 { 6308 {
6313 case TYPE_EQUAL: n1 = (f1 == f2); break; 6309 case ETYPE_EQUAL: n1 = (f1 == f2); break;
6314 case TYPE_NEQUAL: n1 = (f1 != f2); break; 6310 case ETYPE_NEQUAL: n1 = (f1 != f2); break;
6315 case TYPE_GREATER: n1 = (f1 > f2); break; 6311 case ETYPE_GREATER: n1 = (f1 > f2); break;
6316 case TYPE_GEQUAL: n1 = (f1 >= f2); break; 6312 case ETYPE_GEQUAL: n1 = (f1 >= f2); break;
6317 case TYPE_SMALLER: n1 = (f1 < f2); break; 6313 case ETYPE_SMALLER: n1 = (f1 < f2); break;
6318 case TYPE_SEQUAL: n1 = (f1 <= f2); break; 6314 case ETYPE_SEQUAL: n1 = (f1 <= f2); break;
6319 case TYPE_UNKNOWN: 6315 case ETYPE_UNKNOWN:
6320 case TYPE_MATCH: 6316 case ETYPE_IS:
6321 case TYPE_NOMATCH: break; // avoid gcc warning 6317 case ETYPE_ISNOT:
6318 case ETYPE_MATCH:
6319 case ETYPE_NOMATCH: break; // avoid gcc warning
6322 } 6320 }
6323 } 6321 }
6324 #endif 6322 #endif
6325 6323
6326 /* 6324 /*
6327 * If one of the two variables is a number, compare as a number. 6325 * If one of the two variables is a number, compare as a number.
6328 * When using "=~" or "!~", always compare as string. 6326 * When using "=~" or "!~", always compare as string.
6329 */ 6327 */
6330 else if ((typ1->v_type == VAR_NUMBER || typ2->v_type == VAR_NUMBER) 6328 else if ((typ1->v_type == VAR_NUMBER || typ2->v_type == VAR_NUMBER)
6331 && type != TYPE_MATCH && type != TYPE_NOMATCH) 6329 && type != ETYPE_MATCH && type != ETYPE_NOMATCH)
6332 { 6330 {
6333 n1 = tv_get_number(typ1); 6331 n1 = tv_get_number(typ1);
6334 n2 = tv_get_number(typ2); 6332 n2 = tv_get_number(typ2);
6335 switch (type) 6333 switch (type)
6336 { 6334 {
6337 case TYPE_EQUAL: n1 = (n1 == n2); break; 6335 case ETYPE_EQUAL: n1 = (n1 == n2); break;
6338 case TYPE_NEQUAL: n1 = (n1 != n2); break; 6336 case ETYPE_NEQUAL: n1 = (n1 != n2); break;
6339 case TYPE_GREATER: n1 = (n1 > n2); break; 6337 case ETYPE_GREATER: n1 = (n1 > n2); break;
6340 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 6338 case ETYPE_GEQUAL: n1 = (n1 >= n2); break;
6341 case TYPE_SMALLER: n1 = (n1 < n2); break; 6339 case ETYPE_SMALLER: n1 = (n1 < n2); break;
6342 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 6340 case ETYPE_SEQUAL: n1 = (n1 <= n2); break;
6343 case TYPE_UNKNOWN: 6341 case ETYPE_UNKNOWN:
6344 case TYPE_MATCH: 6342 case ETYPE_IS:
6345 case TYPE_NOMATCH: break; // avoid gcc warning 6343 case ETYPE_ISNOT:
6344 case ETYPE_MATCH:
6345 case ETYPE_NOMATCH: break; // avoid gcc warning
6346 } 6346 }
6347 } 6347 }
6348 else 6348 else
6349 { 6349 {
6350 s1 = tv_get_string_buf(typ1, buf1); 6350 s1 = tv_get_string_buf(typ1, buf1);
6351 s2 = tv_get_string_buf(typ2, buf2); 6351 s2 = tv_get_string_buf(typ2, buf2);
6352 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 6352 if (type != ETYPE_MATCH && type != ETYPE_NOMATCH)
6353 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 6353 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2);
6354 else 6354 else
6355 i = 0; 6355 i = 0;
6356 n1 = FALSE; 6356 n1 = FALSE;
6357 switch (type) 6357 switch (type)
6358 { 6358 {
6359 case TYPE_EQUAL: n1 = (i == 0); break; 6359 case ETYPE_EQUAL: n1 = (i == 0); break;
6360 case TYPE_NEQUAL: n1 = (i != 0); break; 6360 case ETYPE_NEQUAL: n1 = (i != 0); break;
6361 case TYPE_GREATER: n1 = (i > 0); break; 6361 case ETYPE_GREATER: n1 = (i > 0); break;
6362 case TYPE_GEQUAL: n1 = (i >= 0); break; 6362 case ETYPE_GEQUAL: n1 = (i >= 0); break;
6363 case TYPE_SMALLER: n1 = (i < 0); break; 6363 case ETYPE_SMALLER: n1 = (i < 0); break;
6364 case TYPE_SEQUAL: n1 = (i <= 0); break; 6364 case ETYPE_SEQUAL: n1 = (i <= 0); break;
6365 6365
6366 case TYPE_MATCH: 6366 case ETYPE_MATCH:
6367 case TYPE_NOMATCH: 6367 case ETYPE_NOMATCH:
6368 n1 = pattern_match(s2, s1, ic); 6368 n1 = pattern_match(s2, s1, ic);
6369 if (type == TYPE_NOMATCH) 6369 if (type == ETYPE_NOMATCH)
6370 n1 = !n1; 6370 n1 = !n1;
6371 break; 6371 break;
6372 6372
6373 case TYPE_UNKNOWN: break; // avoid gcc warning 6373 case ETYPE_IS:
6374 case ETYPE_ISNOT:
6375 case ETYPE_UNKNOWN: break; // avoid gcc warning
6374 } 6376 }
6375 } 6377 }
6376 clear_tv(typ1); 6378 clear_tv(typ1);
6377 typ1->v_type = VAR_NUMBER; 6379 typ1->v_type = VAR_NUMBER;
6378 typ1->vval.v_number = n1; 6380 typ1->vval.v_number = n1;