# HG changeset patch # User vimboss # Date 1190736000 0 # Node ID b63792dadc23ed5ff4e0e9e8c7acc24d9c61e779 # Parent b00bc2bf23eb62a1883318c6565d3fe0d1b4e30e updated for version 7.1-120 diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 7.1. Last change: 2007 Jul 25 +*eval.txt* For Vim version 7.1. Last change: 2007 Sep 25 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1603,7 +1603,7 @@ foldtext( ) String line displayed for 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() none free memory, breaking cyclic references +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}]) @@ -2673,7 +2673,7 @@ function({name}) *function()* *E700* {name} can be a user defined function or an internal function. -garbagecollect() *garbagecollect()* +garbagecollect([at_exit]) *garbagecollect()* Cleanup unused |Lists| and |Dictionaries| that have circular references. There is hardly ever a need to invoke this function, as it is automatically done when Vim runs out of @@ -2683,6 +2683,9 @@ garbagecollect() *garbagecollect()* This is useful if you have deleted a very big |List| and/or |Dictionary| with circular references in a script that runs for a long time. + 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. get({list}, {idx} [, {default}]) *get()* Get item {idx} from |List| {list}. When this item is not diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -6128,6 +6128,7 @@ garbage_collect() /* Only do this once. */ want_garbage_collect = FALSE; may_garbage_collect = FALSE; + garbage_collect_at_exit = FALSE; /* * 1. Go through all accessible variables and mark all lists and dicts @@ -7110,7 +7111,7 @@ static struct fst {"foldtextresult", 1, 1, f_foldtextresult}, {"foreground", 0, 0, f_foreground}, {"function", 1, 1, f_function}, - {"garbagecollect", 0, 0, f_garbagecollect}, + {"garbagecollect", 0, 1, f_garbagecollect}, {"get", 2, 3, f_get}, {"getbufline", 2, 3, f_getbufline}, {"getbufvar", 2, 2, f_getbufvar}, @@ -9719,6 +9720,9 @@ f_garbagecollect(argvars, rettv) /* 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; + + if (argvars[0].v_type != VAR_UNKNOWN && get_tv_number(&argvars[0]) == 1) + garbage_collect_at_exit = TRUE; } /* diff --git a/src/globals.h b/src/globals.h --- a/src/globals.h +++ b/src/globals.h @@ -301,13 +301,17 @@ EXTERN except_T *caught_stack INIT(= NUL #endif #ifdef FEAT_EVAL -/* Garbage collection can only take place when we are sure there are no Lists +/* + * Garbage collection can only take place when we are sure there are no Lists * or Dictionaries being used internally. This is flagged with * "may_garbage_collect" when we are at the toplevel. * "want_garbage_collect" is set by the garbagecollect() function, which means - * we do garbage collection before waiting for a char at the toplevel. */ + * we do garbage collection before waiting for a char at the toplevel. + * "garbage_collect_at_exit" indicates garbagecollect(1) was called. + */ EXTERN int may_garbage_collect INIT(= FALSE); EXTERN int want_garbage_collect INIT(= FALSE); +EXTERN int garbage_collect_at_exit INIT(= FALSE); /* ID of script being sourced or was sourced to define the current function. */ EXTERN scid_T current_SID INIT(= 0); diff --git a/src/main.c b/src/main.c --- a/src/main.c +++ b/src/main.c @@ -1334,6 +1334,10 @@ getout(exitval) #ifdef FEAT_CSCOPE cs_end(); #endif +#ifdef FEAT_EVAL + if (garbage_collect_at_exit) + garbage_collect(); +#endif mch_exit(exitval); } diff --git a/src/testdir/Makefile b/src/testdir/Makefile --- a/src/testdir/Makefile +++ b/src/testdir/Makefile @@ -6,7 +6,7 @@ VIMPROG = ../vim # Uncomment this line for using valgrind. # The output goes into a file "valgrind.$PID" (sorry, no test number). -# VALGRIND = valgrind --tool=memcheck --num-callers=15 --logfile=valgrind +# VALGRIND = valgrind --tool=memcheck --leak-check=yes --num-callers=15 --logfile=valgrind SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \ test7.out test8.out test9.out test10.out test11.out \ @@ -39,7 +39,7 @@ gui: nolog $(SCRIPTS) $(SCRIPTS_GUI) $(SCRIPTS) $(SCRIPTS_GUI): $(VIMPROG) clean: - -rm -rf *.out *.failed *.rej *.orig test.log tiny.vim small.vim mbyte.vim test.ok X* viminfo + -rm -rf *.out *.failed *.rej *.orig test.log tiny.vim small.vim mbyte.vim test.ok X* valgrind.pid* viminfo test1.out: test1.in -rm -f $*.failed tiny.vim small.vim mbyte.vim test.ok X* viminfo @@ -66,5 +66,9 @@ test1.out: test1.in fi" -rm -rf X* test.ok viminfo +test49.out: test49.vim + +test60.out: test60.vim + nolog: -echo Test results: >test.log diff --git a/src/testdir/test14.in b/src/testdir/test14.in --- a/src/testdir/test14.in +++ b/src/testdir/test14.in @@ -18,6 +18,7 @@ vaBiBD:?Bug?,/Piece/-2w! test.out : let tt = "o\65\x42\o103 \33a\xfg\o78\" :endif :exe "normal " . tt +:unlet tt :.w >>test.out :set vb /^Piece diff --git a/src/testdir/test26.in b/src/testdir/test26.in --- a/src/testdir/test26.in +++ b/src/testdir/test26.in @@ -37,6 +37,7 @@ mt:let i = 0 : endif : endif :endwhile +:unlet i j :'t,$w! test.out :qa! ENDTEST diff --git a/src/testdir/test34.in b/src/testdir/test34.in --- a/src/testdir/test34.in +++ b/src/testdir/test34.in @@ -52,7 +52,15 @@ XX+-XX ---*--- (one (two -[(one again:$-5,$wq! test.out +[(one again:$-5,$w! test.out +:delfunc Table +:delfunc Compute +:delfunc Expr1 +:delfunc Expr2 +:delfunc ListItem +:delfunc ListReset +:unlet retval counter +:q! ENDTEST here diff --git a/src/testdir/test45.in b/src/testdir/test45.in --- a/src/testdir/test45.in +++ b/src/testdir/test45.in @@ -55,6 +55,7 @@ endfun /kk$ :call append("$", foldlevel(".")) :/^last/+1,$w! test.out +:delfun Flvl :qa! ENDTEST diff --git a/src/testdir/test47.in b/src/testdir/test47.in --- a/src/testdir/test47.in +++ b/src/testdir/test47.in @@ -34,6 +34,7 @@ j:let three = three . "-" . winline() :call append("$", two) :call append("$", three) :$-2,$w! test.out +:unlet one two three :qa! ENDTEST diff --git a/src/testdir/test49.in b/src/testdir/test49.in --- a/src/testdir/test49.in +++ b/src/testdir/test49.in @@ -1,13 +1,29 @@ This is a test of the script language. If after adding a new test, the test output doesn't appear properly in -test49.failed, try to add one ore more "G"s at the line before ENDTEST. +test49.failed, try to add one ore more "G"s at the line ending in "test.out" STARTTEST :so small.vim :se nocp nomore viminfo+=nviminfo :so test49.vim -GGGGGGGGGG"rp:.-,$wq! test.out +GGGGGGGGGGGGGG"rp:.-,$w! test.out +:" +:" make valgrind happy +:redir => funclist +:silent func +:redir END +:for line in split(funclist, "\n") +: let name = matchstr(line, 'function \zs[A-Z]\w*\ze(') +: if name != '' +: exe "delfunc " . name +: endif +:endfor +:for v in keys(g:) +: silent! exe "unlet " . v +:endfor +:unlet v +:qa! ENDTEST Results of test49.vim: diff --git a/src/testdir/test55.in b/src/testdir/test55.in --- a/src/testdir/test55.in +++ b/src/testdir/test55.in @@ -345,6 +345,10 @@ let l = [0, 1, 2, 3] :endfun :call Test(1, 2, [3, 4], {5: 6}) " This may take a while :" +:delfunc Test +:unlet dict +:call garbagecollect(1) +:" :/^start:/,$wq! test.out ENDTEST diff --git a/src/testdir/test56.in b/src/testdir/test56.in --- a/src/testdir/test56.in +++ b/src/testdir/test56.in @@ -17,5 +17,5 @@ endfun fun s:DoNothing() call append(line('$'), "nothing line") endfun -nnoremap _x :call DoNothing()call DoLast() +nnoremap _x :call DoNothing()call DoLast()delfunc DoNothingdelfunc DoLast end: diff --git a/src/testdir/test58.in b/src/testdir/test58.in --- a/src/testdir/test58.in +++ b/src/testdir/test58.in @@ -86,6 +86,7 @@ gg:/^addstart/+1,/^addend/-1w! Xtest.lat :$put =str `m]s:let [str, a] = spellbadword() :$put =str +:unlet str a :" :" Postponed prefixes :call TestOne('2', '1') @@ -100,6 +101,10 @@ gg:/^addstart/+1,/^addend/-1w! Xtest.lat :" NOSLITSUGS :call TestOne('8', '8') :" +:" clean up for valgrind +:delfunc TestOne +:set spl= enc=latin1 +:" gg:/^test output:/,$wq! test.out ENDTEST diff --git a/src/testdir/test59.in b/src/testdir/test59.in --- a/src/testdir/test59.in +++ b/src/testdir/test59.in @@ -90,6 +90,7 @@ gg:/^addstart/+1,/^addend/-1w! Xtest.utf :$put =str `m]s:let [str, a] = spellbadword() :$put =str +:unlet str a :" :" Postponed prefixes :call TestOne('2', '1') @@ -101,6 +102,10 @@ gg:/^addstart/+1,/^addend/-1w! Xtest.utf :call TestOne('6', '6') :call TestOne('7', '7') :" +:" clean up for valgrind +:delfunc TestOne +:set spl= enc=latin1 +:" gg:/^test output:/,$wq! test.out ENDTEST diff --git a/src/testdir/test60.in b/src/testdir/test60.in --- a/src/testdir/test60.in +++ b/src/testdir/test60.in @@ -569,6 +569,9 @@ endfunction redir END endfunction :call TestExists() +:delfunc TestExists +:delfunc RunTest +:delfunc TestFuncArg :edit! test.out :set ff=unix :w diff --git a/src/testdir/test60.vim b/src/testdir/test60.vim --- a/src/testdir/test60.vim +++ b/src/testdir/test60.vim @@ -94,4 +94,5 @@ if !exists('*s:my_script_func') else echo "FAILED" endif +unlet str diff --git a/src/testdir/test62.in b/src/testdir/test62.in --- a/src/testdir/test62.in +++ b/src/testdir/test62.in @@ -7,6 +7,7 @@ STARTTEST :let nr = tabpagenr() :q :call append(line('$'), 'tab page ' . nr) +:unlet nr :" :" Open three tab pages and use ":tabdo" :0tabnew @@ -23,6 +24,7 @@ STARTTEST :q! :call append(line('$'), line1) :call append(line('$'), line2) +:unlet line1 line2 :" :" :/^Results/,$w! test.out diff --git a/src/testdir/test63.in b/src/testdir/test63.in --- a/src/testdir/test63.in +++ b/src/testdir/test63.in @@ -60,7 +60,7 @@ STARTTEST :else : let @r .= "FAILED\n" :endif -:" --- Check that "matchdelete()" returns 0 if succesfull and otherwise -1. +:" --- Check that "matchdelete()" returns 0 if successful and otherwise -1. :let @r .= "*** Test 6: " :let m = matchadd("MyGroup1", "TODO") :let r1 = matchdelete(m) @@ -117,7 +117,7 @@ STARTTEST :" --- Check that "setmatches()" will not add two matches with the same ID. The :" --- expected behaviour (for now) is to add the first match but not the :" --- second and to return 0 (even though it is a matter of debate whether -:" --- this can be considered succesfull behaviour). +:" --- this can be considered successful behaviour). :let @r .= "*** Test 9: " :let r1 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}, {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 10, 'id': 1}]) :if getmatches() == [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}] && r1 == 0 @@ -127,7 +127,7 @@ STARTTEST :endif :call clearmatches() :unlet r1 -:" --- Check that "setmatches()" returns 0 if succesfull and otherwise -1. +:" --- Check that "setmatches()" returns 0 if successful and otherwise -1. :" --- (A range of valid and invalid input values are tried out to generate the :" --- return values.) :let @r .= "*** Test 10: " diff --git a/src/testdir/test64.in b/src/testdir/test64.in --- a/src/testdir/test64.in +++ b/src/testdir/test64.in @@ -44,8 +44,10 @@ STARTTEST : $put ='ERROR: pat: \"' . t[0] . '\", text: \"' . t[1] . '\", submatch ' . i . ': \"' . l[i] . '\", expected: \"' . e . '\"' : endif : endfor +: unlet i : endif :endfor +:unlet t tl e l :/^Results/,$wq! test.out ENDTEST diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -667,6 +667,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 120, +/**/ 119, /**/ 118,