On 08/04/08 23:57, Mikolaj Machowski wrote:
[...]
> Couldn't apply:
>
> [EMAIL PROTECTED] ~/vim7 $ patch -p0 --dry-run< float.diff
> patch: **** malformed patch at line 5: *E712*
>
> GNU patch 2.5.9
>
> Any ideas? TIA
>
> m.
The patch was sent "inline", and I (and maybe you) received it in
quoted-printable format. I tried to fix it (see attachment): does it work?
Best regards,
Tony.
--
"When the going gets tough, the tough get empirical"
-- Jon Carroll
--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---
*** ../vim-7.1.291/runtime/doc/eval.txt Wed Feb 20 20:09:44 2008
--- runtime/doc/eval.txt Tue Apr 8 22:19:37 2008
***************
*** 39,49 ****
*E712*
There are five types of variables:
! Number A 32 bit signed number.
Examples: -123 0x10 0177
String A NUL terminated string of 8-bit unsigned characters (bytes).
! Examples: "ab\txx\"--" 'x-z''a,c'
Funcref A reference to a function |Funcref|.
Example: function("strlen")
--- 39,53 ----
*E712*
There are five types of variables:
! Number A 32 bit signed number. |expr-number|
Examples: -123 0x10 0177
+ Float A floating point number. |floating-point-format|
+ {only when compiled with the |+float| feature}
+ Examples: 123.456 1.15e-6 -1.1e3
+
String A NUL terminated string of 8-bit unsigned characters (bytes).
! |expr-string| Examples: "ab\txx\"--" 'x-z''a,c'
Funcref A reference to a function |Funcref|.
Example: function("strlen")
***************
*** 92,97 ****
--- 96,105 ----
< *E745* *E728* *E703* *E729* *E730* *E731*
List, Dictionary and Funcref types are not automatically converted.
+ *E805* *E806*
+ When mixing Number and Float the Number is converted to Float. Otherwise
+ there is no automatic conversion of Float.
+
*E706*
You will get an error if you try to change the type of a variable. You need
to |:unlet| it first to avoid this error. String and Number are considered
***************
*** 258,270 ****
< 0
Thus comparing Lists is more strict than comparing numbers and strings. You
! can compare simple values this way too by putting them in a string: >
:let a = 5
:let b = "5"
! echo a == b
< 1 >
! echo [a] == [b]
< 0
--- 266,278 ----
< 0
Thus comparing Lists is more strict than comparing numbers and strings. You
! can compare simple values this way too by putting them in a list: >
:let a = 5
:let b = "5"
! :echo a == b
< 1 >
! :echo [a] == [b]
< 0
***************
*** 797,802 ****
--- 805,812 ----
None of these work for |Funcref|s.
+ . and % do not work for Float. *E804*
+
expr7 *expr7*
-----
***************
*** 909,914 ****
--- 919,945 ----
Decimal, Hexadecimal (starting with 0x or 0X), or Octal (starting with 0).
+ *floating-point-format*
+ Floating point numbers can be written in two forms:
+ - &N.M, where N and M are numbers. The .M can be omitted. The N cannot be
+ omitted. There can be a minus sign in the N. Examples:
+ &123.456
+ &0.0001
+ &55
+ &-0.123
+ Only a decimal point is accepted, not a comma. No matter what the current
+ locale is.
+ - Same, with a following exponent in the form "eX", where X is a decimal
+ number with an optional minus sign. The 'e' can also be upper case.
+ Examples:
+ &1.234e3
+ &1E-6
+ &-3.1416e88
+ The precision and range of floating points numbers depends on the library Vim
+ was compiled with. There is no way to change this at runtime.
+ {only when compiled with the |+float| feature}
+
+
string *expr-string* *E114*
------
***************
*** 2024,2030 ****
< The current 'encoding' is used. Example for "utf-8": >
char2nr("á") returns 225
char2nr("á"[0]) returns 195
! < nr2char() does the opposite.
cindent({lnum}) *cindent()*
Get the amount of indent for line {lnum} according the C
--- 2058,2064 ----
< The current 'encoding' is used. Example for "utf-8": >
char2nr("á") returns 225
char2nr("á"[0]) returns 195
! < |nr2char()| does the opposite.
cindent({lnum}) *cindent()*
Get the amount of indent for line {lnum} according the C
***************
*** 3893,3898 ****
--- 3928,3936 ----
%04x hex number padded with zeros to at least 4 characters
%X hex number using upper case letters
%o octal number
+ %f floating point number in the form 123.456
+ %e floating point number in the form 1.234e3
+ %E floating pointer number in the form 1.234E3
%% the % character itself
Conversion specifications start with '%' and end with the
***************
*** 3951,3956 ****
--- 3989,3996 ----
This gives the minimum number of digits to appear for
d, o, x, and X conversions, or the maximum number of
bytes to be printed from a string for s conversions.
+ For floating point it is the number of digits after
+ the decimal point.
type
A character that specifies the type of conversion to
***************
*** 3968,3973 ****
--- 4008,4014 ----
The conversion specifiers and their meanings are:
+ *printf-d* *printf-o* *printf-x* *printf-X*
doxX The Number argument is converted to signed decimal
(d), unsigned octal (o), or unsigned hexadecimal (x
and X) notation. The letters "abcdef" are used for
***************
*** 3982,3994 ****
--- 4023,4052 ----
a conversion is wider than the field width, the field
is expanded to contain the conversion result.
+ *printf-c*
c The Number argument is converted to a byte, and the
resulting character is written.
+ *printf-s*
s The text of the String argument is used. If a
precision is specified, no more bytes than the number
specified are used.
+ *printf-f* *E807*
+ f The Float argument is converted into a string of the
+ form 123.456. Currently doesn't do any padding. The
+ precision specifies the number of digits after the
+ decimal point. When the precision is zero the decimal
+ point is omitted. When the precision is not specified
+ 6 is used.
+
+ *printf-e* *printf-E*
+ e E The Float argument is converted into a string of the
+ form 1.234e3 or 1.234E3 (when using 'E'). The
+ precision specifies the number of digits after the
+ decimal point, like with 'f'.
+
+ *printf-%*
% A '%' is written. No argument is converted. The
complete conversion specification is "%%".
***************
*** 4781,4786 ****
--- 4841,4859 ----
Text after the number is silently ignored.
+ str2float( {expr}) *str2float()*
+ Convert string {expr} to a Float. This works the same as when
+ using a floating point number directly, see
+ |floating-point-format|, but without the leading '&'.
+ A comma is also accepted for a decimal point.
+ Text after the number is silently ignored.
+ A second comma or decimal point also ends the number:
+ "12,345.67" is converted to 12.345. You can strip out
+ thousands separators with |substitute()|: >
+ let f = str2float(substitute(text, ',', '', 'g'))
+ < {only when compiled with the |+float| feature}
+
+
strftime({format} [, {time}]) *strftime()*
The result is a String, which is a formatted date and time, as
specified by the {format} string. The given {time} is used,
***************
*** 5142,5147 ****
--- 5215,5221 ----
Funcref: 2
List: 3
Dictionary: 4
+ Float: 5
To avoid the magic numbers it should be used this way: >
:if type(myvar) == type(0)
:if type(myvar) == type("")
***************
*** 5200,5205 ****
--- 5274,5281 ----
< This enters the same Visual mode as before. It is also useful
in scripts if you wish to act differently depending on the
Visual mode that was used.
+ If Visual mode is active, use |mode()| to get the Visual mode
+ (e.g., in a |:vmap|).
If an expression is supplied that results in a non-zero number
or a non-empty string, then the Visual mode will be cleared
*** ../vim-7.1.291/src/auto/configure Wed Feb 20 12:43:05 2008
--- src/auto/configure Tue Apr 8 22:37:05 2008
***************
*** 10311,10319 ****
for ac_header in stdarg.h stdlib.h string.h sys/select.h sys/utsname.h \
termcap.h fcntl.h sgtty.h sys/ioctl.h sys/time.h sys/types.h termio.h \
! iconv.h langinfo.h unistd.h stropts.h errno.h \
sys/resource.h sys/systeminfo.h locale.h \
sys/stream.h sys/ptem.h termios.h libc.h sys/statfs.h \
poll.h sys/poll.h pwd.h utime.h sys/param.h libintl.h \
--- 10311,10320 ----
+
for ac_header in stdarg.h stdlib.h string.h sys/select.h sys/utsname.h \
termcap.h fcntl.h sgtty.h sys/ioctl.h sys/time.h sys/types.h termio.h \
! iconv.h langinfo.h math.h unistd.h stropts.h errno.h \
sys/resource.h sys/systeminfo.h locale.h \
sys/stream.h sys/ptem.h termios.h libc.h sys/statfs.h \
poll.h sys/poll.h pwd.h utime.h sys/param.h libintl.h \
***************
*** 13083,13088 ****
--- 13084,13221 ----
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
+
+ echo "$as_me:$LINENO: checking for pow in -lm" >&5
+ echo $ECHO_N "checking for pow in -lm... $ECHO_C" >&6
+ if test "${ac_cv_lib_m_pow+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+ ac_check_lib_save_LIBS=$LIBS
+ LIBS="-lm $LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h. */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h. */
+
+ /* Override any gcc2 internal prototype to avoid an error. */
+ #ifdef __cplusplus
+ extern "C"
+ #endif
+ /* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+ char pow ();
+ int
+ main ()
+ {
+ pow ();
+ ;
+ return 0;
+ }
+ _ACEOF
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_m_pow=yes
+ else
+ echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_m_pow=no
+ fi
+ rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS=$ac_check_lib_save_LIBS
+ fi
+ echo "$as_me:$LINENO: result: $ac_cv_lib_m_pow" >&5
+ echo "${ECHO_T}$ac_cv_lib_m_pow" >&6
+ if test $ac_cv_lib_m_pow = yes; then
+ cat >>confdefs.h <<_ACEOF
+ #define HAVE_LIBM 1
+ _ACEOF
+
+ LIBS="-lm $LIBS"
+
+ fi
+
+ echo "$as_me:$LINENO: checking for pow()" >&5
+ echo $ECHO_N "checking for pow()... $ECHO_C" >&6
+ cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h. */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h. */
+
+ #ifdef HAVE_MATH_H
+ # include <math.h>
+ #endif
+
+ int
+ main ()
+ {
+ double f = pow(1.1, 3.0);
+ ;
+ return 0;
+ }
+ _ACEOF
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ echo "$as_me:$LINENO: result: yes" >&5
+ echo "${ECHO_T}yes" >&6; cat >>confdefs.h <<\_ACEOF
+ #define HAVE_POW 1
+ _ACEOF
+
+ else
+ echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+
+ echo "$as_me:$LINENO: result: no" >&5
+ echo "${ECHO_T}no" >&6
+ fi
+ rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
echo "$as_me:$LINENO: checking --disable-acl argument" >&5
echo $ECHO_N "checking --disable-acl argument... $ECHO_C" >&6
# Check whether --enable-acl or --disable-acl was given.
*** ../vim-7.1.291/src/config.h.in Tue May 1 13:37:23 2007
--- src/config.h.in Sun Apr 6 15:20:29 2008
***************
*** 150,155 ****
--- 150,156 ----
#undef HAVE_MEMSET
#undef HAVE_NANOSLEEP
#undef HAVE_OPENDIR
+ #undef HAVE_POW
#undef HAVE_PUTENV
#undef HAVE_QSORT
#undef HAVE_READLINK
***************
*** 199,204 ****
--- 200,206 ----
#undef HAVE_LIBGEN_H
#undef HAVE_LIBINTL_H
#undef HAVE_LOCALE_H
+ #undef HAVE_MATH_H
#undef HAVE_NDIR_H
#undef HAVE_POLL_H
#undef HAVE_PTHREAD_NP_H
*** ../vim-7.1.291/src/configure.in Wed Feb 20 12:43:05 2008
--- src/configure.in Sun Apr 6 15:22:40 2008
***************
*** 2034,2040 ****
AC_CHECK_HEADERS(stdarg.h stdlib.h string.h sys/select.h sys/utsname.h \
termcap.h fcntl.h sgtty.h sys/ioctl.h sys/time.h sys/types.h termio.h \
! iconv.h langinfo.h unistd.h stropts.h errno.h \
sys/resource.h sys/systeminfo.h locale.h \
sys/stream.h sys/ptem.h termios.h libc.h sys/statfs.h \
poll.h sys/poll.h pwd.h utime.h sys/param.h libintl.h \
--- 2034,2040 ----
AC_CHECK_HEADERS(stdarg.h stdlib.h string.h sys/select.h sys/utsname.h \
termcap.h fcntl.h sgtty.h sys/ioctl.h sys/time.h sys/types.h termio.h \
! iconv.h langinfo.h math.h unistd.h stropts.h errno.h \
sys/resource.h sys/systeminfo.h locale.h \
sys/stream.h sys/ptem.h termios.h libc.h sys/statfs.h \
poll.h sys/poll.h pwd.h utime.h sys/param.h libintl.h \
***************
*** 2490,2495 ****
--- 2490,2506 ----
AC_MSG_RESULT(yes); AC_DEFINE(HAVE_NL_LANGINFO_CODESET),
AC_MSG_RESULT(no))
+ dnl Need pow() for floating point support.
+ AC_CHECK_LIB(m, pow)
+ AC_MSG_CHECKING(for pow())
+ AC_TRY_LINK([
+ #ifdef HAVE_MATH_H
+ # include <math.h>
+ #endif
+ ], [double f = pow(1.1, 3.0);],
+ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_POW),
+ AC_MSG_RESULT(no))
+
dnl Link with -lposix1e for ACL stuff; if not found, try -lacl for SGI
dnl when -lacl works, also try to use -lattr (required for Debian).
AC_MSG_CHECKING(--disable-acl argument)
*** ../vim-7.1.291/src/eval.c Tue Apr 1 13:10:45 2008
--- src/eval.c Tue Apr 8 22:18:23 2008
***************
*** 30,35 ****
--- 30,39 ----
#if defined(FEAT_EVAL) || defined(PROTO)
+ #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
+ # include <math.h>
+ #endif
+
#define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */
/*
***************
*** 349,358 ****
};
/* shorthand */
! #define vv_type vv_di.di_tv.v_type
! #define vv_nr vv_di.di_tv.vval.v_number
! #define vv_str vv_di.di_tv.vval.v_string
! #define vv_tv vv_di.di_tv
/*
* The v: variables are stored in dictionary "vimvardict".
--- 353,363 ----
};
/* shorthand */
! #define vv_type vv_di.di_tv.v_type
! #define vv_nr vv_di.di_tv.vval.v_number
! #define vv_float vv_di.di_tv.vval.v_float
! #define vv_str vv_di.di_tv.vval.v_string
! #define vv_tv vv_di.di_tv
/*
* The v: variables are stored in dictionary "vimvardict".
***************
*** 450,455 ****
--- 455,464 ----
static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID));
static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID));
static char_u *string_quote __ARGS((char_u *str, int function));
+ #ifdef FEAT_FLOAT
+ static void get_float_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
+ static int string2float __ARGS((char_u *text, float_T *value, int comma));
+ #endif
static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
static int find_internal_func __ARGS((char_u *name));
static char_u *deref_func_name __ARGS((char_u *name, int *lenp));
***************
*** 637,642 ****
--- 646,654 ----
static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv));
static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv));
static void f_split __ARGS((typval_T *argvars, typval_T *rettv));
+ #ifdef FEAT_FLOAT
+ static void f_str2float __ARGS((typval_T *argvars, typval_T *rettv));
+ #endif
static void f_str2nr __ARGS((typval_T *argvars, typval_T *rettv));
#ifdef HAVE_STRFTIME
static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv));
***************
*** 1421,1427 ****
|| defined(FEAT_COMPL_FUNC) || defined(PROTO)
/*
* Call some vimL function and return the result in "*rettv".
! * Uses argv[argc] for the function arguments.
* Returns OK or FAIL.
*/
static int
--- 1433,1440 ----
|| defined(FEAT_COMPL_FUNC) || defined(PROTO)
/*
* Call some vimL function and return the result in "*rettv".
! * Uses argv[argc] for the function arguments. Only Number and String
! * arguments are currently supported.
* Returns OK or FAIL.
*/
static int
***************
*** 2848,2863 ****
{
/* nr += nr or nr -= nr*/
n = get_tv_number(tv1);
! if (*op == '+')
! n += get_tv_number(tv2);
else
! n -= get_tv_number(tv2);
! clear_tv(tv1);
! tv1->v_type = VAR_NUMBER;
! tv1->vval.v_number = n;
}
else
{
/* str .= str */
s = get_tv_string(tv1);
s = concat_str(s, get_tv_string_buf(tv2, numbuf));
--- 2861,2896 ----
{
/* nr += nr or nr -= nr*/
n = get_tv_number(tv1);
! #ifdef FEAT_FLOAT
! if (tv2->v_type == VAR_FLOAT)
! {
! float_T f = n;
!
! if (*op == '+')
! f += tv2->vval.v_float;
! else
! f -= tv2->vval.v_float;
! clear_tv(tv1);
! tv1->v_type = VAR_FLOAT;
! tv1->vval.v_float = f;
! }
else
! #endif
! {
! if (*op == '+')
! n += get_tv_number(tv2);
! else
! n -= get_tv_number(tv2);
! clear_tv(tv1);
! tv1->v_type = VAR_NUMBER;
! tv1->vval.v_number = n;
! }
}
else
{
+ if (tv2->v_type == VAR_FLOAT)
+ break;
+
/* str .= str */
s = get_tv_string(tv1);
s = concat_str(s, get_tv_string_buf(tv2, numbuf));
***************
*** 2866,2871 ****
--- 2899,2925 ----
tv1->vval.v_string = s;
}
return OK;
+
+ #ifdef FEAT_FLOAT
+ case VAR_FLOAT:
+ {
+ float_T f;
+
+ if (*op == '.' || (tv2->v_type != VAR_FLOAT
+ && tv2->v_type != VAR_NUMBER
+ && tv2->v_type != VAR_STRING))
+ break;
+ if (tv2->v_type == VAR_FLOAT)
+ f = tv2->vval.v_float;
+ else
+ f = get_tv_number(tv2);
+ if (*op == '+')
+ tv1->vval.v_float += f;
+ else
+ tv1->vval.v_float -= f;
+ }
+ return OK;
+ #endif
}
}
***************
*** 4237,4242 ****
--- 4291,4330 ----
}
}
+ #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 ((rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT)
+ && type != TYPE_MATCH && type != TYPE_NOMATCH)
+ {
+ float_T f1, f2;
+
+ if (rettv->v_type == VAR_FLOAT)
+ f1 = rettv->vval.v_float;
+ else
+ f1 = get_tv_number(rettv);
+ if (var2.v_type == VAR_FLOAT)
+ f2 = var2.vval.v_float;
+ else
+ f2 = get_tv_number(&var2);
+ 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.
***************
*** 4329,4334 ****
--- 4417,4425 ----
typval_T var3;
int op;
long n1, n2;
+ #ifdef FEAT_FLOAT
+ float_T f1 = 0, f2 = 0;
+ #endif
char_u *s1, *s2;
char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
char_u *p;
***************
*** 4348,4354 ****
if (op != '+' && op != '-' && op != '.')
break;
! if (op != '+' || rettv->v_type != VAR_LIST)
{
/* For "list + ...", an illegal use of the first operand as
* a number cannot be determined before evaluating the 2nd
--- 4439,4449 ----
if (op != '+' && op != '-' && op != '.')
break;
! if ((op != '+' || rettv->v_type != VAR_LIST)
! #ifdef FEAT_FLOAT
! && (op == '.' || rettv->v_type != VAR_FLOAT)
! #endif
! )
{
/* For "list + ...", an illegal use of the first operand as
* a number cannot be determined before evaluating the 2nd
***************
*** 4412,4440 ****
{
int error = FALSE;
! n1 = get_tv_number_chk(rettv, &error);
! if (error)
{
! /* This can only happen for "list + non-list".
! * For "non-list + ..." or "something - ...", we returned
! * before evaluating the 2nd operand. */
! clear_tv(rettv);
! return FAIL;
}
! n2 = get_tv_number_chk(&var2, &error);
! if (error)
{
! clear_tv(rettv);
! clear_tv(&var2);
! return FAIL;
}
clear_tv(rettv);
! if (op == '+')
! n1 = n1 + n2;
else
! n1 = n1 - n2;
! rettv->v_type = VAR_NUMBER;
! rettv->vval.v_number = n1;
}
clear_tv(&var2);
}
--- 4507,4579 ----
{
int error = FALSE;
! #ifdef FEAT_FLOAT
! if (rettv->v_type == VAR_FLOAT)
{
! f1 = rettv->vval.v_float;
! n1 = 0;
}
! else
! #endif
{
! n1 = get_tv_number_chk(rettv, &error);
! if (error)
! {
! /* This can only happen for "list + non-list". For
! * "non-list + ..." or "something - ...", we returned
! * before evaluating the 2nd operand. */
! clear_tv(rettv);
! return FAIL;
! }
! #ifdef FEAT_FLOAT
! if (var2.v_type == VAR_FLOAT)
! f1 = n1;
! #endif
! }
! #ifdef FEAT_FLOAT
! if (var2.v_type == VAR_FLOAT)
! {
! f2 = var2.vval.v_float;
! n2 = 0;
! }
! else
! #endif
! {
! n2 = get_tv_number_chk(&var2, &error);
! if (error)
! {
! clear_tv(rettv);
! clear_tv(&var2);
! return FAIL;
! }
! #ifdef FEAT_FLOAT
! if (rettv->v_type == VAR_FLOAT)
! f2 = n2;
! #endif
}
clear_tv(rettv);
!
! #ifdef FEAT_FLOAT
! /* If there is a float on either side the result is a float. */
! if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT)
! {
! if (op == '+')
! f1 = f1 + f2;
! else
! f1 = f1 - f2;
! rettv->v_type = VAR_FLOAT;
! rettv->vval.v_float = f1;
! }
else
! #endif
! {
! if (op == '+')
! n1 = n1 + n2;
! else
! n1 = n1 - n2;
! rettv->v_type = VAR_NUMBER;
! rettv->vval.v_number = n1;
! }
}
clear_tv(&var2);
}
***************
*** 4462,4467 ****
--- 4601,4610 ----
typval_T var2;
int op;
long n1, n2;
+ #ifdef FEAT_FLOAT
+ int use_float = FALSE;
+ float_T f1 = 0, f2;
+ #endif
int error = FALSE;
/*
***************
*** 4481,4487 ****
if (evaluate)
{
! n1 = get_tv_number_chk(rettv, &error);
clear_tv(rettv);
if (error)
return FAIL;
--- 4624,4639 ----
if (evaluate)
{
! #ifdef FEAT_FLOAT
! if (rettv->v_type == VAR_FLOAT)
! {
! f1 = rettv->vval.v_float;
! use_float = TRUE;
! n1 = 0;
! }
! else
! #endif
! n1 = get_tv_number_chk(rettv, &error);
clear_tv(rettv);
if (error)
return FAIL;
***************
*** 4498,4529 ****
if (evaluate)
{
! n2 = get_tv_number_chk(&var2, &error);
! clear_tv(&var2);
! if (error)
! return FAIL;
/*
* Compute the result.
*/
! if (op == '*')
! n1 = n1 * n2;
! else if (op == '/')
{
! if (n2 == 0) /* give an error message? */
! n1 = 0x7fffffffL;
else
! n1 = n1 / n2;
}
else
{
! if (n2 == 0) /* give an error message? */
! n1 = 0;
else
! n1 = n1 % n2;
}
- rettv->v_type = VAR_NUMBER;
- rettv->vval.v_number = n1;
}
}
--- 4650,4729 ----
if (evaluate)
{
! #ifdef FEAT_FLOAT
! if (var2.v_type == VAR_FLOAT)
! {
! if (!use_float)
! {
! f1 = n1;
! use_float = TRUE;
! }
! f2 = var2.vval.v_float;
! n2 = 0;
! }
! else
! #endif
! {
! n2 = get_tv_number_chk(&var2, &error);
! clear_tv(&var2);
! if (error)
! return FAIL;
! #ifdef FEAT_FLOAT
! if (use_float)
! f2 = n2;
! #endif
! }
/*
* Compute the result.
+ * When either side is a float the result is a float.
*/
! #ifdef FEAT_FLOAT
! if (use_float)
{
! if (op == '*')
! f1 = f1 * f2;
! else if (op == '/')
! {
! if (f2 == 0.0) /* give an error message? */
! # ifdef INFINITY
! f1 = INFINITY;
! # else
! f1 = 0x7fffffffL;
! # endif
! else
! f1 = f1 / f2;
! }
else
! {
! EMSG(_("E804: Cannot use % with float"));
! return FAIL;
! }
! rettv->v_type = VAR_FLOAT;
! rettv->vval.v_float = f1;
}
else
+ #endif
{
! if (op == '*')
! n1 = n1 * n2;
! else if (op == '/')
! {
! if (n2 == 0) /* give an error message? */
! n1 = 0x7fffffffL;
! else
! n1 = n1 / n2;
! }
else
! {
! if (n2 == 0) /* give an error message? */
! n1 = 0;
! else
! n1 = n1 % n2;
! }
! rettv->v_type = VAR_NUMBER;
! rettv->vval.v_number = n1;
}
}
}
***************
*** 4565,4571 ****
long n;
int len;
char_u *s;
- int val;
char_u *start_leader, *end_leader;
int ret = OK;
char_u *alias;
--- 4765,4770 ----
***************
*** 4635,4641 ****
/*
* Option value: &name
*/
! case '&': ret = get_option_tv(arg, rettv, evaluate);
break;
/*
--- 4834,4846 ----
/*
* Option value: &name
*/
! case '&':
! #ifdef FEAT_FLOAT
! if (vim_isdigit(*(*arg + 1)))
! get_float_tv(arg, rettv, evaluate);
! else
! #endif
! ret = get_option_tv(arg, rettv, evaluate);
break;
/*
***************
*** 4734,4741 ****
if (ret == OK && evaluate && end_leader > start_leader)
{
int error = FALSE;
! val = get_tv_number_chk(rettv, &error);
if (error)
{
clear_tv(rettv);
--- 4939,4953 ----
if (ret == OK && evaluate && end_leader > start_leader)
{
int error = FALSE;
+ int val = 0;
+ #ifdef FEAT_FLOAT
+ float_T f = 0;
! if (rettv->v_type == VAR_FLOAT)
! f = rettv->vval.v_float;
! else
! #endif
! val = get_tv_number_chk(rettv, &error);
if (error)
{
clear_tv(rettv);
***************
*** 4747,4759 ****
{
--end_leader;
if (*end_leader == '!')
! val = !val;
else if (*end_leader == '-')
! val = -val;
}
- clear_tv(rettv);
- rettv->v_type = VAR_NUMBER;
- rettv->vval.v_number = val;
}
}
--- 4959,4995 ----
{
--end_leader;
if (*end_leader == '!')
! {
! #ifdef FEAT_FLOAT
! if (rettv->v_type == VAR_FLOAT)
! f = !f;
! else
! #endif
! val = !val;
! }
else if (*end_leader == '-')
! {
! #ifdef FEAT_FLOAT
! if (rettv->v_type == VAR_FLOAT)
! f = -f;
! else
! #endif
! val = -val;
! }
! }
! #ifdef FEAT_FLOAT
! if (rettv->v_type == VAR_FLOAT)
! {
! clear_tv(rettv);
! rettv->vval.v_float = f;
! }
! else
! #endif
! {
! clear_tv(rettv);
! rettv->v_type = VAR_NUMBER;
! rettv->vval.v_number = val;
}
}
}
***************
*** 4780,4786 ****
char_u *s;
char_u *key = NULL;
! if (rettv->v_type == VAR_FUNC)
{
if (verbose)
EMSG(_("E695: Cannot index a Funcref"));
--- 5016,5026 ----
char_u *s;
char_u *key = NULL;
! if (rettv->v_type == VAR_FUNC
! #ifdef FEAT_FLOAT
! || rettv->v_type == VAR_FLOAT
! #endif
! )
{
if (verbose)
EMSG(_("E695: Cannot index a Funcref"));
***************
*** 5566,5572 ****
/*
* Return TRUE if "tv1" and "tv2" have the same value.
* Compares the items just like "==" would compare them, but strings and
! * numbers are different.
*/
static int
tv_equal(tv1, tv2, ic)
--- 5806,5812 ----
/*
* Return TRUE if "tv1" and "tv2" have the same value.
* Compares the items just like "==" would compare them, but strings and
! * numbers are different. Floats and numbers are also different.
*/
static int
tv_equal(tv1, tv2, ic)
***************
*** 5608,5613 ****
--- 5848,5858 ----
case VAR_NUMBER:
return tv1->vval.v_number == tv2->vval.v_number;
+ #ifdef FEAT_FLOAT
+ case VAR_FLOAT:
+ return tv1->vval.v_float == tv2->vval.v_float;
+ #endif
+
case VAR_STRING:
s1 = get_tv_string_buf(tv1, buf1);
s2 = get_tv_string_buf(tv2, buf2);
***************
*** 6897,6902 ****
--- 7142,7155 ----
r = get_tv_string_buf(tv, numbuf);
break;
+ #ifdef FEAT_FLOAT
+ case VAR_FLOAT:
+ *tofree = NULL;
+ vim_snprintf(numbuf, NUMBUFLEN, "%f", tv->vval.v_float);
+ r = numbuf;
+ break;
+ #endif
+
default:
EMSG2(_(e_intern2), "echo_string()");
*tofree = NULL;
***************
*** 6929,6934 ****
--- 7182,7190 ----
*tofree = string_quote(tv->vval.v_string, FALSE);
return *tofree;
case VAR_NUMBER:
+ #ifdef FEAT_FLOAT
+ case VAR_FLOAT:
+ #endif
case VAR_LIST:
case VAR_DICT:
break;
***************
*** 6984,6989 ****
--- 7240,7310 ----
return s;
}
+ #ifdef FEAT_FLOAT
+ /*
+ * Get the value of a floating point number: &123.456
+ * "arg" is pointing to the '&'. It is advanced to after the number.
+ */
+ static void
+ get_float_tv(arg, rettv, evaluate)
+ char_u **arg;
+ typval_T *rettv;
+ int evaluate;
+ {
+ float_T f;
+
+ ++*arg;
+ *arg += string2float(*arg, &f, FALSE);
+ if (evaluate)
+ {
+ rettv->v_type = VAR_FLOAT;
+ rettv->vval.v_float = f;
+ }
+ }
+
+ /*
+ * Convert the sting "text" to a floating point number.
+ * Returns the length of the text that was consumed.
+ */
+ static int
+ string2float(text, value, comma)
+ char_u *text;
+ float_T *value; /* result stored here */
+ int comma; /* accept a comma as decimal separator */
+ {
+ char_u *s = text;
+ int len;
+ long n;
+ float_T f;
+
+ vim_str2nr(s, NULL, &len, FALSE, FALSE, &n, NULL);
+ s += len;
+ f = n;
+
+ if ((*s == '.' || (comma && *s == ',')) && s[1] != '-')
+ {
+ ++s;
+ vim_str2nr(s, NULL, &len, FALSE, FALSE, &n, NULL);
+ s += len;
+ f += (float_T)n / pow(10.0, (double)len);
+ }
+
+ /* 1.234e-20 */
+ if (*s == 'e' || *s == 'E')
+ {
+ ++s;
+ if (*s == '+') /* accept 1.234e+3 */
+ ++s;
+ vim_str2nr(s, NULL, &len, FALSE, FALSE, &n, NULL);
+ s += len;
+ f *= pow(10.0, (double)n);
+ }
+
+ *value = f;
+ return (int)(s - text);
+ }
+ #endif
+
/*
* Get the value of an environment variable.
* "arg" is pointing to the '$'. It is advanced to after the name.
***************
*** 7240,7245 ****
--- 7561,7569 ----
{"spellbadword", 0, 1, f_spellbadword},
{"spellsuggest", 1, 3, f_spellsuggest},
{"split", 1, 3, f_split},
+ #ifdef FEAT_FLOAT
+ {"str2float", 1, 1, f_str2float},
+ #endif
{"str2nr", 1, 2, f_str2nr},
#ifdef HAVE_STRFTIME
{"strftime", 1, 2, f_strftime},
***************
*** 8800,8805 ****
--- 9124,9134 ----
case VAR_NUMBER:
n = argvars[0].vval.v_number == 0;
break;
+ #ifdef FEAT_FLOAT
+ case VAR_FLOAT:
+ n = argvars[0].vval.v_float == 0.0;
+ break;
+ #endif
case VAR_LIST:
n = argvars[0].vval.v_list == NULL
|| argvars[0].vval.v_list->lv_first == NULL;
***************
*** 10877,10882 ****
--- 11206,11214 ----
#ifdef FEAT_FIND_ID
"find_in_path",
#endif
+ #ifdef FEAT_FLOAT
+ "float",
+ #endif
#ifdef FEAT_FOLDING
"folding",
#endif
***************
*** 15432,15437 ****
--- 15764,15784 ----
p_cpo = save_cpo;
}
+ #ifdef FEAT_FLOAT
+ /*
+ * "str2float()" function
+ */
+ static void
+ f_str2float(argvars, rettv)
+ typval_T *argvars;
+ typval_T *rettv;
+ {
+ (void)string2float(skipwhite(get_tv_string(&argvars[0])),
+ &rettv->vval.v_float, TRUE);
+ rettv->v_type = VAR_FLOAT;
+ }
+ #endif
+
/*
* "str2nr()" function
*/
***************
*** 16476,16481 ****
--- 16823,16831 ----
case VAR_FUNC: n = 2; break;
case VAR_LIST: n = 3; break;
case VAR_DICT: n = 4; break;
+ #ifdef FEAT_FLOAT
+ case VAR_FLOAT: n = 5; break;
+ #endif
default: EMSG2(_(e_intern2), "f_type()"); n = 0; break;
}
rettv->vval.v_number = n;
***************
*** 17662,17667 ****
--- 18012,18020 ----
dict_unref(varp->vval.v_dict);
break;
case VAR_NUMBER:
+ #ifdef FEAT_FLOAT
+ case VAR_FLOAT:
+ #endif
case VAR_UNKNOWN:
break;
default:
***************
*** 17701,17706 ****
--- 18054,18064 ----
case VAR_NUMBER:
varp->vval.v_number = 0;
break;
+ #ifdef FEAT_FLOAT
+ case VAR_FLOAT:
+ varp->vval.v_float = 0;
+ break;
+ #endif
case VAR_UNKNOWN:
break;
default:
***************
*** 17749,17754 ****
--- 18107,18117 ----
{
case VAR_NUMBER:
return (long)(varp->vval.v_number);
+ #ifdef FEAT_FLOAT
+ case VAR_FLOAT:
+ EMSG(_("E805: Using a Float as a number"));
+ break;
+ #endif
case VAR_FUNC:
EMSG(_("E703: Using a Funcref as a number"));
break;
***************
*** 17872,17877 ****
--- 18235,18245 ----
case VAR_DICT:
EMSG(_("E731: using Dictionary as a String"));
break;
+ #ifdef FEAT_FLOAT
+ case VAR_FLOAT:
+ EMSG(_("E806: using Float as a String"));
+ break;
+ #endif
case VAR_STRING:
if (varp->vval.v_string != NULL)
return varp->vval.v_string;
***************
*** 18410,18415 ****
--- 18778,18788 ----
case VAR_NUMBER:
to->vval.v_number = from->vval.v_number;
break;
+ #ifdef FEAT_FLOAT
+ case VAR_FLOAT:
+ to->vval.v_float = from->vval.v_float;
+ break;
+ #endif
case VAR_STRING:
case VAR_FUNC:
if (from->vval.v_string == NULL)
***************
*** 18472,18477 ****
--- 18845,18853 ----
switch (from->v_type)
{
case VAR_NUMBER:
+ #ifdef FEAT_FLOAT
+ case VAR_FLOAT:
+ #endif
case VAR_STRING:
case VAR_FUNC:
copy_tv(from, to);
***************
*** 20846,20854 ****
#if defined(FEAT_VIMINFO) || defined(FEAT_SESSION)
typedef enum
{
! VAR_FLAVOUR_DEFAULT,
! VAR_FLAVOUR_SESSION,
! VAR_FLAVOUR_VIMINFO
} var_flavour_T;
static var_flavour_T var_flavour __ARGS((char_u *varname));
--- 21222,21230 ----
#if defined(FEAT_VIMINFO) || defined(FEAT_SESSION)
typedef enum
{
! VAR_FLAVOUR_DEFAULT, /* doesn't start with uppercase */
! VAR_FLAVOUR_SESSION, /* starts with uppercase, some lower */
! VAR_FLAVOUR_VIMINFO /* all uppercase */
} var_flavour_T;
static var_flavour_T var_flavour __ARGS((char_u *varname));
***************
*** 20881,20887 ****
int writing;
{
char_u *tab;
! int is_string = FALSE;
typval_T tv;
if (!writing && (find_viminfo_parameter('!') != NULL))
--- 21257,21263 ----
int writing;
{
char_u *tab;
! int type = VAR_NUMBER;
typval_T tv;
if (!writing && (find_viminfo_parameter('!') != NULL))
***************
*** 20891,20914 ****
{
*tab++ = '\0'; /* isolate the variable name */
if (*tab == 'S') /* string var */
! is_string = TRUE;
tab = vim_strchr(tab, '\t');
if (tab != NULL)
{
! if (is_string)
! {
! tv.v_type = VAR_STRING;
tv.vval.v_string = viminfo_readstring(virp,
(int)(tab - virp->vir_line + 1), TRUE);
! }
else
- {
- tv.v_type = VAR_NUMBER;
tv.vval.v_number = atol((char *)tab + 1);
- }
set_var(virp->vir_line + 1, &tv, FALSE);
! if (is_string)
vim_free(tv.vval.v_string);
}
}
--- 21267,21293 ----
{
*tab++ = '\0'; /* isolate the variable name */
if (*tab == 'S') /* string var */
! type = VAR_STRING;
! #ifdef FEAT_FLOAT
! else if (*tab == 'F')
! type = VAR_FLOAT;
! #endif
tab = vim_strchr(tab, '\t');
if (tab != NULL)
{
! tv.v_type = type;
! if (type == VAR_STRING)
tv.vval.v_string = viminfo_readstring(virp,
(int)(tab - virp->vir_line + 1), TRUE);
! #ifdef FEAT_FLOAT
! else if (type == VAR_FLOAT)
! (void)string2float(tab + 1, &tv.vval.v_float, TRUE);
! #endif
else
tv.vval.v_number = atol((char *)tab + 1);
set_var(virp->vir_line + 1, &tv, FALSE);
! if (type == VAR_STRING)
vim_free(tv.vval.v_string);
}
}
***************
*** 20950,20955 ****
--- 21329,21337 ----
{
case VAR_STRING: s = "STR"; break;
case VAR_NUMBER: s = "NUM"; break;
+ #ifdef FEAT_FLOAT
+ case VAR_FLOAT: s = "FLO"; break;
+ #endif
default: continue;
}
fprintf(fp, "!%s\t%s\t", this_var->di_key, s);
***************
*** 21009,21014 ****
--- 21391,21414 ----
}
vim_free(p);
}
+ #ifdef FEAT_FLOAT
+ else if (this_var->di_tv.v_type == VAR_FLOAT
+ && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION)
+ {
+ float_T f = this_var->di_tv.vval.v_float;
+ int sign = ' ';
+
+ if (f < 0)
+ {
+ f = -f;
+ sign = '-';
+ }
+ if ((fprintf(fd, "let %s = %c&%f",
+ this_var->di_key, sign, f) < 0)
+ || put_eol(fd) == FAIL)
+ return FAIL;
+ }
+ #endif
}
}
return OK;
***************
*** 21080,21086 ****
vim_free(*bufp);
*fnamep = *bufp = newbuf;
! l = GetShortPathName(*fnamep,*fnamep,l+1);
/* Really should always succeed, as the buffer is big enough */
}
--- 21480,21486 ----
vim_free(*bufp);
*fnamep = *bufp = newbuf;
! l = GetShortPathName(*fnamep, *fnamep, l+1);
/* Really should always succeed, as the buffer is big enough */
}
*** ../vim-7.1.291/src/feature.h Fri Aug 3 22:01:35 2007
--- src/feature.h Sun Apr 6 15:24:33 2008
***************
*** 35,41 ****
* +small few features enabled, as basic as possible
* +normal A default selection of features enabled
* +big many features enabled, as rich as possible.
! * +huge all possible featues enabled.
*
* When +small is used, +tiny is also included. +normal implies +small, etc.
*/
--- 35,41 ----
* +small few features enabled, as basic as possible
* +normal A default selection of features enabled
* +big many features enabled, as rich as possible.
! * +huge all possible features enabled.
*
* When +small is used, +tiny is also included. +normal implies +small, etc.
*/
***************
*** 376,384 ****
--- 376,388 ----
/*
* +eval Built-in script language and expression evaluation,
* ":let", ":if", etc.
+ * +float Floating point variables.
*/
#ifdef FEAT_NORMAL
# define FEAT_EVAL
+ # if defined(HAVE_POW)
+ # define FEAT_FLOAT
+ # endif
#endif
/*
*** ../vim-7.1.291/src/if_python.c Thu Mar 8 10:20:28 2007
--- src/if_python.c Fri Apr 4 21:07:03 2008
***************
*** 1130,1135 ****
--- 1130,1146 ----
result = Py_BuildValue("s", buf);
PyDict_SetItemString(lookupDict, ptrBuf, result);
}
+ #ifdef FEAT_FLOAT
+ else if (our_tv->v_type == VAR_FLOAT)
+ {
+ char buf[NUMBUFLEN];
+
+ /* For backwards compatibility numbers are stored as strings. */
+ sprintf(buf, "%f", (long)our_tv->vval.v_float);
+ result = Py_BuildValue("s", buf);
+ PyDict_SetItemString(lookupDict, ptrBuf, result);
+ }
+ #endif
else if (our_tv->v_type == VAR_LIST)
{
list_T *list = our_tv->vval.v_list;
*** ../vim-7.1.291/src/message.c Sat Nov 24 15:44:17 2007
--- src/message.c Tue Apr 8 22:19:06 2008
***************
*** 3819,3824 ****
--- 3819,3827 ----
static long tv_nr __ARGS((typval_T *tvs, int *idxp));
static char *tv_str __ARGS((typval_T *tvs, int *idxp));
+ # ifdef FEAT_FLOAT
+ static double tv_float __ARGS((typval_T *tvs, int *idxp));
+ # endif
/*
* Get number argument from "idxp" entry in "tvs". First entry is 1.
***************
*** 3865,3870 ****
--- 3868,3899 ----
}
return s;
}
+
+ # ifdef FEAT_FLOAT
+ /*
+ * Get float argument from "idxp" entry in "tvs". First entry is 1.
+ */
+ static double
+ tv_float(tvs, idxp)
+ typval_T *tvs;
+ int *idxp;
+ {
+ int idx = *idxp - 1;
+ double f = 0;
+
+ if (tvs[idx].v_type == VAR_UNKNOWN)
+ EMSG(_(e_printf));
+ else
+ {
+ ++*idxp;
+ if (tvs[idx].v_type == VAR_FLOAT)
+ f = tvs[idx].vval.v_float;
+ else
+ EMSG(_("E807: Expected Float argument for printf()"));
+ }
+ return f;
+ }
+ # endif
#endif
/*
***************
*** 3883,3888 ****
--- 3912,3919 ----
* with flags: '-', '+', ' ', '0' and '#'.
* An asterisk is supported for field width as well as precision.
*
+ * Limited support for 'f' (floating point) was added.
+ *
* Length modifiers 'h' (short int) and 'l' (long int) are supported.
* 'll' (long long int) is not supported.
*
***************
*** 4124,4129 ****
--- 4155,4161 ----
case 'D': fmt_spec = 'd'; length_modifier = 'l'; break;
case 'U': fmt_spec = 'u'; length_modifier = 'l'; break;
case 'O': fmt_spec = 'o'; length_modifier = 'l'; break;
+ case 'F': fmt_spec = 'f'; break;
default: break;
}
***************
*** 4459,4464 ****
--- 4491,4527 ----
break;
}
+ #ifdef FEAT_FLOAT
+ case 'f':
+ case 'e':
+ case 'E':
+ {
+ /* Floating point. Very limited at the moment. */
+ double f;
+ char format[40];
+ int l;
+
+ f + #ifndef HAVE_STDARG_H
+ get_a_arg(arg_idx);
+ #else
+ # if defined(FEAT_EVAL)
+ tvs != NULL ? tv_float(tvs, &arg_idx) :
+ # endif
+ va_arg(ap, double);
+ #endif
+ format[0] = '%';
+ l = 1;
+ if (precision_specified)
+ l += sprintf(format + 1, ".%d", precision);
+ format[l] = fmt_spec;
+ format[l + 1] = NUL;
+ str_arg_l = sprintf(tmp, format, f);
+ str_arg = tmp;
+ break;
+ }
+ #endif
+
default:
/* unrecognized conversion specifier, keep format string
* as-is */
***************
*** 4566,4572 ****
if (justify_left)
{
/* right blank padding to the field width */
! int pn = (int)(min_field_width - (str_arg_l + number_of_zeros_to_pad));
if (pn > 0)
{
--- 4629,4636 ----
if (justify_left)
{
/* right blank padding to the field width */
! int pn = (int)(min_field_width
! - (str_arg_l + number_of_zeros_to_pad));
if (pn > 0)
{
*** ../vim-7.1.291/src/structs.h Sat Jan 19 15:55:51 2008
--- src/structs.h Fri Apr 4 22:06:03 2008
***************
*** 1005,1010 ****
--- 1005,1011 ----
#else
typedef int varnumber_T;
#endif
+ typedef double float_T;
typedef struct listvar_S list_T;
typedef struct dictvar_S dict_T;
***************
*** 1019,1024 ****
--- 1020,1028 ----
union
{
varnumber_T v_number; /* number value */
+ #ifdef FEAT_FLOAT
+ float_T v_float; /* floating number value */
+ #endif
char_u *v_string; /* string value (can be NULL!) */
list_T *v_list; /* list value (can be NULL!) */
dict_T *v_dict; /* dict value (can be NULL!) */
***************
*** 1032,1037 ****
--- 1036,1042 ----
#define VAR_FUNC 3 /* "v_string" is function name */
#define VAR_LIST 4 /* "v_list" is used */
#define VAR_DICT 5 /* "v_dict" is used */
+ #define VAR_FLOAT 6 /* "v_float" is used */
/* Values for "v_lock". */
#define VAR_LOCKED 1 /* locked with lock(), can use unlock() */
*** ../vim-7.1.291/src/version.c Tue Apr 1 20:58:23 2008
--- src/version.c Sun Apr 6 15:25:42 2008
***************
*** 217,222 ****
--- 217,227 ----
#else
"-find_in_path",
#endif
+ #ifdef FEAT_FLOAT
+ "+float",
+ #else
+ "-float",
+ #endif
#ifdef FEAT_FOLDING
"+folding",
#else