diff --git a/Filelist b/Filelist index fe2e34a8e4..6d8e2e8896 100644 --- a/Filelist +++ b/Filelist @@ -24,6 +24,7 @@ SRC_ALL = \ src/edit.c \ src/eval.c \ src/evalfunc.c \ + src/ex_cmdidxs.h \ src/ex_cmds.c \ src/ex_cmds.h \ src/ex_cmds2.c \ @@ -215,7 +216,7 @@ SRC_UNIX = \ src/config.mk.in \ src/configure \ src/configure.ac \ - src/create_cmdidxs.pl \ + src/create_cmdidxs.vim \ src/gui_at_fs.c \ src/gui_at_sb.c \ src/gui_at_sb.h \ @@ -239,7 +240,7 @@ SRC_UNIX = \ src/link.sh \ src/installman.sh \ src/installml.sh \ - src/mkinstalldirs \ + src/install-sh \ src/os_unix.c \ src/os_unix.h \ src/os_unixx.h \ diff --git a/src/Makefile b/src/Makefile index 14eefdb7e6..b1dffd10a9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -207,7 +207,7 @@ #SunOS 4.1.x +X11 -GUI 5.1b (J) Bram Moolenaar #SunOS 4.1.3_U1 (sun4c) gcc +X11 +GUI Athena 5.0w (J) Darren Hiebert #SUPER-UX 6.2 (NEC SX-4) cc +X11R6 Motif,Athena4.6b (P) Lennart Schultz -#Tandem/NSK (c) Matthew Woehlke +#Tandem/NSK (c) Matthew Woehlke #Unisys 6035 cc +X11 Motif 5.3 (8) Glauber Ribeiro #ESIX V4.2 cc +X11 6.0 (a) Reinhard Wobst #Mac OS X 10.[23] gcc Carbon 6.2 (x) Bram Moolenaar @@ -403,6 +403,7 @@ CClink = $(CC) # First one is for static linking, second one for dynamic loading. # Use --with-luajit if you want to use LuaJIT instead of Lua. # Set PATH environment variable to find lua or luajit executable. +# This requires at least "normal" features, "tiny" and "small" don't work. #CONF_OPT_LUA = --enable-luainterp #CONF_OPT_LUA = --enable-luainterp=dynamic #CONF_OPT_LUA = --enable-luainterp --with-luajit @@ -429,16 +430,15 @@ CClink = $(CC) # the next line. # When you get an error for a missing "perl.exp" file, try creating an empty # one: "touch perl.exp". -# This requires at least "small" features, "tiny" doesn't work. +# This requires at least "normal" features, "tiny" and "small" don't work. #CONF_OPT_PERL = --enable-perlinterp #CONF_OPT_PERL = --enable-perlinterp=dynamic # PYTHON -# Uncomment this when you want to include the Python interface. -# Requires small features or better, fails with tiny features. +# Uncomment lines here when you want to include the Python interface. +# This requires at least "normal" features, "tiny" and "small" don't work. # NOTE: This may cause threading to be enabled, which has side effects (such # as using different libraries and debugging becomes more difficult). -# NOTE: Using this together with Perl may cause a crash in initialization. # For Python3 support make a symbolic link in /usr/local/bin: # ln -s python3 python3.1 # If both python2.x and python3.x are enabled then the linking will be via @@ -454,6 +454,7 @@ CClink = $(CC) # Uncomment this when you want to include the Ruby interface. # First one for static linking, second one for loading when used. # Note: you need the development package (e.g., ruby1.9.1-dev on Ubuntu). +# This requires at least "normal" features, "tiny" and "small" don't work. #CONF_OPT_RUBY = --enable-rubyinterp #CONF_OPT_RUBY = --enable-rubyinterp=dynamic #CONF_OPT_RUBY = --enable-rubyinterp --with-ruby-command=ruby1.9.1 @@ -617,7 +618,7 @@ AUTOCONF = autoconf #PURIFY = purify # VALGRIND - remove the # to use valgrind for memory leaks and access errors. -# Used for the unittest targets. +# Used for the unittest targets. # VALGRIND = valgrind --tool=memcheck --leak-check=yes --num-callers=25 --log-file=valgrind.$@ # NBDEBUG - debugging the netbeans interface. @@ -649,15 +650,15 @@ LINT_OPTIONS = -beprxzF # coverage information. (provided by Yegappan Lakshmanan) # 1. make clean, run configure and build Vim as usual. # 2. Generate the baseline code coverage information: -# $ lcov -c -i -b . -d objects -o objects/coverage_base.info +# $ lcov -c -i -b . -d objects -o objects/coverage_base.info # 3. Run "make test" to run the unit tests. The code coverage information will # be generated in the src/objects directory. # 4. Generate the code coverage information from the tests: -# $ lcov -c -b . -d objects/ -o objects/coverage_test.info +# $ lcov -c -b . -d objects/ -o objects/coverage_test.info # 5. Combine the baseline and test code coverage data: -# $ lcov -a objects/coverage_base.info -a objects/coverage_test.info -o objects/coverage_total.info +# $ lcov -a objects/coverage_base.info -a objects/coverage_test.info -o objects/coverage_total.info # 6. Process the test coverage data and generate a report in html: -# $ genhtml objects/coverage_total.info -o objects +# $ genhtml objects/coverage_total.info -o objects # 7. Open the objects/index.html file in a web browser to view the coverage # information. # @@ -1424,6 +1425,11 @@ PROTO_FLAGS = -d -E"$(CPP)" $(NO_ATTR) SHELL = /bin/sh +# We would normally use "mkdir -p" but it doesn't work properly everywhere. +# Using AC_PROG_MKDIR_P in configure.ac has a problem with the "auto" +# directory. Always use the install-sh script, it's slower but reliable. +MKDIR_P = $(SHELL) install-sh -c -d + .SUFFIXES: .SUFFIXES: .c .o .pro @@ -1901,20 +1907,12 @@ autoconf: -rm -rf autom4te.cache -rm -f auto/config.status auto/config.cache -# Run Perl to generate the Ex command lookup table. This only needs to be run -# when a command name has been added or changed. -# NOTE: Only works when perl and vim executables are available +# Run vim script to generate the Ex command lookup table. +# This only needs to be run when a command name has been added or changed. +# If this fails because you don't have Vim yet, first build and install Vim +# without changes. cmdidxs: ex_cmds.h - if test X`perl -e "print 123"` = "X123"; then \ - vim ex_docmd.c -c '/Beginning.*create_cmdidxs/,/End.*create_cmdidxs/! perl create_cmdidxs.pl' -c wq; \ - else \ - echo Cannot run Perl; \ - fi - -# Re-execute this Makefile to include the new auto/config.mk produced by -# configure Only used when typing "make" with a fresh auto/config.mk. -myself: - $(MAKE) -f Makefile all + vim -u NONE -i NONE -X -S create_cmdidxs.vim # The normal command to compile a .c file to its .o file. @@ -2583,7 +2581,7 @@ DESKTOPPATH = $(DESTDIR)$(DATADIR)/applications KDEPATH = $(HOME)/.kde/share/icons install-icons: if test -n "$(DESTDIR)"; then \ - $(SHELL) ./mkinstalldirs $(ICON48PATH) $(ICON32PATH) \ + $(MKDIR_P) $(ICON48PATH) $(ICON32PATH) \ $(ICON16PATH) $(DESKTOPPATH); \ fi @@ -2624,7 +2622,7 @@ $(DESTDIR)$(exec_prefix) $(DEST_BIN) \ $(DEST_LANG) $(DEST_KMAP) $(DEST_COMP) $(DEST_MACRO) \ $(DEST_PACK) $(DEST_TOOLS) $(DEST_TUTOR) $(DEST_SPELL) \ $(DEST_AUTO) $(DEST_AUTO)/xml $(DEST_PLUG): - -$(SHELL) ./mkinstalldirs $@ + $(MKDIR_P) $@ -chmod $(DIRMOD) $@ # create links from various names to vim. This is only done when the links @@ -2787,7 +2785,8 @@ uninstall_runtime: # Clean up all the files that have been produced, except configure's. # We support common typing mistakes for Juergen! :-) clean celan: testclean macvimclean - -rm -f *.o objects/* core $(VIMTARGET).core $(VIMTARGET) vim xxd/*.o + -rm -f *.o core $(VIMTARGET).core $(VIMTARGET) vim xxd/*.o + -rm -rf objects -rm -f $(TOOLS) auto/osdef.h auto/pathdef.c auto/if_perl.c auto/gui_gtk_gresources.c auto/gui_gtk_gresources.h -rm -f conftest* *~ auto/link.sed -rm -f testdir/opt_test.vim @@ -2804,25 +2803,25 @@ clean celan: testclean macvimclean SHADOWDIR = shadow shadow: runtime pixmaps - mkdir $(SHADOWDIR) - cd $(SHADOWDIR); ln -s ../*.[chm] ../*.in ../*.sh ../*.xs ../*.xbm ../gui_gtk_res.xml ../toolcheck ../proto ../vimtutor ../gvimtutor ../mkinstalldirs . + $(MKDIR_P) $(SHADOWDIR) + cd $(SHADOWDIR); ln -s ../*.[chm] ../*.in ../*.sh ../*.xs ../*.xbm ../gui_gtk_res.xml ../toolcheck ../proto ../vimtutor ../gvimtutor ../install-sh . mkdir $(SHADOWDIR)/auto cd $(SHADOWDIR)/auto; ln -s ../../auto/configure . - mkdir $(SHADOWDIR)/po + $(MKDIR_P) $(SHADOWDIR)/po cd $(SHADOWDIR)/po; ln -s ../../po/*.po ../../po/*.mak ../../po/*.vim ../../po/Makefile . cd $(SHADOWDIR); rm -f auto/link.sed cp Makefile configure $(SHADOWDIR) rm -f $(SHADOWDIR)/auto/config.mk $(SHADOWDIR)/config.mk.dist cp config.mk.dist $(SHADOWDIR)/auto/config.mk cp config.mk.dist $(SHADOWDIR) - mkdir $(SHADOWDIR)/xxd + $(MKDIR_P) $(SHADOWDIR)/xxd cd $(SHADOWDIR)/xxd; ln -s ../../xxd/*.[ch] ../../xxd/Make* . if test -d $(RSRC_DIR); then \ cd $(SHADOWDIR); \ ln -s ../infplist.xml .; \ ln -s ../$(RSRC_DIR) ../os_mac.rsr.hqx ../dehqx.py .; \ fi - mkdir $(SHADOWDIR)/testdir + $(MKDIR_P) $(SHADOWDIR)/testdir cd $(SHADOWDIR)/testdir; ln -s ../../testdir/Makefile \ ../../testdir/Make_all.mak \ ../../testdir/README.txt \ @@ -2959,7 +2958,7 @@ auto/gui_gtk_gresources.h: gui_gtk_res.xml $(GUI_GTK_RES_INPUTS) objects: objects/.dirstamp objects/.dirstamp: - mkdir -p objects + $(MKDIR_P) objects touch objects/.dirstamp # All object files depend on the objects directory, so that parallel make @@ -3299,8 +3298,7 @@ install_macosx: gui_bundle # Generate the help tags file now, it won't work with "make installruntime". -@srcdir=`pwd`; cd $(HELPSOURCE); $(MAKE) VIMEXE=$$srcdir/$(VIMTARGET) vimtags # Install the runtime files. Recursive! - -mkdir -p $(DESTDIR)$(prefix)/$(RESDIR)/vim/runtime -# -mkdir $(DESTDIR)$(prefix)/$(APPDIR)/bin + $(MKDIR_P) $(DESTDIR)$(prefix)/$(RESDIR)/vim/runtime srcdir=`pwd`; $(MAKE) -f Makefile installruntime \ VIMEXE=$$srcdir/$(VIMTARGET) \ prefix=$(DESTDIR)$(prefix)/$(RESDIR)$(VIMDIR) \ @@ -3318,16 +3316,16 @@ gui_bundle: $(RESDIR) bundle-dir bundle-executable bundle-info bundle-resource \ bundle-language $(RESDIR): - mkdir -p $@ + $(MKDIR_P) $@ bundle-dir: $(APPDIR)/Contents $(VIMTARGET) # Make a link to the runtime directory, so that we can try out the executable # without installing it. - mkdir -p $(RESDIR)/vim + $(MKDIR_P) $(RESDIR)/vim -ln -s `pwd`/../runtime $(RESDIR)/vim bundle-executable: $(VIMTARGET) - mkdir -p $(APPDIR)/Contents/MacOS + $(MKDIR_P) $(APPDIR)/Contents/MacOS cp $(VIMTARGET) $(APPDIR)/Contents/MacOS/$(VIMTARGET) bundle-info: bundle-dir @@ -3358,8 +3356,8 @@ bundle-rsrc: os_mac.rsr.hqx bundle-language: bundle-dir $(APPDIR)/Contents: - -$(SHELL) ./mkinstalldirs $(APPDIR)/Contents/MacOS - -$(SHELL) ./mkinstalldirs $(RESDIR)/English.lproj + $(MKDIR_P) $(APPDIR)/Contents/MacOS + $(MKDIR_P) $(RESDIR)/English.lproj ############################################################################## diff --git a/src/auto/configure b/src/auto/configure index 9a32578b58..6531f1fc56 100755 --- a/src/auto/configure +++ b/src/auto/configure @@ -3456,7 +3456,7 @@ ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu - ac_ext=c + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' @@ -3733,7 +3733,7 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | fi rm -f conftest* - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 @@ -3799,7 +3799,7 @@ fi $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing strerror" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing strerror" >&5 $as_echo_n "checking for library containing strerror... " >&6; } if ${ac_cv_search_strerror+:} false; then : $as_echo_n "(cached) " >&6 @@ -3854,7 +3854,7 @@ if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi - for ac_prog in gawk mawk nawk awk + for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 diff --git a/src/config.mk.dist b/src/config.mk.dist index fa7c108505..8a584c29a4 100644 --- a/src/config.mk.dist +++ b/src/config.mk.dist @@ -1,4 +1,4 @@ -the first targets to make vim are: scratch config myself +the first target to make vim is: reconfig srcdir = . VIMNAME = vim EXNAME = ex diff --git a/src/configure.ac b/src/configure.ac index 482773750e..7bfbd231e2 100644 --- a/src/configure.ac +++ b/src/configure.ac @@ -11,12 +11,12 @@ AC_DEFINE(UNIX) AC_PROG_MAKE_SET dnl Checks for programs. -AC_PROG_CC dnl required by almost everything -AC_PROG_CPP dnl required by header file checks -AC_PROGRAM_EGREP dnl required by AC_EGREP_CPP -AC_PROG_FGREP dnl finds working grep -F -AC_ISC_POSIX dnl required by AC_C_CROSS -AC_PROG_AWK dnl required for "make html" in ../doc +AC_PROG_CC dnl required by almost everything +AC_PROG_CPP dnl required by header file checks +AC_PROGRAM_EGREP dnl required by AC_EGREP_CPP +AC_PROG_FGREP dnl finds working grep -F +AC_ISC_POSIX dnl required by AC_C_CROSS +AC_PROG_AWK dnl required for "make html" in ../doc dnl Don't strip if we don't have it AC_CHECK_PROG(STRIP, strip, strip, :) diff --git a/src/create_cmdidxs.pl b/src/create_cmdidxs.pl deleted file mode 100644 index d39ac1614a..0000000000 --- a/src/create_cmdidxs.pl +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/perl -w -# -# This script generates the tables cmdidxs1[] and cmdidxs2[][] which, -# given a Ex command, determine the first value to probe to find -# a matching command in cmdnames[] based on the first character -# and the first 2 characters of the command. -# This is used to speed up lookup in cmdnames[]. -# -# Script should be run every time new Ex commands are added in Vim, -# from the src/vim directory, since it reads commands from "ex_cmds.h". - -use strict; - -# Find the list of Vim commands from cmdnames[] table in ex_cmds.h -my @cmds; -my $skipped_cmds; -open(IN, "< ex_cmds.h") or die "can't open ex_cmds.h: $!\n"; -while () { - if (/^EX\(CMD_\S*,\s*"([a-z][^"]*)"/) { - push @cmds, $1; - } elsif (/^EX\(CMD_/) { - ++$skipped_cmds; - } -} - -my %cmdidxs1; -my %cmdidxs2; - -for (my $i = $#cmds; $i >= 0; --$i) { - my $cmd = $cmds[$i]; - my $c1 = substr($cmd, 0, 1); # First character of command. - - $cmdidxs1{$c1} = $i; - - if (length($cmd) > 1) { - my $c2 = substr($cmd, 1, 1); # Second character of command. - $cmdidxs2{$c1}{$c2} = $i if (('a' lt $c2) and ($c2 lt 'z')); - } -} - -print "/* Beginning of automatically generated code by create_cmdidxs.pl\n", - " *\n", - " * Table giving the index of the first command in cmdnames[] to lookup\n", - " * based on the first letter of a command.\n", - " */\n", - "static const unsigned short cmdidxs1[26] =\n{\n", - join(",\n", map(" /* $_ */ $cmdidxs1{$_}", ('a' .. 'z'))), - "\n};\n", - "\n", - "/*\n", - " * Table giving the index of the first command in cmdnames[] to lookup\n", - " * based on the first 2 letters of a command.\n", - " * Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that they\n", - " * fit in a byte.\n", - " */\n", - "static const unsigned char cmdidxs2[26][26] =\n", - "{ /* a b c d e f g h i j k l m n o p q r s t u v w x y z */\n"; -for my $c1 ('a' .. 'z') { - print " /* $c1 */ {"; - for my $c2 ('a' .. 'z') { - if (exists $cmdidxs2{$c1}{$c2}) { - printf "%3d,", $cmdidxs2{$c1}{$c2} - $cmdidxs1{$c1}; - } else { - printf " 0,"; - } - } - print " }"; - print "," unless ($c1 eq 'z'); - print "\n"; -} -print "};\n", - "\n", - "static const int command_count = ", scalar(@cmds) + $skipped_cmds, ";\n", - "\n", - "/* End of automatically generated code by create_cmdidxs.pl */\n"; diff --git a/src/create_cmdidxs.vim b/src/create_cmdidxs.vim new file mode 100644 index 0000000000..c306ccb872 --- /dev/null +++ b/src/create_cmdidxs.vim @@ -0,0 +1,81 @@ +" This script generates the tables cmdidxs1[] and cmdidxs2[][] which, +" given a Ex command, determine the first value to probe to find +" a matching command in cmdnames[] based on the first character +" and the first 2 characters of the command. +" This is used to speed up lookup in cmdnames[]. +" +" Script should be run every time new Ex commands are added in Vim, +" from the src/vim directory, since it reads commands from "ex_cmds.h". + +let cmds = [] +let skipped_cmds = 0 + +for line in readfile('ex_cmds.h') + if line =~ '^EX(CMD_' + let m = matchlist(line, '^EX(CMD_\S*,\s*"\([a-z][^"]*\)"') + if len(m) >= 2 + let cmds += [ m[1] ] + else + let skipped_cmds += 1 + endif + endif +endfor + +let cmdidxs1 = {} +let cmdidxs2 = {} + +for i in range(len(cmds) - 1, 0, -1) + let cmd = cmds[i] + let c1 = cmd[0] " First character of command + let c2 = cmd[1] " Second character of command (if any) + + let cmdidxs1{c1} = i + if c2 >= 'a' && c2 <= 'z' + let cmdidxs2{c1}{c2} = i + endif +endfor + +let output = [ '/* Automatically generated code by create_cmdidxs.vim' ] +let output += [ ' *' ] +let output += [ ' * Table giving the index of the first command in cmdnames[] to lookup' ] +let output += [ ' * based on the first letter of a command.' ] +let output += [ ' */' ] +let output += [ 'static const unsigned short cmdidxs1[26] =' ] +let output += [ '{' ] + +let a_to_z = map(range(char2nr('a'), char2nr('z')), 'nr2char(v:val)') +for c1 in a_to_z + let line = ' /* ' . c1 . ' */ ' . cmdidxs1{c1} . ((c1 == 'z') ? '' : ',') + let output += [ line ] +endfor +let output += [ '};' ] +let output += [ '' ] +let output += [ '/*' ] +let output += [ ' * Table giving the index of the first command in cmdnames[] to lookup' ] +let output += [ ' * based on the first 2 letters of a command.' ] +let output += [ ' * Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that they' ] +let output += [ ' * fit in a byte.' ] +let output += [ ' */' ] +let output += [ 'static const unsigned char cmdidxs2[26][26] =' ] +let output += [ '{ /* a b c d e f g h i j k l m n o p q r s t u v w x y z */' ] + +for c1 in a_to_z + let line = ' /* ' . c1 . ' */ {' + for c2 in a_to_z + if exists('cmdidxs2{c1}{c2}') + let line .= printf('%3d', cmdidxs2{c1}{c2} - cmdidxs1{c1}) + else + let line .= ' 0' + endif + let line .= (c2 == 'z') ? '' : ',' + endfor + let line .= ' }' . ((c1 == 'z') ? '' : ',') + let output += [ line ] +endfor + +let output += [ '};' ] +let output += [ '' ] +let output += [ 'static const int command_count = ' . (len(cmds) + skipped_cmds) . ';' ] + +call writefile(output, "ex_cmdidxs.h") +quit diff --git a/src/ex_cmdidxs.h b/src/ex_cmdidxs.h new file mode 100644 index 0000000000..3b6120e864 --- /dev/null +++ b/src/ex_cmdidxs.h @@ -0,0 +1,72 @@ +/* Automatically generated code by create_cmdidxs.vim + * + * Table giving the index of the first command in cmdnames[] to lookup + * based on the first letter of a command. + */ +static const unsigned short cmdidxs1[26] = +{ + /* a */ 0, + /* b */ 19, + /* c */ 42, + /* d */ 103, + /* e */ 125, + /* f */ 145, + /* g */ 161, + /* h */ 167, + /* i */ 176, + /* j */ 194, + /* k */ 196, + /* l */ 201, + /* m */ 259, + /* n */ 277, + /* o */ 297, + /* p */ 309, + /* q */ 348, + /* r */ 351, + /* s */ 370, + /* t */ 437, + /* u */ 472, + /* v */ 483, + /* w */ 501, + /* x */ 516, + /* y */ 525, + /* z */ 526 +}; + +/* + * Table giving the index of the first command in cmdnames[] to lookup + * based on the first 2 letters of a command. + * Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that they + * fit in a byte. + */ +static const unsigned char cmdidxs2[26][26] = +{ /* a b c d e f g h i j k l m n o p q r s t u v w x y z */ + /* a */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 0, 0, 0, 7, 15, 0, 16, 0, 0, 0, 0, 0 }, + /* b */ { 2, 0, 0, 4, 5, 7, 0, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, 13, 0, 0, 0, 0, 22, 0, 0, 0 }, + /* c */ { 3, 10, 12, 14, 16, 18, 21, 0, 0, 0, 0, 29, 33, 36, 42, 51, 53, 54, 55, 0, 57, 0, 60, 0, 0, 0 }, + /* d */ { 0, 0, 0, 0, 0, 0, 0, 0, 6, 15, 0, 16, 0, 0, 17, 0, 0, 19, 20, 0, 0, 0, 0, 0, 0, 0 }, + /* e */ { 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0 }, + /* f */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0 }, + /* g */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 4, 5, 0, 0, 0, 0 }, + /* h */ { 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* i */ { 1, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 5, 6, 0, 0, 0, 0, 0, 13, 0, 15, 0, 0, 0, 0, 0 }, + /* j */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, + /* k */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* l */ { 3, 9, 11, 15, 16, 20, 23, 28, 0, 0, 0, 30, 33, 36, 40, 46, 0, 48, 57, 49, 50, 54, 56, 0, 0, 0 }, + /* m */ { 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16 }, + /* n */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 10, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0 }, + /* o */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 5, 0, 0, 0, 0, 0, 0, 9, 0, 11, 0, 0, 0 }, + /* p */ { 1, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 0, 0, 16, 17, 26, 0, 27, 0, 28, 0 }, + /* q */ { 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* r */ { 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 18, 0, 0, 0, 0 }, + /* s */ { 2, 6, 15, 0, 18, 22, 0, 24, 25, 0, 0, 28, 30, 34, 38, 40, 0, 48, 0, 49, 0, 61, 62, 0, 63, 0 }, + /* t */ { 2, 0, 19, 0, 22, 23, 0, 24, 0, 25, 0, 26, 27, 28, 29, 30, 0, 31, 33, 0, 34, 0, 0, 0, 0, 0 }, + /* u */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* v */ { 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 9, 12, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0 }, + /* w */ { 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 8, 0, 9, 10, 0, 12, 0, 13, 14, 0, 0, 0, 0 }, + /* x */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0 }, + /* y */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* z */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } +}; + +static const int command_count = 539; diff --git a/src/ex_cmds.c b/src/ex_cmds.c index 4b0bdef59c..309474ce04 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -4664,6 +4664,8 @@ ex_z(exarg_T *eap) if (curs > curbuf->b_ml.ml_line_count) curs = curbuf->b_ml.ml_line_count; + else if (curs < 1) + curs = 1; for (i = start; i <= end; i++) { @@ -4686,7 +4688,11 @@ ex_z(exarg_T *eap) } } - curwin->w_cursor.lnum = curs; + if (curwin->w_cursor.lnum != curs) + { + curwin->w_cursor.lnum = curs; + curwin->w_cursor.col = 0; + } ex_no_reprint = TRUE; } diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 33879d595d..3817d13817 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -501,81 +501,7 @@ static void ex_folddo(exarg_T *eap); */ #define DO_DECLARE_EXCMD #include "ex_cmds.h" - -/* Beginning of automatically generated code by create_cmdidxs.pl - * - * Table giving the index of the first command in cmdnames[] to lookup - * based on the first letter of a command. - */ -static const unsigned short cmdidxs1[26] = -{ - /* a */ 0, - /* b */ 19, - /* c */ 42, - /* d */ 103, - /* e */ 125, - /* f */ 145, - /* g */ 161, - /* h */ 167, - /* i */ 176, - /* j */ 194, - /* k */ 196, - /* l */ 201, - /* m */ 259, - /* n */ 279, - /* o */ 299, - /* p */ 311, - /* q */ 350, - /* r */ 353, - /* s */ 372, - /* t */ 439, - /* u */ 474, - /* v */ 485, - /* w */ 503, - /* x */ 518, - /* y */ 527, - /* z */ 528 -}; - -/* - * Table giving the index of the first command in cmdnames[] to lookup - * based on the first 2 letters of a command. - * Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that they - * fit in a byte. - */ -static const unsigned char cmdidxs2[26][26] = -{ /* a b c d e f g h i j k l m n o p q r s t u v w x y z */ - /* a */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 0, 0, 0, 7, 15, 0, 16, 0, 0, 0, 0, 0, }, - /* b */ { 0, 0, 0, 4, 5, 7, 0, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, 13, 0, 0, 0, 0, 22, 0, 0, 0, }, - /* c */ { 0, 10, 12, 14, 16, 18, 21, 0, 0, 0, 0, 29, 33, 36, 42, 51, 53, 54, 55, 0, 57, 0, 60, 0, 0, 0, }, - /* d */ { 0, 0, 0, 0, 0, 0, 0, 0, 6, 15, 0, 16, 0, 0, 17, 0, 0, 19, 20, 0, 0, 0, 0, 0, 0, 0, }, - /* e */ { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, }, - /* f */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, }, - /* g */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 4, 5, 0, 0, 0, 0, }, - /* h */ { 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, - /* i */ { 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 5, 6, 0, 0, 0, 0, 0, 13, 0, 15, 0, 0, 0, 0, 0, }, - /* j */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, }, - /* k */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, - /* l */ { 0, 9, 11, 15, 16, 20, 23, 28, 0, 0, 0, 30, 33, 36, 40, 46, 0, 48, 57, 49, 50, 54, 56, 0, 0, 0, }, - /* m */ { 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, - /* n */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 10, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, }, - /* o */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 5, 0, 0, 0, 0, 0, 0, 9, 0, 11, 0, 0, 0, }, - /* p */ { 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 0, 0, 16, 17, 26, 0, 27, 0, 28, 0, }, - /* q */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, - /* r */ { 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 18, 0, 0, 0, 0, }, - /* s */ { 0, 6, 15, 0, 18, 22, 0, 24, 25, 0, 0, 28, 30, 34, 38, 40, 0, 48, 0, 49, 0, 61, 62, 0, 63, 0, }, - /* t */ { 0, 0, 19, 0, 22, 23, 0, 24, 0, 25, 0, 26, 27, 28, 29, 30, 0, 31, 33, 0, 34, 0, 0, 0, 0, 0, }, - /* u */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, - /* v */ { 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 9, 12, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, }, - /* w */ { 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 8, 0, 9, 10, 0, 12, 0, 13, 14, 0, 0, 0, 0, }, - /* x */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, }, - /* y */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, - /* z */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } -}; - -static const int command_count = 541; - -/* End of automatically generated code by create_cmdidxs.pl */ +#include "ex_cmdidxs.h" static char_u dollar_command[2] = {'$', 0}; @@ -3053,7 +2979,10 @@ do_one_cmd( doend: if (curwin->w_cursor.lnum == 0) /* can happen with zero line number */ + { curwin->w_cursor.lnum = 1; + curwin->w_cursor.col = 0; + } if (errormsg != NULL && *errormsg != NUL && !did_emsg) { diff --git a/src/install-sh b/src/install-sh new file mode 100644 index 0000000000..0b0fdcbba6 --- /dev/null +++ b/src/install-sh @@ -0,0 +1,501 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2013-12-25.23; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +tab=' ' +nl=' +' +IFS=" $tab$nl" + +# Set DOITPROG to "echo" to test this script. + +doit=${DOITPROG-} +doit_exec=${doit:-exec} + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +is_target_a_directory=possibly + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) is_target_a_directory=never;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + dstdir=`dirname "$dst"` + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + oIFS=$IFS + IFS=/ + set -f + set fnord $dstdir + shift + set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + set +f && + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/src/installman.sh b/src/installman.sh index 0ac6c46a14..a2f09ad35e 100755 --- a/src/installman.sh +++ b/src/installman.sh @@ -39,7 +39,7 @@ tutorsubloc=$scriptloc/tutor if test $what = "install" -o $what = "xxd"; then if test ! -d $destdir; then echo creating $destdir - ./mkinstalldirs $destdir + /bin/sh install-sh -c -d $destdir fi fi diff --git a/src/installml.sh b/src/installml.sh index e6dc3d8f32..8649c6ff56 100644 --- a/src/installml.sh +++ b/src/installml.sh @@ -49,7 +49,7 @@ eviewname=$9 if test $what = "install" -a \( -f $destdir/$vimname.1 -o -f $destdir/$vimdiffname.1 -o -f $destdir/$eviewname.1 \); then if test ! -d $destdir; then echo creating $destdir - ./mkinstalldirs $destdir + /bin/sh install-sh -c -d $destdir fi # ex diff --git a/src/misc1.c b/src/misc1.c index e8feb2db27..41972547c9 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -9257,7 +9257,8 @@ find_match(int lookfor, linenr_T ourscope) int get_expr_indent(void) { - int indent; + int indent = -1; + char_u *inde_copy; pos_T save_pos; colnr_T save_curswant; int save_set_curswant; @@ -9274,7 +9275,16 @@ get_expr_indent(void) if (use_sandbox) ++sandbox; ++textlock; - indent = (int)eval_to_number(curbuf->b_p_inde); + + /* Need to make a copy, the 'indentexpr' option could be changed while + * evaluating it. */ + inde_copy = vim_strsave(curbuf->b_p_inde); + if (inde_copy != NULL) + { + indent = (int)eval_to_number(inde_copy); + vim_free(inde_copy); + } + if (use_sandbox) --sandbox; --textlock; diff --git a/src/mkinstalldirs b/src/mkinstalldirs deleted file mode 100755 index 68c4e738da..0000000000 --- a/src/mkinstalldirs +++ /dev/null @@ -1,38 +0,0 @@ -#! /bin/sh -# mkinstalldirs --- make directory hierarchy -# Author: Noah Friedman -# Created: 1993-05-16 -# Public domain - -errstatus=0 - -for file -do - set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` - shift - - pathcomp= - for d - do - pathcomp="$pathcomp$d" - case "$pathcomp" in - -* ) pathcomp=./$pathcomp ;; - esac - - if test ! -d "$pathcomp"; then - echo "mkdir $pathcomp" 1>&2 - - mkdir "$pathcomp" || lasterr=$? - - if test ! -d "$pathcomp"; then - errstatus=$lasterr - fi - fi - - pathcomp="$pathcomp/" - done -done - -exit $errstatus - -# mkinstalldirs ends here diff --git a/src/normal.c b/src/normal.c index 214c2c0d44..7aaa8e43ae 100644 --- a/src/normal.c +++ b/src/normal.c @@ -4376,7 +4376,12 @@ find_decl( if ((pos = findmatchlimit(NULL, '}', FM_FORWARD, (int)(old_pos.lnum - curwin->w_cursor.lnum + 1))) != NULL && pos->lnum < old_pos.lnum) + { + /* There can't be a useful match before the end of this block. + * Skip to the end. */ + curwin->w_cursor = *pos; continue; + } } if (t == FAIL) @@ -8345,6 +8350,7 @@ nv_g_cmd(cmdarg_T *cap) break; #endif + /* "g<": show scrollback text */ case '<': show_sb_text(); break; diff --git a/src/quickfix.c b/src/quickfix.c index d2921b21c6..b28a321f3c 100644 --- a/src/quickfix.c +++ b/src/quickfix.c @@ -2750,12 +2750,18 @@ qf_free(qf_info_T *qi, int idx) vim_free(qi->qf_lists[idx].qf_title); qi->qf_lists[idx].qf_title = NULL; qi->qf_lists[idx].qf_index = 0; + qi->qf_lists[idx].qf_start = NULL; qi->qf_lists[idx].qf_last = NULL; + qi->qf_lists[idx].qf_ptr = NULL; + qi->qf_lists[idx].qf_nonevalid = TRUE; qf_clean_dir_stack(&qi->qf_dir_stack); qi->qf_directory = NULL; qf_clean_dir_stack(&qi->qf_file_stack); qi->qf_currfile = NULL; + qi->qf_multiline = FALSE; + qi->qf_multiignore = FALSE; + qi->qf_multiscan = FALSE; } /* @@ -4923,6 +4929,7 @@ qf_free_stack(win_T *wp, qf_info_T *qi) /* If the location list window is open, then create a new empty * location list */ qf_info_T *new_ll = ll_new_list(); + orig_wp->w_llist_ref = new_ll; if (llwin != NULL) { diff --git a/src/term.c b/src/term.c index 9be746705f..dd60d0442d 100644 --- a/src/term.c +++ b/src/term.c @@ -3187,15 +3187,19 @@ settmode(int tmode) #endif #ifdef FEAT_MOUSE_TTY if (tmode != TMODE_RAW) - mch_setmouse(FALSE); /* switch mouse off */ + mch_setmouse(FALSE); /* switch mouse off */ #endif + if (tmode != TMODE_RAW) + out_str(T_BD); /* disable bracketed paste mode */ out_flush(); - mch_settmode(tmode); /* machine specific function */ + mch_settmode(tmode); /* machine specific function */ cur_tmode = tmode; #ifdef FEAT_MOUSE if (tmode == TMODE_RAW) - setmouse(); /* may switch mouse on */ + setmouse(); /* may switch mouse on */ #endif + if (tmode == TMODE_RAW) + out_str(T_BE); /* enable bracketed paste mode */ out_flush(); } #ifdef FEAT_TERMRESPONSE diff --git a/src/testdir/test_ex_z.vim b/src/testdir/test_ex_z.vim index 608a36c490..6e03b0bff9 100644 --- a/src/testdir/test_ex_z.vim +++ b/src/testdir/test_ex_z.vim @@ -68,7 +68,7 @@ func Test_z() bw! endfunc -func Test_z_bug() +func Test_z_overflow() " This used to access invalid memory as a result of an integer overflow " and freeze vim. normal ox @@ -76,3 +76,10 @@ func Test_z_bug() z777777776666666 ') endfunc + +func Test_z_negative_lnum() + new + z^ + call assert_equal(1, line('.')) + bwipe! +endfunc diff --git a/src/testdir/test_goto.vim b/src/testdir/test_goto.vim index 2573401707..ea67fe7386 100644 --- a/src/testdir/test_goto.vim +++ b/src/testdir/test_goto.vim @@ -288,3 +288,24 @@ func Test_cursorline_keep_col() set nocursorline endfunc +func Test_gd_local_block() + let lines = [ + \ ' int main()', + \ '{', + \ ' char *a = "NOT NULL";', + \ ' if(a)', + \ ' {', + \ ' char *b = a;', + \ ' printf("%s\n", b);', + \ ' }', + \ ' else', + \ ' {', + \ ' char *b = "NULL";', + \ ' return b;', + \ ' }', + \ '', + \ ' return 0;', + \ '}', + \ ] + call XTest_goto_decl('1gd', lines, 11, 11) +endfunc diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim index d72ca74b29..5d2033a5df 100644 --- a/src/testdir/test_options.vim +++ b/src/testdir/test_options.vim @@ -319,3 +319,16 @@ func Test_set_values() throw 'Skipped: opt_test.vim does not exist' endif endfunc + +func ResetIndentexpr() + set indentexpr= +endfunc + +func Test_set_indentexpr() + " this was causing usage of freed memory + set indentexpr=ResetIndentexpr() + new + call feedkeys("i\", 'x') + call assert_equal('', &indentexpr) + bwipe! +endfunc diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim index 54995f7876..b5d0c1b85e 100644 --- a/src/testdir/test_quickfix.vim +++ b/src/testdir/test_quickfix.vim @@ -24,8 +24,8 @@ func s:setup_commands(cchar) command! -nargs=* Xgetbuffer cgetbuffer command! -nargs=* Xaddbuffer caddbuffer command! -nargs=* Xrewind crewind - command! -nargs=* -bang Xnext cnext - command! -nargs=* -bang Xprev cprev + command! -count -nargs=* -bang Xnext cnext + command! -count -nargs=* -bang Xprev cprev command! -nargs=* -bang Xfirst cfirst command! -nargs=* -bang Xlast clast command! -nargs=* -bang Xnfile cnfile @@ -56,8 +56,8 @@ func s:setup_commands(cchar) command! -nargs=* Xgetbuffer lgetbuffer command! -nargs=* Xaddbuffer laddbuffer command! -nargs=* Xrewind lrewind - command! -nargs=* -bang Xnext lnext - command! -nargs=* -bang Xprev lprev + command! -count -nargs=* -bang Xnext lnext + command! -count -nargs=* -bang Xprev lprev command! -nargs=* -bang Xfirst lfirst command! -nargs=* -bang Xlast llast command! -nargs=* -bang Xnfile lnfile @@ -395,7 +395,9 @@ func Xtest_browse(cchar) Xgetexpr ['Xqftestfile1:5:Line5', \ 'Xqftestfile1:6:Line6', \ 'Xqftestfile2:10:Line10', - \ 'Xqftestfile2:11:Line11'] + \ 'Xqftestfile2:11:Line11', + \ 'RegularLine1', + \ 'RegularLine2'] Xfirst call assert_fails('Xprev', 'E553') @@ -407,6 +409,7 @@ func Xtest_browse(cchar) call assert_equal('Xqftestfile1', bufname('%')) call assert_equal(6, line('.')) Xlast + Xprev call assert_equal('Xqftestfile2', bufname('%')) call assert_equal(11, line('.')) call assert_fails('Xnext', 'E553') @@ -415,6 +418,13 @@ func Xtest_browse(cchar) call assert_equal('Xqftestfile1', bufname('%')) call assert_equal(5, line('.')) + 10Xnext + call assert_equal('Xqftestfile2', bufname('%')) + call assert_equal(11, line('.')) + 10Xprev + call assert_equal('Xqftestfile1', bufname('%')) + call assert_equal(5, line('.')) + Xexpr "" call assert_fails('Xnext', 'E42:') @@ -455,9 +465,30 @@ func s:test_xhelpgrep(cchar) let title_text = ':lhelpgrep quickfix' endif call assert_true(w:quickfix_title =~ title_text, w:quickfix_title) + + " Jumping to a help topic should open the help window + only + Xnext + call assert_true(&buftype == 'help') + call assert_true(winnr('$') == 2) + " Jumping to the next match should reuse the help window + Xnext + call assert_true(&buftype == 'help') + call assert_true(winnr() == 1) + call assert_true(winnr('$') == 2) + " Jumping to the next match from the quickfix window should reuse the help + " window + Xopen + Xnext + call assert_true(&buftype == 'help') + call assert_true(winnr() == 1) + call assert_true(winnr('$') == 2) + " This wipes out the buffer, make sure that doesn't cause trouble. Xclose + new | only + " Search for non existing help string call assert_fails('Xhelpgrep a1b2c3', 'E480:') endfunc @@ -596,10 +627,7 @@ func Test_locationlist() lrewind enew lopen - lnext - lnext - lnext - lnext + 4lnext vert split wincmd L lopen @@ -1057,6 +1085,25 @@ func Test_efm2() call assert_equal(1, l[4].valid) call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr)) + " The following sequence of commands used to crash Vim + set efm=%W%m + cgetexpr ['msg1'] + let l = getqflist() + call assert_equal(1, len(l), string(l)) + call assert_equal('msg1', l[0].text) + set efm=%C%m + lexpr 'msg2' + let l = getloclist(0) + call assert_equal(1, len(l), string(l)) + call assert_equal('msg2', l[0].text) + lopen + call setqflist([], 'r') + caddbuf + let l = getqflist() + call assert_equal(1, len(l), string(l)) + call assert_equal('|| msg2', l[0].text) + + new | only let &efm = save_efm endfunc @@ -1387,18 +1434,18 @@ func Test_switchbuf() let winid = win_getid() cfirst | cnext call assert_equal(winid, win_getid()) - cnext | cnext + 2cnext call assert_equal(winid, win_getid()) - cnext | cnext + 2cnext call assert_equal(winid, win_getid()) enew set switchbuf=useopen cfirst | cnext call assert_equal(file1_winid, win_getid()) - cnext | cnext + 2cnext call assert_equal(file2_winid, win_getid()) - cnext | cnext + 2cnext call assert_equal(file2_winid, win_getid()) enew | only @@ -1408,9 +1455,9 @@ func Test_switchbuf() tabfirst cfirst | cnext call assert_equal(2, tabpagenr()) - cnext | cnext + 2cnext call assert_equal(3, tabpagenr()) - cnext | cnext + 2cnext call assert_equal(3, tabpagenr()) tabfirst | tabonly | enew @@ -1975,3 +2022,15 @@ func Test_qf_free() call XfreeTests('c') call XfreeTests('l') endfunc + +func Test_no_reuse_mem() + set efm=E,%W%m, + cgetexpr ['C'] + set efm=%C%m + lexpr '0' + lopen + call setqflist([], 'r') + caddbuf + + set efm& +endfunc diff --git a/src/version.c b/src/version.c index b6f783fcb6..cabbb95856 100644 --- a/src/version.c +++ b/src/version.c @@ -779,6 +779,26 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 577, +/**/ + 576, +/**/ + 575, +/**/ + 574, +/**/ + 573, +/**/ + 572, +/**/ + 571, +/**/ + 570, +/**/ + 569, +/**/ + 568, /**/ 567, /**/