# HG changeset patch # User Bram Moolenaar # Date 1275218781 -7200 # Node ID 2e6906bbc5f4c147830bfac0873f1aa6d8e3a31b # Parent aa6412cab544f8e725dd16bdd78f15ccd70c45e6 A few more fixes for undo file. Split test in two parts so that it doesn't fail with tiny features. diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -1093,6 +1093,7 @@ Vim 7.3: Use register_shell_extension()? (George Reilly, 2010 May 26) Ron's version: http://dev.ronware.org/p/vim/finfo?name=gvim.nsi - Persistent undo bugs / fixes: + - check for sizeof(time_t) results in compiler warning in misc2.c - Memory leak reproduced by Dominique Pelle, 2010 May 28. - When there is no undo info (undolevels negative), delete the undo file. - Need to check all values for evil manipulation. diff --git a/src/auto/configure b/src/auto/configure --- a/src/auto/configure +++ b/src/auto/configure @@ -11238,6 +11238,49 @@ cat >>confdefs.h <<_ACEOF _ACEOF +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of time_t" >&5 +$as_echo_n "checking size of time_t... " >&6; } +if test "${ac_cv_sizeof_time_t+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + as_fn_error "failed to compile test program" "$LINENO" 5 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#if STDC_HEADERS +# include +# include +#endif +#include +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", (int)sizeof(time_t)); + exit(0); +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_sizeof_time_t=`cat conftestval` +else + as_fn_error "failed to determine sizeof(time_t)" "$LINENO" 5 +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_time_t" >&5 +$as_echo "$ac_cv_sizeof_time_t" >&6; } +cat >>confdefs.h <<_ACEOF +#define SIZEOF_TIME_T $ac_cv_sizeof_time_t +_ACEOF + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking uint32_t is 32 bits" >&5 $as_echo_n "checking uint32_t is 32 bits... " >&6; } if test "$cross_compiling" = yes; then : diff --git a/src/config.h.in b/src/config.h.in --- a/src/config.h.in +++ b/src/config.h.in @@ -39,6 +39,9 @@ /* Defined to the size of an int */ #undef SIZEOF_INT +/* Defined to the size of time_t */ +#undef SIZEOF_TIME_T + /* Define when wchar_t is only 2 bytes. */ #undef SMALL_WCHAR_T diff --git a/src/configure.in b/src/configure.in --- a/src/configure.in +++ b/src/configure.in @@ -2988,6 +2988,29 @@ main() AC_MSG_RESULT($ac_cv_sizeof_int) AC_DEFINE_UNQUOTED(SIZEOF_INT, $ac_cv_sizeof_int) +dnl Figure out sizeof(time_t) so that it can be used in #ifdef. +AC_MSG_CHECKING(size of time_t) +AC_CACHE_VAL(ac_cv_sizeof_time_t, + [AC_TRY_RUN([ +#include +#if STDC_HEADERS +# include +# include +#endif +#include +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", (int)sizeof(time_t)); + exit(0); +}], + ac_cv_sizeof_time_t=`cat conftestval`, + AC_MSG_ERROR([failed to determine sizeof(time_t)]), + AC_MSG_ERROR([failed to compile test program]))]) +AC_MSG_RESULT($ac_cv_sizeof_time_t) +AC_DEFINE_UNQUOTED(SIZEOF_TIME_T, $ac_cv_sizeof_time_t) + dnl Make sure that uint32_t is really 32 bits unsigned. AC_MSG_CHECKING([uint32_t is 32 bits]) AC_TRY_RUN([ diff --git a/src/misc2.c b/src/misc2.c --- a/src/misc2.c +++ b/src/misc2.c @@ -6260,9 +6260,10 @@ put_time(fd, the_time) /* time_t can be up to 8 bytes in size, more than long_u, thus we * can't use put_bytes() here. * Another problem is that ">>" may do an arithmetic shift that keeps the - * sign. A cast to long_u may truncate if time_t is 8 bytes. So only use - * a cast when it is 4 bytes, it's safe to assume that long_u is 4 bytes - * or more and when using 8 bytes the top bit won't be set. */ + * sign. This happens for large values of wtime. A cast to long_u may + * truncate if time_t is 8 bytes. So only use a cast when it is 4 bytes, + * it's safe to assume that long_u is 4 bytes or more and when using 8 + * bytes the top bit won't be set. */ for (i = 7; i >= 0; --i) { if (i + 1 > (int)sizeof(time_t)) @@ -6270,11 +6271,11 @@ put_time(fd, the_time) putc(0, fd); else { - /* use "i" in condition to avoid compiler warning */ - if (i >= 0 && sizeof(time_t) > 4) - c = wtime >> (i * 8); - else - c = (long_u)wtime >> (i * 8); +#if defined(SIZEOF_TIME_T) && SIZEOF_TIME_T > 4 + c = wtime >> (i * 8); +#else + c = (long_u)wtime >> (i * 8); +#endif putc(c, fd); } } diff --git a/src/testdir/Make_amiga.mak b/src/testdir/Make_amiga.mak --- a/src/testdir/Make_amiga.mak +++ b/src/testdir/Make_amiga.mak @@ -26,7 +26,8 @@ SCRIPTS = test1.out test3.out test4.out test48.out test51.out test53.out test54.out test55.out \ test56.out test57.out test58.out test59.out test60.out \ test61.out test62.out test63.out test64.out test65.out \ - test66.out test67.out test68.out test69.out + test66.out test67.out test68.out test69.out test70.out \ + test71.out test72.out .SUFFIXES: .in .out @@ -115,3 +116,6 @@ test66.out: test66.in test67.out: test67.in test68.out: test68.in test69.out: test69.in +test70.out: test70.in +test71.out: test71.in +test72.out: test72.in diff --git a/src/testdir/Make_dos.mak b/src/testdir/Make_dos.mak --- a/src/testdir/Make_dos.mak +++ b/src/testdir/Make_dos.mak @@ -27,7 +27,7 @@ SCRIPTS = test3.out test4.out test5.out test30.out test31.out test32.out test33.out test34.out \ test37.out test38.out test39.out test40.out test41.out \ test42.out test52.out test65.out test66.out test67.out \ - test68.out test69.out test71.out + test68.out test69.out test71.out test72.out SCRIPTS32 = test50.out test70.out diff --git a/src/testdir/Make_ming.mak b/src/testdir/Make_ming.mak --- a/src/testdir/Make_ming.mak +++ b/src/testdir/Make_ming.mak @@ -46,7 +46,7 @@ SCRIPTS = test3.out test4.out test5.out test30.out test31.out test32.out test33.out test34.out \ test37.out test38.out test39.out test40.out test41.out \ test42.out test52.out test65.out test66.out test67.out \ - test68.out test69.out test71.out + test68.out test69.out test71.out test72.out SCRIPTS32 = test50.out test70.out diff --git a/src/testdir/Make_os2.mak b/src/testdir/Make_os2.mak --- a/src/testdir/Make_os2.mak +++ b/src/testdir/Make_os2.mak @@ -26,7 +26,8 @@ SCRIPTS = test1.out test3.out test4.out test48.out test51.out test53.out test54.out test55.out \ test56.out test57.out test58.out test59.out test60.out \ test61.out test62.out test63.out test64.out test65.out \ - test66.out test67.out test68.out test69.out + test66.out test67.out test68.out test69.out test70.out \ + test71.out test72.out .SUFFIXES: .in .out diff --git a/src/testdir/Make_vms.mms b/src/testdir/Make_vms.mms --- a/src/testdir/Make_vms.mms +++ b/src/testdir/Make_vms.mms @@ -69,7 +69,8 @@ SCRIPT = test1.out test2.out test3.out test48.out test51.out test53.out test54.out test55.out \ test56.out test57.out test60.out \ test61.out test62.out test63.out test64.out test65.out \ - test66.out test67.out test68.out test69.out + test66.out test67.out test68.out test69.out test70.out \ + test71.out test72.out .IFDEF WANT_GUI SCRIPT_GUI = test16.out diff --git a/src/testdir/Makefile b/src/testdir/Makefile --- a/src/testdir/Makefile +++ b/src/testdir/Makefile @@ -23,7 +23,7 @@ SCRIPTS = test1.out test2.out test3.out test54.out test55.out test56.out test57.out test58.out \ test59.out test60.out test61.out test62.out test63.out \ test64.out test65.out test66.out test67.out test68.out \ - test69.out test70.out test71.out + test69.out test70.out test71.out test72.out SCRIPTS_GUI = test16.out diff --git a/src/testdir/test61.in b/src/testdir/test61.in --- a/src/testdir/test61.in +++ b/src/testdir/test61.in @@ -50,53 +50,6 @@ obbbbu:.w >>test.out obbbb:set ul=100 :undojoin occccu:.w >>test.out -:" -:" Test 'undofile': first a simple one-line change. -:set nocp ul=100 undofile -:e! Xtestfile -ggdGithis is one line:set ul=100 -:s/one/ONE/ -:set ul=100 -:w -:bwipe! -:e Xtestfile -u:.w >>test.out -:" -:" Test 'undofile', change in original file fails check -:set noundofile -:e! Xtestfile -:s/line/Line/ -:w -:set undofile -:bwipe! -:e Xtestfile -u:.w >>test.out -:" -:" Test 'undofile', add 10 lines, delete 6 lines, undo 3 -:set undofile -ggdGione -two -three -four -five -six -seven -eight -nine -ten:set ul=100 -3Gdd:set ul=100 -dd:set ul=100 -dd:set ul=100 -dd:set ul=100 -dd:set ul=100 -dd:set ul=100 -:w -:bwipe! -:e Xtestfile -uuu:w >>test.out -:" -:" Rename the undo file so that it gets cleaned up. -:call rename(".Xtestfile.un~", "Xtestundo") :qa! ENDTEST diff --git a/src/testdir/test61.ok b/src/testdir/test61.ok --- a/src/testdir/test61.ok +++ b/src/testdir/test61.ok @@ -22,12 +22,3 @@ 123456 123456abc aaaa aaaa -this is one line -this is ONE Line -one -two -six -seven -eight -nine -ten diff --git a/src/testdir/test72.in b/src/testdir/test72.in new file mode 100644 --- /dev/null +++ b/src/testdir/test72.in @@ -0,0 +1,60 @@ +Tests for undo file. +Since this script is sourced we need to explicitly break changes up in +undo-able pieces. Do that by setting 'undolevels'. + +STARTTEST +:so small.vim +:" +:" Test 'undofile': first a simple one-line change. +:set nocp ul=100 undofile +:e! Xtestfile +ggdGithis is one line:set ul=100 +:s/one/ONE/ +:set ul=100 +:w +:bwipe! +:e Xtestfile +u:.w! test.out +:" +:" Test 'undofile', change in original file fails check +:set noundofile +:e! Xtestfile +:s/line/Line/ +:w +:set undofile +:bwipe! +:e Xtestfile +u:.w >>test.out +:" +:" Test 'undofile', add 10 lines, delete 6 lines, undo 3 +:set undofile +ggdGione +two +three +four +five +six +seven +eight +nine +ten:set ul=100 +3Gdd:set ul=100 +dd:set ul=100 +dd:set ul=100 +dd:set ul=100 +dd:set ul=100 +dd:set ul=100 +:w +:bwipe! +:e Xtestfile +uuu:w >>test.out +:" +:" Rename the undo file so that it gets cleaned up. +:call rename(".Xtestfile.un~", "Xtestundo") +:qa! +ENDTEST + +1111 ----- +2222 ----- + +123456789 diff --git a/src/testdir/test72.ok b/src/testdir/test72.ok new file mode 100644 --- /dev/null +++ b/src/testdir/test72.ok @@ -0,0 +1,9 @@ +this is one line +this is ONE Line +one +two +six +seven +eight +nine +ten diff --git a/src/undo.c b/src/undo.c --- a/src/undo.c +++ b/src/undo.c @@ -858,6 +858,8 @@ unserialize_uep(fp, error, file_name) } vim_memset(array, 0, sizeof(char_u *) * uep->ue_size); } + else + array = NULL; uep->ue_array = array; for (i = 0; i < uep->ue_size; ++i) @@ -1365,7 +1367,6 @@ u_read_undo(name, hash) if (num_read_uhps >= num_head) { corruption_error("num_head", file_name); - u_free_uhp(uhp); goto error; } @@ -1442,7 +1443,7 @@ u_read_undo(name, hash) * culling was done at undofile write time, and there can be uh_seq * gaps in the uhps. */ - for (i = num_read_uhps - 1; i >= -1; i--) + for (i = num_read_uhps - 1; ; --i) { /* if i == -1, we've hit the leftmost side of the table, so insert * at uhp_table[0]. */