diff src/message.c @ 9389:32e34e574716 v7.4.1976

commit https://github.com/vim/vim/commit/22fcfad29276bd5f317faf516637dcd491b96a12 Author: Bram Moolenaar <Bram@vim.org> Date: Fri Jul 1 18:17:26 2016 +0200 patch 7.4.1976 Problem: Number variables are not 64 bits while they could be. Solution: Add the num64 feature. (Ken Takata)
author Christian Brabandt <cb@256bit.org>
date Fri, 01 Jul 2016 18:30:07 +0200
parents 70d3337ff173
children f048e5a27253
line wrap: on
line diff
--- a/src/message.c
+++ b/src/message.c
@@ -3846,7 +3846,7 @@ do_browse(
 #if defined(FEAT_EVAL)
 static char *e_printf = N_("E766: Insufficient arguments for printf()");
 
-static long tv_nr(typval_T *tvs, int *idxp);
+static varnumber_T tv_nr(typval_T *tvs, int *idxp);
 static char *tv_str(typval_T *tvs, int *idxp);
 # ifdef FEAT_FLOAT
 static double tv_float(typval_T *tvs, int *idxp);
@@ -3855,11 +3855,11 @@ static double tv_float(typval_T *tvs, in
 /*
  * Get number argument from "idxp" entry in "tvs".  First entry is 1.
  */
-    static long
+    static varnumber_T
 tv_nr(typval_T *tvs, int *idxp)
 {
     int		idx = *idxp - 1;
-    long	n = 0;
+    varnumber_T	n = 0;
     int		err = FALSE;
 
     if (tvs[idx].v_type == VAR_UNKNOWN)
@@ -3912,7 +3912,7 @@ tv_float(typval_T *tvs, int *idxp)
 	if (tvs[idx].v_type == VAR_FLOAT)
 	    f = tvs[idx].vval.v_float;
 	else if (tvs[idx].v_type == VAR_NUMBER)
-	    f = tvs[idx].vval.v_number;
+	    f = (double)tvs[idx].vval.v_number;
 	else
 	    EMSG(_("E807: Expected Float argument for printf()"));
     }
@@ -4170,7 +4170,11 @@ vim_vsnprintf(
 		if (length_modifier == 'l' && *p == 'l')
 		{
 		    /* double l = long long */
+# ifdef FEAT_NUM64
+		    length_modifier = 'L';
+# else
 		    length_modifier = 'l';	/* treat it as a single 'l' */
+# endif
 		    p++;
 		}
 	    }
@@ -4299,6 +4303,12 @@ vim_vsnprintf(
 		    long int long_arg = 0;
 		    unsigned long int ulong_arg = 0;
 
+# ifdef FEAT_NUM64
+		    /* only defined for length modifier ll */
+		    varnumber_T llong_arg = 0;
+		    uvarnumber_T ullong_arg = 0;
+# endif
+
 		    /* pointer argument value -only defined for p
 		     * conversion */
 		    void *ptr_arg = NULL;
@@ -4343,6 +4353,19 @@ vim_vsnprintf(
 			    else if (long_arg < 0)
 				arg_sign = -1;
 			    break;
+# ifdef FEAT_NUM64
+			case 'L':
+			    llong_arg =
+#  if defined(FEAT_EVAL)
+					tvs != NULL ? tv_nr(tvs, &arg_idx) :
+#  endif
+					    va_arg(ap, varnumber_T);
+			    if (llong_arg > 0)
+				arg_sign =  1;
+			    else if (llong_arg < 0)
+				arg_sign = -1;
+			    break;
+# endif
 			}
 		    }
 		    else
@@ -4371,6 +4394,18 @@ vim_vsnprintf(
 				if (ulong_arg != 0)
 				    arg_sign = 1;
 				break;
+# ifdef FEAT_NUM64
+			    case 'L':
+				ullong_arg =
+#  if defined(FEAT_EVAL)
+					    tvs != NULL ? (uvarnumber_T)
+							tv_nr(tvs, &arg_idx) :
+#  endif
+						va_arg(ap, uvarnumber_T);
+				if (ullong_arg != 0)
+				    arg_sign = 1;
+				break;
+# endif
 			}
 		    }
 
@@ -4415,17 +4450,27 @@ vim_vsnprintf(
 		    }
 		    else
 		    {
-			char	f[5];
+			char	f[6];
 			int	f_l = 0;
 
 			/* construct a simple format string for sprintf */
 			f[f_l++] = '%';
 			if (!length_modifier)
 			    ;
-			else if (length_modifier == '2')
+			else if (length_modifier == 'L')
 			{
+# ifdef FEAT_NUM64
+#  ifdef WIN3264
+			    f[f_l++] = 'I';
+			    f[f_l++] = '6';
+			    f[f_l++] = '4';
+#  else
 			    f[f_l++] = 'l';
 			    f[f_l++] = 'l';
+#  endif
+# else
+			    f[f_l++] = 'l';
+# endif
 			}
 			else
 			    f[f_l++] = length_modifier;
@@ -4446,6 +4491,11 @@ vim_vsnprintf(
 			    case 'l': str_arg_l += sprintf(
 						tmp + str_arg_l, f, long_arg);
 				      break;
+# ifdef FEAT_NUM64
+			    case 'L': str_arg_l += sprintf(
+					       tmp + str_arg_l, f, llong_arg);
+				      break;
+# endif
 			    }
 			}
 			else
@@ -4460,6 +4510,11 @@ vim_vsnprintf(
 			    case 'l': str_arg_l += sprintf(
 					       tmp + str_arg_l, f, ulong_arg);
 				      break;
+# ifdef FEAT_NUM64
+			    case 'L': str_arg_l += sprintf(
+					      tmp + str_arg_l, f, ullong_arg);
+				      break;
+# endif
 			    }
 			}