1/ According to ":help functions", function cursor() is meant
to return a value of type 'Number'. But function cursor()
(f_cursor() in eval.c) does not return anything. So doing
":echo cursor(1,1)" prints an uninitialized value and valgrind
reports the following error:
==20458== Use of uninitialised value of size 4
==20458== at 0x4F9A7F6: (within /lib/tls/i686/cmov/libc-2.8.90.so)
==20458== by 0x4F9E398: vfprintf (in /lib/tls/i686/cmov/libc-2.8.90.so)
==20458== by 0x4FBE02B: vsprintf (in /lib/tls/i686/cmov/libc-2.8.90.so)
==20458== by 0x4FA5D3A: sprintf (in /lib/tls/i686/cmov/libc-2.8.90.so)
==20458== by 0x80932DE: get_tv_string_buf_chk (stdio2.h:34)
==20458== by 0x809334A: get_tv_string_buf (eval.c:18752)
==20458== by 0x8094A71: echo_string (eval.c:7290)
==20458== by 0x80AD37E: ex_echo (eval.c:19507)
==20458== by 0x80CCA86: do_one_cmd (ex_docmd.c:2622)
==20458== by 0x80CAD92: do_cmdline (ex_docmd.c:1096)
==20458== by 0x8142E0F: nv_colon (normal.c:5218)
==20458== by 0x8144EAF: normal_cmd (normal.c:1189)
==20458== by 0x81044D6: main_loop (main.c:1180)
==20458== by 0x81078B2: main (main.c:939)
Attached patch makes cursor() return 0 if success, -1 if failure.
2/ Function setpos() returns 'none' according to ":help functions"
but looking at the code, it actually returns 0 in case of success
and -1 in case of error.
Patch fixes documentation.
3/ Function complete() returns a String according to ":help functions"
but it may return something initialized in case of error.
:echo complete('', '') for example prints something uninitialized
and valgrind also reports an error.
Patch makes it return an empty string in case of error.
4/ Function feedkeys() always returns 0 according to ":help feedkeys()"
but it may return something uninitialized when doing:
":sandbox echo feedkeys('')
Attached patch makes it always return 0 as stated in documentation.
5/ The following functions do not return anything:
clearmatches()
garbagecollect()
winrestview()
So doing ":echo garbagecollect()" prints something uninitialized
and valgrind reports uninitialized memory access.
Making them return something is better I think. So
":echo garbagecollect()" prints something deterministic.
Attached patch makes them always return 0, just like what
is already done for "feedkeys()".
Regards
-- Dominique
--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---
Index: src/eval.c
===================================================================
RCS file: /cvsroot/vim/vim7/src/eval.c,v
retrieving revision 1.280
diff -c -r1.280 eval.c
*** src/eval.c 4 Feb 2009 15:27:06 -0000 1.280
--- src/eval.c 21 Mar 2009 20:41:21 -0000
***************
*** 1285,1291 ****
--- 1285,1293 ----
typval_T tv;
char_u *retval;
garray_T ga;
+ #ifdef FEAT_FLOAT
char_u numbuf[NUMBUFLEN];
+ #endif
if (eval0(arg, &tv, nextcmd, TRUE) == FAIL)
retval = NULL;
***************
*** 8859,8864 ****
--- 8861,8867 ----
typval_T *argvars;
typval_T *rettv;
{
+ rettv->vval.v_number = 0;
#ifdef FEAT_SEARCH_EXTRA
clear_matches(curwin);
#endif
***************
*** 8929,8934 ****
--- 8932,8940 ----
{
int startcol;
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+
if ((State & INSERT) == 0)
{
EMSG(_("E785: complete() can only be used in Insert mode"));
***************
*** 9189,9195 ****
/*
* "cursor(lnum, col)" function
*
! * Moves the cursor to the specified line and column
*/
/*ARGSUSED*/
static void
--- 9195,9202 ----
/*
* "cursor(lnum, col)" function
*
! * Moves the cursor to the specified line and column.
! * Returns 0 when the position could be set, -1 otherwise.
*/
/*ARGSUSED*/
static void
***************
*** 9202,9207 ****
--- 9209,9215 ----
long coladd = 0;
#endif
+ rettv->vval.v_number = -1;
if (argvars[1].v_type == VAR_UNKNOWN)
{
pos_T pos;
***************
*** 9246,9251 ****
--- 9254,9260 ----
#endif
curwin->w_set_curswant = TRUE;
+ rettv->vval.v_number = 0;
}
/*
***************
*** 9727,9739 ****
int typed = FALSE;
char_u *keys_esc;
/* This is not allowed in the sandbox. If the commands would still be
* executed in the sandbox it would be OK, but it probably happens later,
* when "sandbox" is no longer set. */
if (check_secure())
return;
- rettv->vval.v_number = 0;
keys = get_tv_string(&argvars[0]);
if (*keys != NUL)
{
--- 9736,9749 ----
int typed = FALSE;
char_u *keys_esc;
+ rettv->vval.v_number = 0;
+
/* This is not allowed in the sandbox. If the commands would still be
* executed in the sandbox it would be OK, but it probably happens later,
* when "sandbox" is no longer set. */
if (check_secure())
return;
keys = get_tv_string(&argvars[0]);
if (*keys != NUL)
{
***************
*** 10385,10390 ****
--- 10395,10401 ----
/* This is postponed until we are back at the toplevel, because we may be
* using Lists and Dicts internally. E.g.: ":echo [garbagecollect()]". */
want_garbage_collect = TRUE;
+ rettv->vval.v_number = 0;
if (argvars[0].v_type != VAR_UNKNOWN && get_tv_number(&argvars[0]) == 1)
garbage_collect_at_exit = TRUE;
***************
*** 17529,17534 ****
--- 17540,17546 ----
{
dict_T *dict;
+ rettv->vval.v_number = 0;
if (argvars[0].v_type != VAR_DICT
|| (dict = argvars[0].vval.v_dict) == NULL)
EMSG(_(e_invarg));
*** ../vim-runtime/doc/eval.txt 2009-01-14 21:14:54.000000000 +0100
--- runtime/doc/eval.txt 2009-03-21 21:34:46.000000000 +0100
***************
*** 1681,1687 ****
changenr() Number current change number
char2nr( {expr}) Number ASCII value of first char in {expr}
cindent( {lnum}) Number C indent for line {lnum}
! clearmatches() None clear all matches
col( {expr}) Number column nr of cursor or mark
complete({startcol}, {matches}) String set Insert mode completion
complete_add( {expr}) Number add completion match
--- 1681,1687 ----
changenr() Number current change number
char2nr( {expr}) Number ASCII value of first char in {expr}
cindent( {lnum}) Number C indent for line {lnum}
! clearmatches() Number clear all matches
col( {expr}) Number column nr of cursor or mark
complete({startcol}, {matches}) String set Insert mode completion
complete_add( {expr}) Number add completion match
***************
*** 1731,1737 ****
foldtextresult( {lnum}) String text for closed fold at {lnum}
foreground( ) Number bring the Vim window to the foreground
function( {name}) Funcref reference to function {name}
! garbagecollect( [at_exit]) none free memory, breaking cyclic references
get( {list}, {idx} [, {def}]) any get item {idx} from {list} or {def}
get( {dict}, {key} [, {def}]) any get item {key} from {dict} or {def}
getbufline( {expr}, {lnum} [, {end}])
--- 1731,1737 ----
foldtextresult( {lnum}) String text for closed fold at {lnum}
foreground( ) Number bring the Vim window to the foreground
function( {name}) Funcref reference to function {name}
! garbagecollect( [at_exit]) Number free memory, breaking cyclic references
get( {list}, {idx} [, {def}]) any get item {idx} from {list} or {def}
get( {dict}, {key} [, {def}]) any get item {key} from {dict} or {def}
getbufline( {expr}, {lnum} [, {end}])
***************
*** 1871,1877 ****
setloclist( {nr}, {list}[, {action}])
Number modify location list using {list}
setmatches( {list}) Number restore a list of matches
! setpos( {expr}, {list}) none set the {expr} position to {list}
setqflist( {list}[, {action}]) Number modify quickfix list using {list}
setreg( {n}, {v}[, {opt}]) Number set register to value and type
settabwinvar( {tabnr}, {winnr}, {varname}, {val}) set {varname} in window
--- 1871,1877 ----
setloclist( {nr}, {list}[, {action}])
Number modify location list using {list}
setmatches( {list}) Number restore a list of matches
! setpos( {expr}, {list}) Number set the {expr} position to {list}
setqflist( {list}[, {action}]) Number modify quickfix list using {list}
setreg( {n}, {v}[, {opt}]) Number set register to value and type
settabwinvar( {tabnr}, {winnr}, {varname}, {val}) set {varname} in window
***************
*** 1933,1939 ****
winline() Number window line of the cursor
winnr( [{expr}]) Number number of current window
winrestcmd() String returns command to restore window sizes
! winrestview({dict}) None restore view of current window
winsaveview() Dict save view of current window
winwidth( {nr}) Number width of window {nr}
writefile({list}, {fname} [, {binary}])
--- 1933,1939 ----
winline() Number window line of the cursor
winnr( [{expr}]) Number number of current window
winrestcmd() String returns command to restore window sizes
! winrestview({dict}) Number restore view of current window
winsaveview() Dict save view of current window
winwidth( {nr}) Number width of window {nr}
writefile({list}, {fname} [, {binary}])
***************
*** 2202,2207 ****
--- 2202,2208 ----
clearmatches() *clearmatches()*
Clears all matches previously defined by |matchadd()| and the
|:match| commands.
+ Return value is always 0.
*col()*
col({expr}) The result is a Number, which is the byte index of the column
***************
*** 2249,2255 ****
{matches} must be a |List|. Each |List| item is one match.
See |complete-items| for the kind of items that are possible.
Note that the after calling this function you need to avoid
! inserting anything that would completion to stop.
The match can be selected with CTRL-N and CTRL-P as usual with
Insert mode completion. The popup menu will appear if
specified, see |ins-completion-menu|.
--- 2250,2256 ----
{matches} must be a |List|. Each |List| item is one match.
See |complete-items| for the kind of items that are possible.
Note that the after calling this function you need to avoid
! inserting anything that would cause completion to stop.
The match can be selected with CTRL-N and CTRL-P as usual with
Insert mode completion. The popup menu will appear if
specified, see |ins-completion-menu|.
***************
*** 2418,2423 ****
--- 2419,2425 ----
When 'virtualedit' is used {off} specifies the offset in
screen columns from the start of the character. E.g., a
position within a <Tab> or after the last character.
+ Returns 0 when the position could be set, -1 otherwise.
deepcopy({expr}[, {noref}]) *deepcopy()* *E698*
***************
*** 2939,2944 ****
--- 2941,2947 ----
When the optional "at_exit" argument is one, garbage
collection will also be done when exiting Vim, if it wasn't
done before. This is useful when checking for memory leaks.
+ Return value is always 0.
get({list}, {idx} [, {default}]) *get()*
Get item {idx} from |List| {list}. When this item is not
***************
*** 5696,5701 ****
--- 5699,5705 ----
the view of the current window.
If you have changed the values the result is unpredictable.
If the window size changed the result won't be the same.
+ Return value is always 0.
*winsaveview()*
winsaveview() Returns a |Dictionary| that contains information to restore