Patch 8.0.1511 (after 8.0.1505)
Problem: Some code for the debugger watch expression is clumsy.
Solution: Clean up the code.
Files: src/ex_cmds2.c, src/eval.c, src/proto/eval.pro
*** ../vim-8.0.1510/src/ex_cmds2.c 2018-02-12 22:07:45.593058158 +0100
--- src/ex_cmds2.c 2018-02-13 12:44:35.560861213 +0100
***************
*** 988,1010 ****
}
else
{
! typval_T val3;
!
! if (typval_copy(bp->dbg_val, &val3) == OK)
{
! if (typval_compare(tv, &val3, TYPE_EQUAL,
! TRUE, FALSE, TRUE) == OK
! && tv->vval.v_number == FALSE)
! {
! typval_T *v;
! line = TRUE;
! debug_oldval = typval_tostring(bp->dbg_val);
! v = eval_expr(bp->dbg_name, NULL);
! debug_newval = typval_tostring(v);
! free_tv(bp->dbg_val);
! bp->dbg_val = v;
! }
}
free_tv(tv);
}
--- 988,1007 ----
}
else
{
! if (typval_compare(tv, bp->dbg_val, TYPE_EQUAL,
! TRUE, FALSE) == OK
! && tv->vval.v_number == FALSE)
{
! typval_T *v;
! line = TRUE;
! debug_oldval = typval_tostring(bp->dbg_val);
! /* Need to evaluate again, typval_compare() overwrites
! * "tv". */
! v = eval_expr(bp->dbg_name, NULL);
! debug_newval = typval_tostring(v);
! free_tv(bp->dbg_val);
! bp->dbg_val = v;
}
free_tv(tv);
}
*** ../vim-8.0.1510/src/eval.c 2018-02-13 12:26:08.904247750 +0100
--- src/eval.c 2018-02-13 12:44:47.396760236 +0100
***************
*** 3596,3602 ****
clear_tv(rettv);
return FAIL;
}
! return typval_compare(rettv, &var2, type, type_is, ic, evaluate);
}
return OK;
--- 3596,3608 ----
clear_tv(rettv);
return FAIL;
}
! if (evaluate)
! {
! int ret = typval_compare(rettv, &var2, type, type_is, ic);
!
! clear_tv(&var2);
! return ret;
! }
}
return OK;
***************
*** 9091,9317 ****
}
}
!
int
typval_compare(
typval_T *typ1, /* first operand */
typval_T *typ2, /* second operand */
exptype_T type, /* operator */
int type_is, /* TRUE for "is" and "isnot" */
! int ic, /* ignore case */
! int evaluate)
{
int i;
varnumber_T n1, n2;
char_u *s1, *s2;
char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
! if (evaluate)
{
! if (type_is && typ1->v_type != typ2->v_type)
{
! /* For "is" a different type always means FALSE, for "notis"
! * it means TRUE. */
! n1 = (type == TYPE_NEQUAL);
}
! else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST)
{
! if (type_is)
! {
! n1 = (typ1->v_type == typ2->v_type
! && typ1->vval.v_list == typ2->vval.v_list);
! if (type == TYPE_NEQUAL)
! n1 = !n1;
! }
! else if (typ1->v_type != typ2->v_type
! || (type != TYPE_EQUAL && type != TYPE_NEQUAL))
! {
! if (typ1->v_type != typ2->v_type)
! EMSG(_("E691: Can only compare List with List"));
! else
! EMSG(_("E692: Invalid operation for List"));
! clear_tv(typ1);
! clear_tv(typ2);
! return FAIL;
! }
else
! {
! /* Compare two Lists for being equal or unequal. */
! n1 = list_equal(typ1->vval.v_list, typ2->vval.v_list,
! ic, FALSE);
! if (type == TYPE_NEQUAL)
! n1 = !n1;
! }
}
!
! else if (typ1->v_type == VAR_DICT || typ2->v_type == VAR_DICT)
{
! if (type_is)
! {
! n1 = (typ1->v_type == typ2->v_type
! && typ1->vval.v_dict == typ2->vval.v_dict);
! if (type == TYPE_NEQUAL)
! n1 = !n1;
! }
! else if (typ1->v_type != typ2->v_type
! || (type != TYPE_EQUAL && type != TYPE_NEQUAL))
! {
! if (typ1->v_type != typ2->v_type)
! EMSG(_("E735: Can only compare Dictionary with
Dictionary"));
! else
! EMSG(_("E736: Invalid operation for Dictionary"));
! clear_tv(typ1);
! clear_tv(typ2);
! return FAIL;
! }
! else
! {
! /* Compare two Dictionaries for being equal or unequal. */
! n1 = dict_equal(typ1->vval.v_dict, typ2->vval.v_dict,
! ic, FALSE);
! if (type == TYPE_NEQUAL)
! n1 = !n1;
! }
}
! else if (typ1->v_type == VAR_FUNC || typ2->v_type == VAR_FUNC
! || typ1->v_type == VAR_PARTIAL || typ2->v_type == VAR_PARTIAL)
{
! if (type != TYPE_EQUAL && type != TYPE_NEQUAL)
! {
! EMSG(_("E694: Invalid operation for Funcrefs"));
! clear_tv(typ1);
! clear_tv(typ2);
! return FAIL;
! }
! if ((typ1->v_type == VAR_PARTIAL
! && typ1->vval.v_partial == NULL)
! || (typ2->v_type == VAR_PARTIAL
! && typ2->vval.v_partial == NULL))
! /* when a partial is NULL assume not equal */
! n1 = FALSE;
! else if (type_is)
! {
! if (typ1->v_type == VAR_FUNC && typ2->v_type == VAR_FUNC)
! /* strings are considered the same if their value is
! * the same */
! n1 = tv_equal(typ1, typ2, ic, FALSE);
! else if (typ1->v_type == VAR_PARTIAL
! && typ2->v_type == VAR_PARTIAL)
! n1 = (typ1->vval.v_partial == typ2->vval.v_partial);
! else
! n1 = FALSE;
! }
! else
! n1 = tv_equal(typ1, typ2, ic, FALSE);
if (type == TYPE_NEQUAL)
n1 = !n1;
}
!
! #ifdef FEAT_FLOAT
! /*
! * If one of the two variables is a float, compare as a float.
! * When using "=~" or "!~", always compare as string.
! */
! else if ((typ1->v_type == VAR_FLOAT || typ2->v_type == VAR_FLOAT)
! && type != TYPE_MATCH && type != TYPE_NOMATCH)
{
! float_T f1, f2;
!
! if (typ1->v_type == VAR_FLOAT)
! f1 = typ1->vval.v_float;
! else
! f1 = get_tv_number(typ1);
! if (typ2->v_type == VAR_FLOAT)
! f2 = typ2->vval.v_float;
else
! f2 = get_tv_number(typ2);
! n1 = FALSE;
! switch (type)
! {
! case TYPE_EQUAL: n1 = (f1 == f2); break;
! case TYPE_NEQUAL: n1 = (f1 != f2); break;
! case TYPE_GREATER: n1 = (f1 > f2); break;
! case TYPE_GEQUAL: n1 = (f1 >= f2); break;
! case TYPE_SMALLER: n1 = (f1 < f2); break;
! case TYPE_SEQUAL: n1 = (f1 <= f2); break;
! case TYPE_UNKNOWN:
! case TYPE_MATCH:
! case TYPE_NOMATCH: break; /* avoid gcc warning */
! }
}
! #endif
! /*
! * If one of the two variables is a number, compare as a number.
! * When using "=~" or "!~", always compare as string.
! */
! else if ((typ1->v_type == VAR_NUMBER || typ2->v_type == VAR_NUMBER)
! && type != TYPE_MATCH && type != TYPE_NOMATCH)
! {
! n1 = get_tv_number(typ1);
! n2 = get_tv_number(typ2);
! switch (type)
! {
! case TYPE_EQUAL: n1 = (n1 == n2); break;
! case TYPE_NEQUAL: n1 = (n1 != n2); break;
! case TYPE_GREATER: n1 = (n1 > n2); break;
! case TYPE_GEQUAL: n1 = (n1 >= n2); break;
! case TYPE_SMALLER: n1 = (n1 < n2); break;
! case TYPE_SEQUAL: n1 = (n1 <= n2); break;
! case TYPE_UNKNOWN:
! case TYPE_MATCH:
! case TYPE_NOMATCH: break; /* avoid gcc warning */
! }
}
! else
{
! s1 = get_tv_string_buf(typ1, buf1);
! s2 = get_tv_string_buf(typ2, buf2);
! if (type != TYPE_MATCH && type != TYPE_NOMATCH)
! i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2);
else
! i = 0;
! n1 = FALSE;
! switch (type)
! {
! case TYPE_EQUAL: n1 = (i == 0); break;
! case TYPE_NEQUAL: n1 = (i != 0); break;
! case TYPE_GREATER: n1 = (i > 0); break;
! case TYPE_GEQUAL: n1 = (i >= 0); break;
! case TYPE_SMALLER: n1 = (i < 0); break;
! case TYPE_SEQUAL: n1 = (i <= 0); break;
!
! case TYPE_MATCH:
! case TYPE_NOMATCH:
! n1 = pattern_match(s2, s1, ic);
! if (type == TYPE_NOMATCH)
! n1 = !n1;
! break;
!
! case TYPE_UNKNOWN: break; /* avoid gcc warning */
! }
! }
! clear_tv(typ1);
! clear_tv(typ2);
! typ1->v_type = VAR_NUMBER;
! typ1->vval.v_number = n1;
}
- return OK;
- }
! int
! typval_copy(typ1, typ2)
! typval_T *typ1;
! typval_T *typ2;
! {
! if (typ2 == NULL)
! rettv_list_alloc(typ2);
! if (typ1 != NULL && typ2 != NULL)
! return item_copy(typ1, typ2, TRUE, 0);
! return FAIL;
}
char_u *
--- 9097,9304 ----
}
}
! /*
! * Compare "typ1" and "typ2". Put the result in "typ1".
! */
int
typval_compare(
typval_T *typ1, /* first operand */
typval_T *typ2, /* second operand */
exptype_T type, /* operator */
int type_is, /* TRUE for "is" and "isnot" */
! int ic) /* ignore case */
{
int i;
varnumber_T n1, n2;
char_u *s1, *s2;
char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
! if (type_is && typ1->v_type != typ2->v_type)
{
! /* For "is" a different type always means FALSE, for "notis"
! * it means TRUE. */
! n1 = (type == TYPE_NEQUAL);
! }
! else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST)
! {
! if (type_is)
{
! n1 = (typ1->v_type == typ2->v_type
! && typ1->vval.v_list == typ2->vval.v_list);
! if (type == TYPE_NEQUAL)
! n1 = !n1;
}
! else if (typ1->v_type != typ2->v_type
! || (type != TYPE_EQUAL && type != TYPE_NEQUAL))
{
! if (typ1->v_type != typ2->v_type)
! EMSG(_("E691: Can only compare List with List"));
else
! EMSG(_("E692: Invalid operation for List"));
! clear_tv(typ1);
! return FAIL;
}
! else
{
! /* Compare two Lists for being equal or unequal. */
! n1 = list_equal(typ1->vval.v_list, typ2->vval.v_list,
! ic, FALSE);
! if (type == TYPE_NEQUAL)
! n1 = !n1;
}
+ }
! else if (typ1->v_type == VAR_DICT || typ2->v_type == VAR_DICT)
! {
! if (type_is)
{
! n1 = (typ1->v_type == typ2->v_type
! && typ1->vval.v_dict == typ2->vval.v_dict);
if (type == TYPE_NEQUAL)
n1 = !n1;
}
! else if (typ1->v_type != typ2->v_type
! || (type != TYPE_EQUAL && type != TYPE_NEQUAL))
{
! if (typ1->v_type != typ2->v_type)
! EMSG(_("E735: Can only compare Dictionary with Dictionary"));
else
! EMSG(_("E736: Invalid operation for Dictionary"));
! clear_tv(typ1);
! return FAIL;
}
! else
! {
! /* Compare two Dictionaries for being equal or unequal. */
! n1 = dict_equal(typ1->vval.v_dict, typ2->vval.v_dict,
! ic, FALSE);
! if (type == TYPE_NEQUAL)
! n1 = !n1;
! }
! }
! else if (typ1->v_type == VAR_FUNC || typ2->v_type == VAR_FUNC
! || typ1->v_type == VAR_PARTIAL || typ2->v_type == VAR_PARTIAL)
! {
! if (type != TYPE_EQUAL && type != TYPE_NEQUAL)
! {
! EMSG(_("E694: Invalid operation for Funcrefs"));
! clear_tv(typ1);
! return FAIL;
}
! if ((typ1->v_type == VAR_PARTIAL
! && typ1->vval.v_partial == NULL)
! || (typ2->v_type == VAR_PARTIAL
! && typ2->vval.v_partial == NULL))
! /* when a partial is NULL assume not equal */
! n1 = FALSE;
! else if (type_is)
{
! if (typ1->v_type == VAR_FUNC && typ2->v_type == VAR_FUNC)
! /* strings are considered the same if their value is
! * the same */
! n1 = tv_equal(typ1, typ2, ic, FALSE);
! else if (typ1->v_type == VAR_PARTIAL
! && typ2->v_type == VAR_PARTIAL)
! n1 = (typ1->vval.v_partial == typ2->vval.v_partial);
else
! n1 = FALSE;
! }
! else
! n1 = tv_equal(typ1, typ2, ic, FALSE);
! if (type == TYPE_NEQUAL)
! n1 = !n1;
}
! #ifdef FEAT_FLOAT
! /*
! * If one of the two variables is a float, compare as a float.
! * When using "=~" or "!~", always compare as string.
! */
! else if ((typ1->v_type == VAR_FLOAT || typ2->v_type == VAR_FLOAT)
! && type != TYPE_MATCH && type != TYPE_NOMATCH)
! {
! float_T f1, f2;
! if (typ1->v_type == VAR_FLOAT)
! f1 = typ1->vval.v_float;
! else
! f1 = get_tv_number(typ1);
! if (typ2->v_type == VAR_FLOAT)
! f2 = typ2->vval.v_float;
! else
! f2 = get_tv_number(typ2);
! n1 = FALSE;
! switch (type)
! {
! case TYPE_EQUAL: n1 = (f1 == f2); break;
! case TYPE_NEQUAL: n1 = (f1 != f2); break;
! case TYPE_GREATER: n1 = (f1 > f2); break;
! case TYPE_GEQUAL: n1 = (f1 >= f2); break;
! case TYPE_SMALLER: n1 = (f1 < f2); break;
! case TYPE_SEQUAL: n1 = (f1 <= f2); break;
! case TYPE_UNKNOWN:
! case TYPE_MATCH:
! case TYPE_NOMATCH: break; /* avoid gcc warning */
! }
! }
! #endif
! /*
! * If one of the two variables is a number, compare as a number.
! * When using "=~" or "!~", always compare as string.
! */
! else if ((typ1->v_type == VAR_NUMBER || typ2->v_type == VAR_NUMBER)
! && type != TYPE_MATCH && type != TYPE_NOMATCH)
! {
! n1 = get_tv_number(typ1);
! n2 = get_tv_number(typ2);
! switch (type)
! {
! case TYPE_EQUAL: n1 = (n1 == n2); break;
! case TYPE_NEQUAL: n1 = (n1 != n2); break;
! case TYPE_GREATER: n1 = (n1 > n2); break;
! case TYPE_GEQUAL: n1 = (n1 >= n2); break;
! case TYPE_SMALLER: n1 = (n1 < n2); break;
! case TYPE_SEQUAL: n1 = (n1 <= n2); break;
! case TYPE_UNKNOWN:
! case TYPE_MATCH:
! case TYPE_NOMATCH: break; /* avoid gcc warning */
! }
! }
! else
! {
! s1 = get_tv_string_buf(typ1, buf1);
! s2 = get_tv_string_buf(typ2, buf2);
! if (type != TYPE_MATCH && type != TYPE_NOMATCH)
! i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2);
! else
! i = 0;
! n1 = FALSE;
! switch (type)
! {
! case TYPE_EQUAL: n1 = (i == 0); break;
! case TYPE_NEQUAL: n1 = (i != 0); break;
! case TYPE_GREATER: n1 = (i > 0); break;
! case TYPE_GEQUAL: n1 = (i >= 0); break;
! case TYPE_SMALLER: n1 = (i < 0); break;
! case TYPE_SEQUAL: n1 = (i <= 0); break;
!
! case TYPE_MATCH:
! case TYPE_NOMATCH:
! n1 = pattern_match(s2, s1, ic);
! if (type == TYPE_NOMATCH)
! n1 = !n1;
! break;
!
! case TYPE_UNKNOWN: break; /* avoid gcc warning */
! }
! }
! clear_tv(typ1);
! typ1->v_type = VAR_NUMBER;
! typ1->vval.v_number = n1;
!
! return OK;
}
char_u *
*** ../vim-8.0.1510/src/proto/eval.pro 2018-02-13 12:26:08.904247750 +0100
--- src/proto/eval.pro 2018-02-13 12:45:37.008343019 +0100
***************
*** 130,137 ****
void assert_beeps(typval_T *argvars);
void assert_fails(typval_T *argvars);
void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, char_u *exp_str,
typval_T *exp_tv, typval_T *got_tv, assert_type_T atype);
! int typval_compare(typval_T *typ1, typval_T *typ2, exptype_T type, int
type_is, int ic, int evaluate);
! int typval_copy(typval_T *typ1, typval_T *typ2);
char_u *typval_tostring(typval_T *arg);
int var_exists(char_u *var);
int modify_fname(char_u *src, int *usedlen, char_u **fnamep, char_u **bufp,
int *fnamelen);
--- 130,136 ----
void assert_beeps(typval_T *argvars);
void assert_fails(typval_T *argvars);
void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, char_u *exp_str,
typval_T *exp_tv, typval_T *got_tv, assert_type_T atype);
! int typval_compare(typval_T *typ1, typval_T *typ2, exptype_T type, int
type_is, int ic);
char_u *typval_tostring(typval_T *arg);
int var_exists(char_u *var);
int modify_fname(char_u *src, int *usedlen, char_u **fnamep, char_u **bufp,
int *fnamelen);
*** ../vim-8.0.1510/src/version.c 2018-02-13 12:26:08.908247730 +0100
--- src/version.c 2018-02-13 12:45:48.416248398 +0100
***************
*** 773,774 ****
--- 773,776 ----
{ /* Add new patch number below this line */
+ /**/
+ 1511,
/**/
--
ARTHUR: A scratch? Your arm's off!
BLACK KNIGHT: No, it isn't.
ARTHUR: Well, what's that then?
BLACK KNIGHT: I've had worse.
The Quest for the Holy Grail (Monty Python)
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.