While working on the Float printing function, I also noted an odd Vim
behaviour: it won't let you assign a Float to a variable that was
previously a Number, and vice-versa. Or for that matter, it won't let
you change the type of a variable at all with an assignment.

The trouble is in the set_var() function. Consider the following patch
(it is applied to my patched Vim, so line numbers will be ridiculously
different to the original, probably, but should apply cleanly and can be
found manually by :tag set_var):

diff -r 64942db7407d src/eval.c
--- a/src/eval.c        Sat Jun 21 23:24:54 2008 +1000
+++ b/src/eval.c        Mon Jun 23 13:35:03 2008 +1000
@@ -19306,9 +19306,11 @@
            return;
        if (v->di_tv.v_type != tv->v_type
                && !((v->di_tv.v_type == VAR_STRING
-                       || v->di_tv.v_type == VAR_NUMBER)
+                       || v->di_tv.v_type == VAR_NUMBER
+                       || v->di_tv.v_type == VAR_FLOAT)
                    && (tv->v_type == VAR_STRING
-                       || tv->v_type == VAR_NUMBER)))
+                       || tv->v_type == VAR_NUMBER
+                       || tv->v_type == VAR_FLOAT)))
        {
            EMSG2(_("E706: Variable type mismatch for: %s"), name);
            return;
@@ -19372,7 +19374,7 @@
        v->di_flags = 0;
      }

-    if (copy || tv->v_type == VAR_NUMBER)
+    if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT)
        copy_tv(tv, &v->di_tv);
      else
      {

The first hunk patches the variable type mismatch check so that it
allows floats to be included as allowed type changes.

However, why is this check there? I don't see any reason changing a
variable type to or from a list, dictionary or function reference would
cause any problems either. References are correctly updated by a call to
clear_tv shortly after the check, and tv and v->tv could not reference
the same variable and include a change in type, so there is no chance of
freeing a structure that is about to be used. Couldn't the check be
safely removed and thus enable variables to be freely assigned values of
new types?

The second hunk seems to be purely an optimisation, avoiding an
unnecessary call to init_tv in the else part. It applies equally to
Floats as Numbers, I think.

I will leave you to consider it, Bram. As I'm not all that familiar with
the codebase, I may have missed something, but I think I've checked it
out thoroughly enough.

Ben.




--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

diff -r 64942db7407d src/eval.c
--- a/src/eval.c	Sat Jun 21 23:24:54 2008 +1000
+++ b/src/eval.c	Mon Jun 23 13:35:03 2008 +1000
@@ -19306,9 +19306,11 @@
 	    return;
 	if (v->di_tv.v_type != tv->v_type
 		&& !((v->di_tv.v_type == VAR_STRING
-			|| v->di_tv.v_type == VAR_NUMBER)
+			|| v->di_tv.v_type == VAR_NUMBER
+			|| v->di_tv.v_type == VAR_FLOAT)
 		    && (tv->v_type == VAR_STRING
-			|| tv->v_type == VAR_NUMBER)))
+			|| tv->v_type == VAR_NUMBER
+			|| tv->v_type == VAR_FLOAT)))
 	{
 	    EMSG2(_("E706: Variable type mismatch for: %s"), name);
 	    return;
@@ -19372,7 +19374,7 @@
 	v->di_flags = 0;
     }
 
-    if (copy || tv->v_type == VAR_NUMBER)
+    if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT)
 	copy_tv(tv, &v->di_tv);
     else
     {

Raspunde prin e-mail lui