Patch 8.1.1044
Problem: No way to check the reference count of objects.
Solution: Add test_refcount(). (Ozaki Kiichi, closes #4124)
Files: runtime/doc/eval.txt, src/evalfunc.c,
src/testdir/test_vimscript.vim
*** ../vim-8.1.1043/runtime/doc/eval.txt 2019-03-17 16:39:01.562006195
+0100
--- runtime/doc/eval.txt 2019-03-23 14:11:43.603170194 +0100
***************
*** 2645,2650 ****
--- 2672,2678 ----
test_null_string() String null value for testing
test_option_not_set({name}) none reset flag indicating option was set
test_override({expr}, {val}) none test with Vim internal overrides
+ test_refcount({expr}) Number get the reference count of {expr}
test_scrollbar({which}, {value}, {dragging})
none scroll in the GUI for testing
test_settime({expr}) none set current time for testing
***************
*** 9532,9537 ****
--- 9590,9600 ----
< The value of "starting" is saved. It is restored by: >
call test_override('starting', 0)
+ test_refcount({expr}) *test_refcount()*
+ Return the reference count of {expr}. When {expr} is of a
+ type that does not have a reference count, returns -1. Only
+ to be used for testing.
+
test_scrollbar({which}, {value}, {dragging}) *test_scrollbar()*
Pretend using scrollbar {which} to move it to position
{value}. {which} can be:
*** ../vim-8.1.1043/src/evalfunc.c 2019-03-22 17:03:01.783689365 +0100
--- src/evalfunc.c 2019-03-23 14:09:39.184057626 +0100
***************
*** 428,433 ****
--- 428,434 ----
static void f_test_feedinput(typval_T *argvars, typval_T *rettv);
static void f_test_option_not_set(typval_T *argvars, typval_T *rettv);
static void f_test_override(typval_T *argvars, typval_T *rettv);
+ static void f_test_refcount(typval_T *argvars, typval_T *rettv);
static void f_test_garbagecollect_now(typval_T *argvars, typval_T *rettv);
static void f_test_ignore_error(typval_T *argvars, typval_T *rettv);
static void f_test_null_blob(typval_T *argvars, typval_T *rettv);
***************
*** 952,958 ****
{"test_feedinput", 1, 1, f_test_feedinput},
{"test_garbagecollect_now", 0, 0, f_test_garbagecollect_now},
{"test_ignore_error", 1, 1, f_test_ignore_error},
! {"test_null_blob", 0, 0, f_test_null_blob},
#ifdef FEAT_JOB_CHANNEL
{"test_null_channel", 0, 0, f_test_null_channel},
#endif
--- 953,959 ----
{"test_feedinput", 1, 1, f_test_feedinput},
{"test_garbagecollect_now", 0, 0, f_test_garbagecollect_now},
{"test_ignore_error", 1, 1, f_test_ignore_error},
! {"test_null_blob", 0, 0, f_test_null_blob},
#ifdef FEAT_JOB_CHANNEL
{"test_null_channel", 0, 0, f_test_null_channel},
#endif
***************
*** 964,970 ****
{"test_null_partial", 0, 0, f_test_null_partial},
{"test_null_string", 0, 0, f_test_null_string},
{"test_option_not_set", 1, 1, f_test_option_not_set},
! {"test_override", 2, 2, f_test_override},
#ifdef FEAT_GUI
{"test_scrollbar", 3, 3, f_test_scrollbar},
#endif
--- 965,972 ----
{"test_null_partial", 0, 0, f_test_null_partial},
{"test_null_string", 0, 0, f_test_null_string},
{"test_option_not_set", 1, 1, f_test_option_not_set},
! {"test_override", 2, 2, f_test_override},
! {"test_refcount", 1, 1, f_test_refcount},
#ifdef FEAT_GUI
{"test_scrollbar", 3, 3, f_test_scrollbar},
#endif
***************
*** 13847,13852 ****
--- 13849,13915 ----
}
/*
+ * "test_refcount({expr})" function
+ */
+ static void
+ f_test_refcount(typval_T *argvars, typval_T *rettv)
+ {
+ int retval = -1;
+
+ switch (argvars[0].v_type)
+ {
+ case VAR_UNKNOWN:
+ case VAR_NUMBER:
+ case VAR_FLOAT:
+ case VAR_SPECIAL:
+ case VAR_STRING:
+ break;
+ case VAR_JOB:
+ #ifdef FEAT_JOB_CHANNEL
+ if (argvars[0].vval.v_job != NULL)
+ retval = argvars[0].vval.v_job->jv_refcount - 1;
+ #endif
+ break;
+ case VAR_CHANNEL:
+ #ifdef FEAT_JOB_CHANNEL
+ if (argvars[0].vval.v_channel != NULL)
+ retval = argvars[0].vval.v_channel->ch_refcount - 1;
+ #endif
+ break;
+ case VAR_FUNC:
+ if (argvars[0].vval.v_string != NULL)
+ {
+ ufunc_T *fp;
+
+ fp = find_func(argvars[0].vval.v_string);
+ if (fp != NULL)
+ retval = fp->uf_refcount;
+ }
+ break;
+ case VAR_PARTIAL:
+ if (argvars[0].vval.v_partial != NULL)
+ retval = argvars[0].vval.v_partial->pt_refcount - 1;
+ break;
+ case VAR_BLOB:
+ if (argvars[0].vval.v_blob != NULL)
+ retval = argvars[0].vval.v_blob->bv_refcount - 1;
+ break;
+ case VAR_LIST:
+ if (argvars[0].vval.v_list != NULL)
+ retval = argvars[0].vval.v_list->lv_refcount - 1;
+ break;
+ case VAR_DICT:
+ if (argvars[0].vval.v_dict != NULL)
+ retval = argvars[0].vval.v_dict->dv_refcount - 1;
+ break;
+ }
+
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = retval;
+
+ }
+
+ /*
* "test_garbagecollect_now()" function
*/
static void
*** ../vim-8.1.1043/src/testdir/test_vimscript.vim 2019-03-02
11:57:06.159125888 +0100
--- src/testdir/test_vimscript.vim 2019-03-23 14:21:08.991161181 +0100
***************
*** 1556,1561 ****
--- 1556,1670 ----
let @/ = ''
endfunc
+ func Test_refcount()
+ " Immediate values
+ call assert_equal(-1, test_refcount(1))
+ call assert_equal(-1, test_refcount('s'))
+ call assert_equal(-1, test_refcount(v:true))
+ call assert_equal(0, test_refcount([]))
+ call assert_equal(0, test_refcount({}))
+ call assert_equal(0, test_refcount(0zff))
+ call assert_equal(0, test_refcount({-> line('.')}))
+ if has('float')
+ call assert_equal(-1, test_refcount(0.1))
+ endif
+ if has('job')
+ call assert_equal(0, test_refcount(job_start([&shell, &shellcmdflag,
'echo .'])))
+ endif
+
+ " No refcount types
+ let x = 1
+ call assert_equal(-1, test_refcount(x))
+ let x = 's'
+ call assert_equal(-1, test_refcount(x))
+ let x = v:true
+ call assert_equal(-1, test_refcount(x))
+ if has('float')
+ let x = 0.1
+ call assert_equal(-1, test_refcount(x))
+ endif
+
+ " Check refcount
+ let x = []
+ call assert_equal(1, test_refcount(x))
+
+ let x = {}
+ call assert_equal(1, test_refcount(x))
+
+ let x = 0zff
+ call assert_equal(1, test_refcount(x))
+
+ let X = {-> line('.')}
+ call assert_equal(1, test_refcount(X))
+ let Y = X
+ call assert_equal(2, test_refcount(X))
+
+ if has('job')
+ let job = job_start([&shell, &shellcmdflag, 'echo .'])
+ call assert_equal(1, test_refcount(job))
+ call assert_equal(1, test_refcount(job_getchannel(job)))
+ call assert_equal(1, test_refcount(job))
+ endif
+
+ " Function arguments, copying and unassigning
+ func ExprCheck(x, i)
+ let i = a:i + 1
+ call assert_equal(i, test_refcount(a:x))
+ let Y = a:x
+ call assert_equal(i + 1, test_refcount(a:x))
+ call assert_equal(test_refcount(a:x), test_refcount(Y))
+ let Y = 0
+ call assert_equal(i, test_refcount(a:x))
+ endfunc
+ call ExprCheck([], 0)
+ call ExprCheck({}, 0)
+ call ExprCheck(0zff, 0)
+ call ExprCheck({-> line('.')}, 0)
+ if has('job')
+ call ExprCheck(job, 1)
+ call ExprCheck(job_getchannel(job), 1)
+ call job_stop(job)
+ endif
+ delfunc ExprCheck
+
+ " Regarding function
+ func Func(x) abort
+ call assert_equal(2, test_refcount(function('Func')))
+ call assert_equal(0, test_refcount(funcref('Func')))
+ endfunc
+ call assert_equal(1, test_refcount(function('Func')))
+ call assert_equal(0, test_refcount(function('Func', [1])))
+ call assert_equal(0, test_refcount(funcref('Func')))
+ call assert_equal(0, test_refcount(funcref('Func', [1])))
+ let X = function('Func')
+ let Y = X
+ call assert_equal(1, test_refcount(X))
+ let X = function('Func', [1])
+ let Y = X
+ call assert_equal(2, test_refcount(X))
+ let X = funcref('Func')
+ let Y = X
+ call assert_equal(2, test_refcount(X))
+ let X = funcref('Func', [1])
+ let Y = X
+ call assert_equal(2, test_refcount(X))
+ unlet X
+ unlet Y
+ call Func(1)
+ delfunc Func
+
+ " Function with dict
+ func DictFunc() dict
+ call assert_equal(3, test_refcount(self))
+ endfunc
+ let d = {'Func': function('DictFunc')}
+ call assert_equal(1, test_refcount(d))
+ call assert_equal(0, test_refcount(d.Func))
+ call d.Func()
+ unlet d
+ delfunc DictFunc
+ endfunc
+
"-------------------------------------------------------------------------------
" Modelines {{{1
" vim: ts=8 sw=4 tw=80 fdm=marker
*** ../vim-8.1.1043/src/version.c 2019-03-23 13:56:30.189804811 +0100
--- src/version.c 2019-03-23 14:10:54.583519509 +0100
***************
*** 777,778 ****
--- 777,780 ----
{ /* Add new patch number below this line */
+ /**/
+ 1044,
/**/
--
A meeting is an event at which the minutes are kept and the hours are lost.
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
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 [email protected].
For more options, visit https://groups.google.com/d/optout.