patch 9.1.0462: eval5() and eval7 are too complex

Commit: 
https://github.com/vim/vim/commit/734286e4c626f80ace27eeb252a5e384e798aebf
Author: Yegappan Lakshmanan <yegap...@yahoo.com>
Date:   Mon Jun 3 18:52:22 2024 +0200

    patch 9.1.0462: eval5() and eval7 are too complex
    
    Problem:  eval5() and eval7 are too complex
    Solution: Refactor eval5() and eval7() in eval.c
              (Yegappan Lakshmanan)
    
    closes: #14900
    
    Signed-off-by: Yegappan Lakshmanan <yegap...@yahoo.com>
    Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/eval.c b/src/eval.c
index 4a039792c..7848feaa8 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -3946,6 +3946,40 @@ eval_addlist(typval_T *tv1, typval_T *tv2)
     return OK;
 }
 
+/*
+ * Left or right shift the number "tv1" by the number "tv2" and store the
+ * result in "tv1".
+ *
+ * Return OK or FAIL.
+ */
+    static int
+eval_shift_number(typval_T *tv1, typval_T *tv2, int shift_type)
+{
+    if (tv2->v_type != VAR_NUMBER || tv2->vval.v_number < 0)
+    {
+       // right operand should be a positive number
+       if (tv2->v_type != VAR_NUMBER)
+           emsg(_(e_bitshift_ops_must_be_number));
+       else
+           emsg(_(e_bitshift_ops_must_be_positive));
+       clear_tv(tv1);
+       clear_tv(tv2);
+       return FAIL;
+    }
+
+    if (tv2->vval.v_number > MAX_LSHIFT_BITS)
+       // shifting more bits than we have always results in zero
+       tv1->vval.v_number = 0;
+    else if (shift_type == EXPR_LSHIFT)
+       tv1->vval.v_number =
+           (uvarnumber_T)tv1->vval.v_number << tv2->vval.v_number;
+    else
+       tv1->vval.v_number =
+           (uvarnumber_T)tv1->vval.v_number >> tv2->vval.v_number;
+
+    return OK;
+}
+
 /*
  * Handle the bitwise left/right shift operator expression:
  *     var1 << var2
@@ -3972,16 +4006,16 @@ eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
     {
        char_u          *p;
        int             getnext;
-       exprtype_T      type;
+       exprtype_T      exprtype;
        int             evaluate;
        typval_T        var2;
        int             vim9script;
 
        p = eval_next_non_blank(*arg, evalarg, &getnext);
        if (p[0] == '<' && p[1] == '<')
-           type = EXPR_LSHIFT;
+           exprtype = EXPR_LSHIFT;
        else if (p[0] == '>' && p[1] == '>')
-           type = EXPR_RSHIFT;
+           exprtype = EXPR_RSHIFT;
        else
            return OK;
 
@@ -4026,27 +4060,8 @@ eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
 
        if (evaluate)
        {
-           if (var2.v_type != VAR_NUMBER || var2.vval.v_number < 0)
-           {
-               // right operand should be a positive number
-               if (var2.v_type != VAR_NUMBER)
-                   emsg(_(e_bitshift_ops_must_be_number));
-               else
-                   emsg(_(e_bitshift_ops_must_be_positive));
-               clear_tv(rettv);
-               clear_tv(&var2);
+           if (eval_shift_number(rettv, &var2, exprtype) == FAIL)
                return FAIL;
-           }
-
-           if (var2.vval.v_number > MAX_LSHIFT_BITS)
-               // shifting more bits than we have always results in zero
-               rettv->vval.v_number = 0;
-           else if (type == EXPR_LSHIFT)
-               rettv->vval.v_number =
-                     (uvarnumber_T)rettv->vval.v_number << var2.vval.v_number;
-           else
-               rettv->vval.v_number =
-                     (uvarnumber_T)rettv->vval.v_number >> var2.vval.v_number;
        }
 
        clear_tv(&var2);
@@ -4100,7 +4115,7 @@ eval_concat_str(typval_T *tv1, typval_T *tv2)
  * The numbers can be whole numbers or floats.
  */
     static int
-eval_addsub_num(typval_T *tv1, typval_T *tv2, int op)
+eval_addsub_number(typval_T *tv1, typval_T *tv2, int op)
 {
     int                error = FALSE;
     varnumber_T        n1, n2;
@@ -4290,7 +4305,7 @@ eval6(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
            }
            else
            {
-               if (eval_addsub_num(rettv, &var2, op) == FAIL)
+               if (eval_addsub_number(rettv, &var2, op) == FAIL)
                    return FAIL;
            }
            clear_tv(&var2);
@@ -4299,6 +4314,113 @@ eval6(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
     return OK;
 }
 
+/*
+ * Multiply or divide or compute the modulo of numbers "tv1" and "tv2" and
+ * store the result in "tv1".  The numbers can be whole numbers or floats.
+ */
+    static int
+eval_multdiv_number(typval_T *tv1, typval_T *tv2, int op)
+{
+    varnumber_T        n1, n2;
+    float_T    f1, f2;
+    int                error;
+    int                use_float = FALSE;
+
+    f1 = 0;
+    f2 = 0;
+    error = FALSE;
+    if (tv1->v_type == VAR_FLOAT)
+    {
+       f1 = tv1->vval.v_float;
+       use_float = TRUE;
+       n1 = 0;
+    }
+    else
+       n1 = tv_get_number_chk(tv1, &error);
+    clear_tv(tv1);
+    if (error)
+    {
+       clear_tv(tv2);
+       return FAIL;
+    }
+
+    if (tv2->v_type == VAR_FLOAT)
+    {
+       if (!use_float)
+       {
+           f1 = n1;
+           use_float = TRUE;
+       }
+       f2 = tv2->vval.v_float;
+       n2 = 0;
+    }
+    else
+    {
+       n2 = tv_get_number_chk(tv2, &error);
+       clear_tv(tv2);
+       if (error)
+           return FAIL;
+       if (use_float)
+           f2 = n2;
+    }
+
+    /*
+     * Compute the result.
+     * When either side is a float the result is a float.
+     */
+    if (use_float)
+    {
+       if (op == '*')
+           f1 = f1 * f2;
+       else if (op == '/')
+       {
+#ifdef VMS
+           // VMS crashes on divide by zero, work around it
+           if (f2 == 0.0)
+           {
+               if (f1 == 0)
+                   f1 = -1 * __F_FLT_MAX - 1L;   // similar to NaN
+               else if (f1 < 0)
+                   f1 = -1 * __F_FLT_MAX;
+               else
+                   f1 = __F_FLT_MAX;
+           }
+           else
+               f1 = f1 / f2;
+#else
+           // We rely on the floating point library to handle divide
+           // by zero to result in "inf" and not a crash.
+           f1 = f1 / f2;
+#endif
+       }
+       else
+       {
+           emsg(_(e_cannot_use_percent_with_float));
+           return FAIL;
+       }
+       tv1->v_type = VAR_FLOAT;
+       tv1->vval.v_float = f1;
+    }
+    else
+    {
+       int         failed = FALSE;
+
+       if (op == '*')
+           n1 = n1 * n2;
+       else if (op == '/')
+           n1 = num_divide(n1, n2, &failed);
+       else
+           n1 = num_modulus(n1, n2, &failed);
+       if (failed)
+           return FAIL;
+
+       tv1->v_type = VAR_NUMBER;
+       tv1->vval.v_number = n1;
+    }
+
+    return OK;
+}
+
 /*
  * Handle sixth level expression:
  *     *       number multiplication
@@ -4317,8 +4439,6 @@ eval7(
     evalarg_T  *evalarg,
     int                want_string)  // after "." operator
 {
-    int            use_float = FALSE;
-
     /*
      * Get the first expression.
      */
@@ -4335,9 +4455,6 @@ eval7(
        typval_T    var2;
        char_u      *p;
        int         op;
-       varnumber_T n1, n2;
-       float_T     f1, f2;
-       int         error;
 
        // "*=", "/=" and "%=" are assignments
        p = eval_next_non_blank(*arg, evalarg, &getnext);
@@ -4359,26 +4476,6 @@ eval7(
            *arg = p;
        }
 
-       f1 = 0;
-       f2 = 0;
-       error = FALSE;
-       if (evaluate)
-       {
-           if (rettv->v_type == VAR_FLOAT)
-           {
-               f1 = rettv->vval.v_float;
-               use_float = TRUE;
-               n1 = 0;
-           }
-           else
-               n1 = tv_get_number_chk(rettv, &error);
-           clear_tv(rettv);
-           if (error)
-               return FAIL;
-       }
-       else
-           n1 = 0;
-
        /*
         * Get the second variable.
         */
@@ -4393,81 +4490,9 @@ eval7(
            return FAIL;
 
        if (evaluate)
-       {
-           if (var2.v_type == VAR_FLOAT)
-           {
-               if (!use_float)
-               {
-                   f1 = n1;
-                   use_float = TRUE;
-               }
-               f2 = var2.vval.v_float;
-               n2 = 0;
-           }
-           else
-           {
-               n2 = tv_get_number_chk(&var2, &error);
-               clear_tv(&var2);
-               if (error)
-                   return FAIL;
-               if (use_float)
-                   f2 = n2;
-           }
-
-           /*
-            * Compute the result.
-            * When either side is a float the result is a float.
-            */
-           if (use_float)
-           {
-               if (op == '*')
-                   f1 = f1 * f2;
-               else if (op == '/')
-               {
-#ifdef VMS
-                   // VMS crashes on divide by zero, work around it
-                   if (f2 == 0.0)
-                   {
-                       if (f1 == 0)
-                           f1 = -1 * __F_FLT_MAX - 1L;   // similar to NaN
-                       else if (f1 < 0)
-                           f1 = -1 * __F_FLT_MAX;
-                       else
-                           f1 = __F_FLT_MAX;
-                   }
-                   else
-                       f1 = f1 / f2;
-#else
-                   // We rely on the floating point library to handle divide
-                   // by zero to result in "inf" and not a crash.
-                   f1 = f1 / f2;
-#endif
-               }
-               else
-               {
-                   emsg(_(e_cannot_use_percent_with_float));
-                   return FAIL;
-               }
-               rettv->v_type = VAR_FLOAT;
-               rettv->vval.v_float = f1;
-           }
-           else
-           {
-               int         failed = FALSE;
-
-               if (op == '*')
-                   n1 = n1 * n2;
-               else if (op == '/')
-                   n1 = num_divide(n1, n2, &failed);
-               else
-                   n1 = num_modulus(n1, n2, &failed);
-               if (failed)
-                   return FAIL;
-
-               rettv->v_type = VAR_NUMBER;
-               rettv->vval.v_number = n1;
-           }
-       }
+           // Compute the result.
+           if (eval_multdiv_number(rettv, &var2, op) == FAIL)
+               return FAIL;
     }
 
     return OK;
diff --git a/src/scriptfile.c b/src/scriptfile.c
index 6a6a037e3..711f576c0 100644
--- a/src/scriptfile.c
+++ b/src/scriptfile.c
@@ -439,8 +439,8 @@ check_script_symlink(int sid)
                SCRIPT_ITEM(real_sid)->sn_import_autoload
                                                    = si->sn_import_autoload;
                if (si->sn_autoload_prefix != NULL)
-                       SCRIPT_ITEM(real_sid)->sn_autoload_prefix =
-                               vim_strsave(si->sn_autoload_prefix);
+                   SCRIPT_ITEM(real_sid)->sn_autoload_prefix =
+                                       vim_strsave(si->sn_autoload_prefix);
            }
        }
     }
diff --git a/src/version.c b/src/version.c
index 13010a386..55282ab82 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    462,
 /**/
     461,
 /**/

-- 
-- 
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 vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1sEBH0-0081DT-Ay%40256bit.org.

Raspunde prin e-mail lui