From 64379f252ac5339740c75262ea762e705567961e Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 7 Jul 2011 15:04:52 +0200 Subject: [PATCH 01/34] updated for version 7.3.238 Problem: Compiler warning for conversion. Solution: Add type cast. (Mike Williams) --- src/ex_getln.c | 2 +- src/version.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ex_getln.c b/src/ex_getln.c index 85f8cfac10..561ab970ee 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -5025,7 +5025,7 @@ ExpandRTDir(pat, num_file, file, dirnames) *num_file = 0; *file = NULL; - pat_len = STRLEN(pat); + pat_len = (int)STRLEN(pat); ga_init2(&ga, (int)sizeof(char *), 10); for (i = 0; dirnames[i] != NULL; ++i) diff --git a/src/version.c b/src/version.c index 731a46dd39..92612ad3ac 100644 --- a/src/version.c +++ b/src/version.c @@ -709,6 +709,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 238, /**/ 237, /**/ From f562b94b3f6eef40d92ba890373a825af631f0ab Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 7 Jul 2011 15:04:52 +0200 Subject: [PATCH 02/34] Added tag v7-3-238 for changeset f2c108f44f41 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index cd3b16359b..324bee592a 100644 --- a/.hgtags +++ b/.hgtags @@ -1572,3 +1572,4 @@ b67d3a44262a97e7b3ae212fcffb36926b5f53f4 v7-3-232 441d364773dc53264b5f26042f8fc6f8b77c8044 v7-3-235 c1733ef5b6e87dde521d0d85a1e5e62259854ac1 v7-3-236 e3bb93df6c34da672244bce5695c1426da139614 v7-3-237 +f2c108f44f415c7cfe92862e791a01cc542ac378 v7-3-238 From a732285db7a2653d327fa1116b30c00c9ee9d3f0 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 7 Jul 2011 15:08:58 +0200 Subject: [PATCH 03/34] updated for version 7.3.239 Problem: Python corrects the cursor column without taking 'virtualedit' into account. (lilydjwg) Solution: Call check_cursor_col_win(). --- src/if_py_both.h | 10 +++------- src/mbyte.c | 7 ++++--- src/misc2.c | 42 ++++++++++++++++++++++++++---------------- src/normal.c | 2 +- src/proto/mbyte.pro | 2 +- src/proto/misc2.pro | 1 + src/version.c | 2 ++ 7 files changed, 38 insertions(+), 28 deletions(-) diff --git a/src/if_py_both.h b/src/if_py_both.h index 07eedb5f31..c7870bc10b 100644 --- a/src/if_py_both.h +++ b/src/if_py_both.h @@ -534,7 +534,6 @@ WindowSetattr(PyObject *self, char *name, PyObject *val) { long lnum; long col; - long len; if (!PyArg_Parse(val, "(ll)", &lnum, &col)) return -1; @@ -549,18 +548,15 @@ WindowSetattr(PyObject *self, char *name, PyObject *val) if (VimErrorCheck()) return -1; - /* When column is out of range silently correct it. */ - len = (long)STRLEN(ml_get_buf(this->win->w_buffer, lnum, FALSE)); - if (col > len) - col = len; - this->win->w_cursor.lnum = lnum; this->win->w_cursor.col = col; #ifdef FEAT_VIRTUALEDIT this->win->w_cursor.coladd = 0; #endif - update_screen(VALID); + /* When column is out of range silently correct it. */ + check_cursor_col_win(this->win); + update_screen(VALID); return 0; } else if (strcmp(name, "height") == 0) diff --git a/src/mbyte.c b/src/mbyte.c index ce0c8975ee..6e0dbf6549 100644 --- a/src/mbyte.c +++ b/src/mbyte.c @@ -3563,7 +3563,7 @@ dbcs_screen_tail_off(base, p) void mb_adjust_cursor() { - mb_adjustpos(&curwin->w_cursor); + mb_adjustpos(curbuf, &curwin->w_cursor); } /* @@ -3571,7 +3571,8 @@ mb_adjust_cursor() * If it points to a tail byte it's moved backwards to the head byte. */ void -mb_adjustpos(lp) +mb_adjustpos(buf, lp) + buf_T *buf; pos_T *lp; { char_u *p; @@ -3582,7 +3583,7 @@ mb_adjustpos(lp) #endif ) { - p = ml_get(lp->lnum); + p = ml_get_buf(buf, lp->lnum, FALSE); lp->col -= (*mb_head_off)(p, p + lp->col); #ifdef FEAT_VIRTUALEDIT /* Reset "coladd" when the cursor would be on the right half of a diff --git a/src/misc2.c b/src/misc2.c index c6207ff042..9479a53c20 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -333,7 +333,7 @@ coladvance2(pos, addspaces, finetune, wcol) #ifdef FEAT_MBYTE /* prevent from moving onto a trail byte */ if (has_mbyte) - mb_adjustpos(pos); + mb_adjustpos(curbuf, pos); #endif if (col < wcol) @@ -543,17 +543,27 @@ check_cursor_lnum() */ void check_cursor_col() +{ + check_cursor_col_win(curwin); +} + +/* + * Make sure win->w_cursor.col is valid. + */ + void +check_cursor_col_win(win) + win_T *win; { colnr_T len; #ifdef FEAT_VIRTUALEDIT - colnr_T oldcol = curwin->w_cursor.col; - colnr_T oldcoladd = curwin->w_cursor.col + curwin->w_cursor.coladd; + colnr_T oldcol = win->w_cursor.col; + colnr_T oldcoladd = win->w_cursor.col + win->w_cursor.coladd; #endif - len = (colnr_T)STRLEN(ml_get_curline()); + len = (colnr_T)STRLEN(ml_get_buf(win->w_buffer, win->w_cursor.lnum, FALSE)); if (len == 0) - curwin->w_cursor.col = 0; - else if (curwin->w_cursor.col >= len) + win->w_cursor.col = 0; + else if (win->w_cursor.col >= len) { /* Allow cursor past end-of-line when: * - in Insert mode or restarting Insert mode @@ -567,33 +577,33 @@ check_cursor_col() || (ve_flags & VE_ONEMORE) #endif || virtual_active()) - curwin->w_cursor.col = len; + win->w_cursor.col = len; else { - curwin->w_cursor.col = len - 1; + win->w_cursor.col = len - 1; #ifdef FEAT_MBYTE - /* prevent cursor from moving on the trail byte */ + /* Move the cursor to the head byte. */ if (has_mbyte) - mb_adjust_cursor(); + mb_adjustpos(win->w_buffer, &win->w_cursor); #endif } } - else if (curwin->w_cursor.col < 0) - curwin->w_cursor.col = 0; + else if (win->w_cursor.col < 0) + win->w_cursor.col = 0; #ifdef FEAT_VIRTUALEDIT /* If virtual editing is on, we can leave the cursor on the old position, * only we must set it to virtual. But don't do it when at the end of the * line. */ if (oldcol == MAXCOL) - curwin->w_cursor.coladd = 0; + win->w_cursor.coladd = 0; else if (ve_flags == VE_ALL) { - if (oldcoladd > curwin->w_cursor.col) - curwin->w_cursor.coladd = oldcoladd - curwin->w_cursor.col; + if (oldcoladd > win->w_cursor.col) + win->w_cursor.coladd = oldcoladd - win->w_cursor.col; else /* avoid weird number when there is a miscalculation or overflow */ - curwin->w_cursor.coladd = 0; + win->w_cursor.coladd = 0; } #endif } diff --git a/src/normal.c b/src/normal.c index bd6f1f239c..522480fc4a 100644 --- a/src/normal.c +++ b/src/normal.c @@ -8774,7 +8774,7 @@ unadjust_for_sel() { --pp->col; #ifdef FEAT_MBYTE - mb_adjustpos(pp); + mb_adjustpos(curbuf, pp); #endif } else if (pp->lnum > 1) diff --git a/src/proto/mbyte.pro b/src/proto/mbyte.pro index 9519a19371..88496ccf06 100644 --- a/src/proto/mbyte.pro +++ b/src/proto/mbyte.pro @@ -56,7 +56,7 @@ void utf_find_illegal __ARGS((void)); int utf_valid_string __ARGS((char_u *s, char_u *end)); int dbcs_screen_tail_off __ARGS((char_u *base, char_u *p)); void mb_adjust_cursor __ARGS((void)); -void mb_adjustpos __ARGS((pos_T *lp)); +void mb_adjustpos __ARGS((buf_T *buf, pos_T *lp)); char_u *mb_prevptr __ARGS((char_u *line, char_u *p)); int mb_charlen __ARGS((char_u *str)); int mb_charlen_len __ARGS((char_u *str, int len)); diff --git a/src/proto/misc2.pro b/src/proto/misc2.pro index 720d263fd6..a22ba7f0ae 100644 --- a/src/proto/misc2.pro +++ b/src/proto/misc2.pro @@ -14,6 +14,7 @@ int decl __ARGS((pos_T *lp)); linenr_T get_cursor_rel_lnum __ARGS((win_T *wp, linenr_T lnum)); void check_cursor_lnum __ARGS((void)); void check_cursor_col __ARGS((void)); +void check_cursor_col_win __ARGS((win_T *win)); void check_cursor __ARGS((void)); void adjust_cursor_col __ARGS((void)); int leftcol_changed __ARGS((void)); diff --git a/src/version.c b/src/version.c index 92612ad3ac..8af816c080 100644 --- a/src/version.c +++ b/src/version.c @@ -709,6 +709,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 239, /**/ 238, /**/ From dab1828e3d30f6d934e8c0b70f646537c5d92142 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 7 Jul 2011 15:08:58 +0200 Subject: [PATCH 04/34] Added tag v7-3-239 for changeset 0bef86c5c985 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 324bee592a..2110400b1b 100644 --- a/.hgtags +++ b/.hgtags @@ -1573,3 +1573,4 @@ b67d3a44262a97e7b3ae212fcffb36926b5f53f4 v7-3-232 c1733ef5b6e87dde521d0d85a1e5e62259854ac1 v7-3-236 e3bb93df6c34da672244bce5695c1426da139614 v7-3-237 f2c108f44f415c7cfe92862e791a01cc542ac378 v7-3-238 +0bef86c5c985218a9448fa16d935b913e67af8d5 v7-3-239 From 09fcb0313816640d19e9bde0e8cb039d88a1c894 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 7 Jul 2011 16:20:52 +0200 Subject: [PATCH 05/34] updated for version 7.3.240 Problem: External commands can't use pipes on MS-Windows. Solution: Implement pipes and use them when 'shelltemp' isn't set. (Vincent Berthoux) --- src/eval.c | 2 +- src/ex_cmds.c | 2 +- src/misc2.c | 19 ++ src/os_unix.c | 21 -- src/os_win32.c | 520 +++++++++++++++++++++++++++++++++++++++++++- src/proto/misc2.pro | 1 + src/ui.c | 2 +- src/version.c | 2 + 8 files changed, 540 insertions(+), 29 deletions(-) diff --git a/src/eval.c b/src/eval.c index 648d938dc2..e111707365 100644 --- a/src/eval.c +++ b/src/eval.c @@ -11931,7 +11931,7 @@ f_has(argvars, rettv) #ifdef FEAT_SEARCHPATH "file_in_path", #endif -#if defined(UNIX) && !defined(USE_SYSTEM) +#if (defined(UNIX) && !defined(USE_SYSTEM)) || defined(WIN3264) "filterpipe", #endif #ifdef FEAT_FIND_ID diff --git a/src/ex_cmds.c b/src/ex_cmds.c index 43e861ae83..9542113853 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -1107,7 +1107,7 @@ do_filter(line1, line2, eap, cmd, do_in, do_out) if (do_out) shell_flags |= SHELL_DOOUT; -#if !defined(USE_SYSTEM) && defined(UNIX) +#if (!defined(USE_SYSTEM) && defined(UNIX)) || defined(WIN3264) if (!do_in && do_out && !p_stmp) { /* Use a pipe to fetch stdout of the command, do not use a temp file. */ diff --git a/src/misc2.c b/src/misc2.c index 9479a53c20..b7e7d01ea2 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -2146,6 +2146,25 @@ ga_append(gap, c) } } +#if (defined(UNIX) && !defined(USE_SYSTEM)) || defined(WIN3264) +/* + * Append the text in "gap" below the cursor line and clear "gap". + */ + void +append_ga_line(gap) + garray_T *gap; +{ + /* Remove trailing CR. */ + if (gap->ga_len > 0 + && !curbuf->b_p_bin + && ((char_u *)gap->ga_data)[gap->ga_len - 1] == CAR) + --gap->ga_len; + ga_append(gap, NUL); + ml_append(curwin->w_cursor.lnum++, gap->ga_data, 0, FALSE); + gap->ga_len = 0; +} +#endif + /************************************************************************ * functions that use lookup tables for various things, generally to do with * special key codes. diff --git a/src/os_unix.c b/src/os_unix.c index a6df74c375..a3c4fd690f 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3660,27 +3660,6 @@ mch_new_shellsize() /* Nothing to do. */ } -#ifndef USE_SYSTEM -static void append_ga_line __ARGS((garray_T *gap)); - -/* - * Append the text in "gap" below the cursor line and clear "gap". - */ - static void -append_ga_line(gap) - garray_T *gap; -{ - /* Remove trailing CR. */ - if (gap->ga_len > 0 - && !curbuf->b_p_bin - && ((char_u *)gap->ga_data)[gap->ga_len - 1] == CAR) - --gap->ga_len; - ga_append(gap, NUL); - ml_append(curwin->w_cursor.lnum++, gap->ga_data, 0, FALSE); - gap->ga_len = 0; -} -#endif - int mch_call_shell(cmd, options) char_u *cmd; diff --git a/src/os_win32.c b/src/os_win32.c index d4ef93988b..88ead6fd63 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -417,6 +417,11 @@ static PSNSECINFO pSetNamedSecurityInfo; static PGNSECINFO pGetNamedSecurityInfo; #endif +typedef BOOL (WINAPI *PSETHANDLEINFORMATION)(HANDLE, DWORD, DWORD); + +static BOOL allowPiping = FALSE; +static PSETHANDLEINFORMATION pSetHandleInformation; + /* * Set g_PlatformId to VER_PLATFORM_WIN32_NT (NT) or * VER_PLATFORM_WIN32_WINDOWS (Win95). @@ -467,6 +472,18 @@ PlatformId(void) } } #endif + /* + * If we are on windows NT, try to load the pipe functions, only + * available from Win2K. + */ + if (g_PlatformId == VER_PLATFORM_WIN32_NT) + { + HANDLE kernel32 = GetModuleHandle("kernel32"); + pSetHandleInformation = (PSETHANDLEINFORMATION)GetProcAddress( + kernel32, "SetHandleInformation"); + + allowPiping = pSetHandleInformation != NULL; + } done = TRUE; } } @@ -1635,7 +1652,7 @@ executable_exists(char *name) } #if ((defined(__MINGW32__) || defined (__CYGWIN32__)) && \ - __MSVCRT_VERSION__ >= 0x800) || (defined(_MSC_VER) && _MSC_VER >= 1400) + __MSVCRT_VERSION__ >= 0x800) || (defined(_MSC_VER) && _MSC_VER >= 1400) /* * Bad parameter handler. * @@ -3210,7 +3227,7 @@ mch_set_winsize_now(void) * 4. Prompt the user to press a key to close the console window */ static int -mch_system(char *cmd, int options) +mch_system_classic(char *cmd, int options) { STARTUPINFO si; PROCESS_INFORMATION pi; @@ -3315,6 +3332,498 @@ mch_system(char *cmd, int options) return ret; } + +/* + * Thread launched by the gui to send the current buffer data to the + * process. This way avoid to hang up vim totally if the children + * process take a long time to process the lines. + */ + static DWORD WINAPI +sub_process_writer(LPVOID param) +{ + HANDLE g_hChildStd_IN_Wr = param; + linenr_T lnum = curbuf->b_op_start.lnum; + DWORD len = 0; + DWORD l; + char_u *lp = ml_get(lnum); + char_u *s; + int written = 0; + + for (;;) + { + l = (DWORD)STRLEN(lp + written); + if (l == 0) + len = 0; + else if (lp[written] == NL) + { + /* NL -> NUL translation */ + WriteFile(g_hChildStd_IN_Wr, "", 1, &len, NULL); + } + else + { + s = vim_strchr(lp + written, NL); + WriteFile(g_hChildStd_IN_Wr, (char *)lp + written, + s == NULL ? l : (DWORD)(s - (lp + written)), + &len, NULL); + } + if (len == (int)l) + { + /* Finished a line, add a NL, unless this line should not have + * one. */ + if (lnum != curbuf->b_op_end.lnum + || !curbuf->b_p_bin + || (lnum != curbuf->b_no_eol_lnum + && (lnum != curbuf->b_ml.ml_line_count + || curbuf->b_p_eol))) + { + WriteFile(g_hChildStd_IN_Wr, "\n", 1, &ignored, NULL); + } + + ++lnum; + if (lnum > curbuf->b_op_end.lnum) + break; + + lp = ml_get(lnum); + written = 0; + } + else if (len > 0) + written += len; + } + + /* finished all the lines, close pipe */ + CloseHandle(g_hChildStd_IN_Wr); + ExitThread(0); +} + + +# define BUFLEN 100 /* length for buffer, stolen from unix version */ + +/* + * This function read from the children's stdout and write the + * data on screen or in the buffer accordingly. + */ + static void +dump_pipe(int options, + HANDLE g_hChildStd_OUT_Rd, + garray_T *ga, + char_u buffer[], + DWORD *buffer_off) +{ + DWORD availableBytes = 0; + DWORD i; + int c; + char_u *p; + int ret; + DWORD len; + DWORD toRead; + int repeatCount; + + /* we query the pipe to see if there is any data to read + * to avoid to perform a blocking read */ + ret = PeekNamedPipe(g_hChildStd_OUT_Rd, /* pipe to query */ + NULL, /* optional buffer */ + 0, /* buffe size */ + NULL, /* number of read bytes */ + &availableBytes, /* available bytes total */ + NULL); /* byteLeft */ + + repeatCount = 0; + /* We got real data in the pipe, read it */ + while (ret != 0 && availableBytes > 0 && availableBytes > 0) + { + repeatCount++; + toRead = +# ifdef FEAT_MBYTE + (DWORD)(BUFLEN - *buffer_off); +# else + (DWORD)BUFLEN; +# endif + toRead = availableBytes < toRead ? availableBytes : toRead; + ReadFile(g_hChildStd_OUT_Rd, buffer +# ifdef FEAT_MBYTE + + *buffer_off, toRead +# else + , toRead +# endif + , &len, NULL); + + /* If we haven't read anything, there is a problem */ + if (len == 0) + break; + + availableBytes -= len; + + if (options & SHELL_READ) + { + /* Do NUL -> NL translation, append NL separated + * lines to the current buffer. */ + for (i = 0; i < len; ++i) + { + if (buffer[i] == NL) + append_ga_line(ga); + else if (buffer[i] == NUL) + ga_append(ga, NL); + else + ga_append(ga, buffer[i]); + } + } +# ifdef FEAT_MBYTE + else if (has_mbyte) + { + int l; + + len += *buffer_off; + buffer[len] = NUL; + + /* Check if the last character in buffer[] is + * incomplete, keep these bytes for the next + * round. */ + for (p = buffer; p < buffer + len; p += l) + { + l = mb_cptr2len(p); + if (l == 0) + l = 1; /* NUL byte? */ + else if (MB_BYTE2LEN(*p) != l) + break; + } + if (p == buffer) /* no complete character */ + { + /* avoid getting stuck at an illegal byte */ + if (len >= 12) + ++p; + else + { + *buffer_off = len; + return; + } + } + c = *p; + *p = NUL; + msg_puts(buffer); + if (p < buffer + len) + { + *p = c; + *buffer_off = (DWORD)((buffer + len) - p); + mch_memmove(buffer, p, *buffer_off); + return; + } + *buffer_off = 0; + } +# endif /* FEAT_MBYTE */ + else + { + buffer[len] = NUL; + msg_puts(buffer); + } + + windgoto(msg_row, msg_col); + cursor_on(); + out_flush(); + } +} + +/* + * Version of system to use for windows NT > 5.0 (Win2K), use pipe + * for communication and doesn't open any new window. + */ + static int +mch_system_piped(char *cmd, int options) +{ + STARTUPINFO si; + PROCESS_INFORMATION pi; + DWORD ret = 0; + + HANDLE g_hChildStd_IN_Rd = NULL; + HANDLE g_hChildStd_IN_Wr = NULL; + HANDLE g_hChildStd_OUT_Rd = NULL; + HANDLE g_hChildStd_OUT_Wr = NULL; + + char_u buffer[BUFLEN + 1]; /* reading buffer + size */ + DWORD len; + + /* buffer used to receive keys */ + char_u ta_buf[BUFLEN + 1]; /* TypeAHead */ + int ta_len = 0; /* valid bytes in ta_buf[] */ + + DWORD i; + int c; + int noread_cnt = 0; + garray_T ga; + int delay = 1; +# ifdef FEAT_MBYTE + DWORD buffer_off = 0; /* valid bytes in buffer[] */ +# endif + + SECURITY_ATTRIBUTES saAttr; + + /* Set the bInheritHandle flag so pipe handles are inherited. */ + saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); + saAttr.bInheritHandle = TRUE; + saAttr.lpSecurityDescriptor = NULL; + + if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) + /* Ensure the read handle to the pipe for STDOUT is not inherited. */ + || ! pSetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) + /* Create a pipe for the child process's STDIN. */ + || ! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0) + /* Ensure the write handle to the pipe for STDIN is not inherited. */ + || ! pSetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0) ) + { + CloseHandle(g_hChildStd_IN_Rd); + CloseHandle(g_hChildStd_IN_Wr); + CloseHandle(g_hChildStd_OUT_Rd); + CloseHandle(g_hChildStd_OUT_Wr); + MSG_PUTS(_("\nCannot create pipes\n")); + } + + si.cb = sizeof(si); + si.lpReserved = NULL; + si.lpDesktop = NULL; + si.lpTitle = NULL; + si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; + + /* set-up our file redirection */ + si.hStdError = g_hChildStd_OUT_Wr; + si.hStdOutput = g_hChildStd_OUT_Wr; + si.hStdInput = g_hChildStd_IN_Rd; + si.wShowWindow = SW_HIDE; + si.cbReserved2 = 0; + si.lpReserved2 = NULL; + + if (options & SHELL_READ) + ga_init2(&ga, 1, BUFLEN); + + /* Now, run the command */ + CreateProcess(NULL, /* Executable name */ + cmd, /* Command to execute */ + NULL, /* Process security attributes */ + NULL, /* Thread security attributes */ + + // this command can be litigeous, handle inheritence was + // deactivated for pending temp file, but, if we deactivate + // it, the pipes don't work for some reason. + TRUE, /* Inherit handles, first deactivated, + * but needed */ + CREATE_DEFAULT_ERROR_MODE, /* Creation flags */ + NULL, /* Environment */ + NULL, /* Current directory */ + &si, /* Startup information */ + &pi); /* Process information */ + + + /* Close our unused side of the pipes */ + CloseHandle(g_hChildStd_IN_Rd); + CloseHandle(g_hChildStd_OUT_Wr); + + if (options & SHELL_WRITE) + { + HANDLE thread = + CreateThread(NULL, /* security attributes */ + 0, /* default stack size */ + sub_process_writer, /* function to be executed */ + g_hChildStd_IN_Wr, /* parameter */ + 0, /* creation flag, start immediately */ + NULL); /* we don't care about thread id */ + CloseHandle(thread); + g_hChildStd_IN_Wr = NULL; + } + + /* Keep updating the window while waiting for the shell to finish. */ + for (;;) + { + MSG msg; + + if (PeekMessage(&msg, (HWND)NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + /* write pipe information in the window */ + if ((options & (SHELL_READ|SHELL_WRITE)) +# ifdef FEAT_GUI + || gui.in_use +# endif + ) + { + len = 0; + if (!(options & SHELL_EXPAND) + && ((options & + (SHELL_READ|SHELL_WRITE|SHELL_COOKED)) + != (SHELL_READ|SHELL_WRITE|SHELL_COOKED) +# ifdef FEAT_GUI + || gui.in_use +# endif + ) + && (ta_len > 0 || noread_cnt > 4)) + { + if (ta_len == 0) + { + /* Get extra characters when we don't have any. Reset the + * counter and timer. */ + noread_cnt = 0; +# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) + gettimeofday(&start_tv, NULL); +# endif + len = ui_inchar(ta_buf, BUFLEN, 10L, 0); + } + if (ta_len > 0 || len > 0) + { + /* + * For pipes: Check for CTRL-C: send interrupt signal to + * child. Check for CTRL-D: EOF, close pipe to child. + */ + if (len == 1 && cmd != NULL) + { + if (ta_buf[ta_len] == Ctrl_C) + { + /* Learn what exit code is expected, for + * now put 9 as SIGKILL */ + TerminateProcess(pi.hProcess, 9); + } + if (ta_buf[ta_len] == Ctrl_D) + { + CloseHandle(g_hChildStd_IN_Wr); + g_hChildStd_IN_Wr = NULL; + } + } + + /* replace K_BS by and K_DEL by */ + for (i = ta_len; i < ta_len + len; ++i) + { + if (ta_buf[i] == CSI && len - i > 2) + { + c = TERMCAP2KEY(ta_buf[i + 1], ta_buf[i + 2]); + if (c == K_DEL || c == K_KDEL || c == K_BS) + { + mch_memmove(ta_buf + i + 1, ta_buf + i + 3, + (size_t)(len - i - 2)); + if (c == K_DEL || c == K_KDEL) + ta_buf[i] = DEL; + else + ta_buf[i] = Ctrl_H; + len -= 2; + } + } + else if (ta_buf[i] == '\r') + ta_buf[i] = '\n'; +# ifdef FEAT_MBYTE + if (has_mbyte) + i += (*mb_ptr2len_len)(ta_buf + i, + ta_len + len - i) - 1; +# endif + } + + /* + * For pipes: echo the typed characters. For a pty this + * does not seem to work. + */ + for (i = ta_len; i < ta_len + len; ++i) + { + if (ta_buf[i] == '\n' || ta_buf[i] == '\b') + msg_putchar(ta_buf[i]); +# ifdef FEAT_MBYTE + else if (has_mbyte) + { + int l = (*mb_ptr2len)(ta_buf + i); + + msg_outtrans_len(ta_buf + i, l); + i += l - 1; + } +# endif + else + msg_outtrans_len(ta_buf + i, 1); + } + windgoto(msg_row, msg_col); + out_flush(); + + ta_len += len; + + /* + * Write the characters to the child, unless EOF has been + * typed for pipes. Write one character at a time, to + * avoid losing too much typeahead. When writing buffer + * lines, drop the typed characters (only check for + * CTRL-C). + */ + if (options & SHELL_WRITE) + ta_len = 0; + else if (g_hChildStd_IN_Wr != NULL) + { + WriteFile(g_hChildStd_IN_Wr, (char*)ta_buf, + 1, &len, NULL); + // if we are typing in, we want to keep things reactive + delay = 1; + if (len > 0) + { + ta_len -= len; + mch_memmove(ta_buf, ta_buf + len, ta_len); + } + } + } + } + } + + if (ta_len) + ui_inchar_undo(ta_buf, ta_len); + + if (WaitForSingleObject(pi.hProcess, delay) != WAIT_TIMEOUT) + { + dump_pipe(options, g_hChildStd_OUT_Rd, + &ga, buffer, &buffer_off); + break; + } + + ++noread_cnt; + dump_pipe(options, g_hChildStd_OUT_Rd, + &ga, buffer, &buffer_off); + + /* We start waiting for a very short time and then increase it, so + * that we respond quickly when the process is quick, and don't + * consume too much overhead when it's slow. */ + if (delay < 50) + delay += 10; + } + + /* Close the pipe */ + CloseHandle(g_hChildStd_OUT_Rd); + if (g_hChildStd_IN_Wr != NULL) + CloseHandle(g_hChildStd_IN_Wr); + + WaitForSingleObject(pi.hProcess, INFINITE); + + /* Get the command exit code */ + GetExitCodeProcess(pi.hProcess, &ret); + + if (options & SHELL_READ) + { + if (ga.ga_len > 0) + { + append_ga_line(&ga); + /* remember that the NL was missing */ + curbuf->b_no_eol_lnum = curwin->w_cursor.lnum; + } + else + curbuf->b_no_eol_lnum = 0; + ga_clear(&ga); + } + + /* Close the handles to the subprocess, so that it goes away */ + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + + return ret; +} + + static int +mch_system(char *cmd, int options) +{ + /* if we can pipe and the shelltemp option is off */ + if (allowPiping && !p_stmp) + return mch_system_piped(cmd, options); + else + return mch_system_classic(cmd, options); +} #else # define mch_system(c, o) system(c) @@ -3388,7 +3897,7 @@ mch_call_shell( char_u *newcmd; long_u cmdlen = ( #ifdef FEAT_GUI_W32 - STRLEN(vimrun_path) + + (allowPiping && !p_stmp ? 0 : STRLEN(vimrun_path)) + #endif STRLEN(p_sh) + STRLEN(p_shcf) + STRLEN(cmd) + 10); @@ -3497,7 +4006,7 @@ mch_call_shell( MB_ICONWARNING); need_vimrun_warning = FALSE; } - if (!s_dont_use_vimrun) + if (!s_dont_use_vimrun && (!allowPiping || p_stmp)) /* Use vimrun to execute the command. It opens a console * window, which can be closed without killing Vim. */ vim_snprintf((char *)newcmd, cmdlen, "%s%s%s %s %s", @@ -3521,7 +4030,8 @@ mch_call_shell( /* Print the return value, unless "vimrun" was used. */ if (x != 0 && !(options & SHELL_SILENT) && !emsg_silent #if defined(FEAT_GUI_W32) - && ((options & SHELL_DOOUT) || s_dont_use_vimrun) + && ((options & SHELL_DOOUT) || s_dont_use_vimrun + || (allowPiping && !p_stmp)) #endif ) { diff --git a/src/proto/misc2.pro b/src/proto/misc2.pro index a22ba7f0ae..d8d3cc374b 100644 --- a/src/proto/misc2.pro +++ b/src/proto/misc2.pro @@ -58,6 +58,7 @@ int ga_grow __ARGS((garray_T *gap, int n)); char_u *ga_concat_strings __ARGS((garray_T *gap)); void ga_concat __ARGS((garray_T *gap, char_u *s)); void ga_append __ARGS((garray_T *gap, int c)); +void append_ga_line __ARGS((garray_T *gap)); int name_to_mod_mask __ARGS((int c)); int simplify_key __ARGS((int key, int *modifiers)); int handle_x_keys __ARGS((int key)); diff --git a/src/ui.c b/src/ui.c index 82d83d3af4..3b0ae72488 100644 --- a/src/ui.c +++ b/src/ui.c @@ -58,7 +58,7 @@ ui_write(s, len) #endif } -#if defined(UNIX) || defined(VMS) || defined(PROTO) +#if defined(UNIX) || defined(VMS) || defined(PROTO) || defined(WIN3264) /* * When executing an external program, there may be some typed characters that * are not consumed by it. Give them back to ui_inchar() and they are stored diff --git a/src/version.c b/src/version.c index 8af816c080..2104c0f6a0 100644 --- a/src/version.c +++ b/src/version.c @@ -709,6 +709,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 240, /**/ 239, /**/ From a9c96dd4b486c19be7ef91eb3dfe3b7c4b011331 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 7 Jul 2011 16:20:52 +0200 Subject: [PATCH 06/34] Added tag v7-3-240 for changeset bf283e37792b --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 2110400b1b..d7d5bd2a42 100644 --- a/.hgtags +++ b/.hgtags @@ -1574,3 +1574,4 @@ c1733ef5b6e87dde521d0d85a1e5e62259854ac1 v7-3-236 e3bb93df6c34da672244bce5695c1426da139614 v7-3-237 f2c108f44f415c7cfe92862e791a01cc542ac378 v7-3-238 0bef86c5c985218a9448fa16d935b913e67af8d5 v7-3-239 +bf283e37792b4b557a2b9081e4fdb0e10acb9655 v7-3-240 From fd92d3e268daf1da7b93771b98bc329820efb7dd Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 7 Jul 2011 16:44:37 +0200 Subject: [PATCH 07/34] updated for version 7.3.241 Problem: Using CTRL-R CTRL-W on the command line may insert only part of the word. Solution: Use the cursor position instead of assuming it is at the end of the command. (Tyru) --- src/ex_getln.c | 4 ++-- src/version.c | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ex_getln.c b/src/ex_getln.c index 561ab970ee..913d9830ed 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -3046,7 +3046,7 @@ cmdline_paste(regname, literally, remcr) int len; /* Locate start of last word in the cmd buffer. */ - for (w = ccline.cmdbuff + ccline.cmdlen; w > ccline.cmdbuff; ) + for (w = ccline.cmdbuff + ccline.cmdpos; w > ccline.cmdbuff; ) { #ifdef FEAT_MBYTE if (has_mbyte) @@ -3064,7 +3064,7 @@ cmdline_paste(regname, literally, remcr) --w; } } - len = (int)((ccline.cmdbuff + ccline.cmdlen) - w); + len = (int)((ccline.cmdbuff + ccline.cmdpos) - w); if (p_ic ? STRNICMP(w, arg, len) == 0 : STRNCMP(w, arg, len) == 0) p += len; } diff --git a/src/version.c b/src/version.c index 2104c0f6a0..d9b50a6500 100644 --- a/src/version.c +++ b/src/version.c @@ -709,6 +709,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 241, /**/ 240, /**/ From 195add062077589da4c40752fd3b8ea99fa4998d Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 7 Jul 2011 16:44:38 +0200 Subject: [PATCH 08/34] Added tag v7-3-241 for changeset 0a650db02653 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index d7d5bd2a42..20cad66102 100644 --- a/.hgtags +++ b/.hgtags @@ -1575,3 +1575,4 @@ e3bb93df6c34da672244bce5695c1426da139614 v7-3-237 f2c108f44f415c7cfe92862e791a01cc542ac378 v7-3-238 0bef86c5c985218a9448fa16d935b913e67af8d5 v7-3-239 bf283e37792b4b557a2b9081e4fdb0e10acb9655 v7-3-240 +0a650db0265381b540df8ca6bd716c4b2d47dfc9 v7-3-241 From b20d2575d0c3d2d170700d32eef03691e2a6f1ac Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 7 Jul 2011 17:15:33 +0200 Subject: [PATCH 09/34] updated for version 7.3.242 Problem: Illegal memory access in after_pathsep(). Solution: Check that the pointer is not at the start of the file name. (Dominique Pelle) --- src/misc2.c | 4 ++-- src/version.c | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/misc2.c b/src/misc2.c index b7e7d01ea2..dfb1fc487f 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -3247,7 +3247,7 @@ get_real_state() #if defined(FEAT_MBYTE) || defined(PROTO) /* * Return TRUE if "p" points to just after a path separator. - * Take care of multi-byte characters. + * Takes care of multi-byte characters. * "b" must point to the start of the file name */ int @@ -3255,7 +3255,7 @@ after_pathsep(b, p) char_u *b; char_u *p; { - return vim_ispathsep(p[-1]) + return p > b && vim_ispathsep(p[-1]) && (!has_mbyte || (*mb_head_off)(b, p - 1) == 0); } #endif diff --git a/src/version.c b/src/version.c index d9b50a6500..4826a51544 100644 --- a/src/version.c +++ b/src/version.c @@ -709,6 +709,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 242, /**/ 241, /**/ From 8dd190f6117f2d949dae94a427fd65646c11bfb7 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 7 Jul 2011 17:15:33 +0200 Subject: [PATCH 10/34] Added tag v7-3-242 for changeset 3d96ddbeb3b0 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 20cad66102..9e944e62d1 100644 --- a/.hgtags +++ b/.hgtags @@ -1576,3 +1576,4 @@ f2c108f44f415c7cfe92862e791a01cc542ac378 v7-3-238 0bef86c5c985218a9448fa16d935b913e67af8d5 v7-3-239 bf283e37792b4b557a2b9081e4fdb0e10acb9655 v7-3-240 0a650db0265381b540df8ca6bd716c4b2d47dfc9 v7-3-241 +3d96ddbeb3b0003de29b736f63b76675909f133c v7-3-242 From b70aad41ed8d2ea8958b2c8935eecbd47563abe5 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 7 Jul 2011 17:36:56 +0200 Subject: [PATCH 11/34] updated for version 7.3.243 Problem: Illegal memory access in readline(). Solution: Swap the conditions. (Dominique Pelle) --- src/eval.c | 2 +- src/version.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/eval.c b/src/eval.c index e111707365..0ee5b7a0e9 100644 --- a/src/eval.c +++ b/src/eval.c @@ -14318,7 +14318,7 @@ f_readfile(argvars, rettv) tolist = 0; for ( ; filtd < buflen || readlen <= 0; ++filtd) { - if (buf[filtd] == '\n' || readlen <= 0) + if (readlen <= 0 || buf[filtd] == '\n') { /* In binary mode add an empty list item when the last * non-empty line ends in a '\n'. */ diff --git a/src/version.c b/src/version.c index 4826a51544..ae75308e51 100644 --- a/src/version.c +++ b/src/version.c @@ -709,6 +709,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 243, /**/ 242, /**/ From cf1628689a9d3ebb5574841e83491d9b217ca918 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 7 Jul 2011 17:36:57 +0200 Subject: [PATCH 12/34] Added tag v7-3-243 for changeset 512ddd87f1a8 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 9e944e62d1..f4f1846a93 100644 --- a/.hgtags +++ b/.hgtags @@ -1577,3 +1577,4 @@ f2c108f44f415c7cfe92862e791a01cc542ac378 v7-3-238 bf283e37792b4b557a2b9081e4fdb0e10acb9655 v7-3-240 0a650db0265381b540df8ca6bd716c4b2d47dfc9 v7-3-241 3d96ddbeb3b0003de29b736f63b76675909f133c v7-3-242 +512ddd87f1a817749c8362bd043682a7bbd87014 v7-3-243 From 9c42afa5501a4cba42bd8aece9a4edf324bdd01b Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 7 Jul 2011 17:43:41 +0200 Subject: [PATCH 13/34] updated for version 7.3.244 Problem: MS-Windows: Build problem with old compiler. (John Beckett) Solution: Only use HandleToLong() when available. (Mike Williams) --- src/gui_w32.c | 4 ++++ src/version.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/gui_w32.c b/src/gui_w32.c index 128869ee12..e4d25704f7 100644 --- a/src/gui_w32.c +++ b/src/gui_w32.c @@ -1574,6 +1574,10 @@ gui_mch_init(void) #endif #ifdef FEAT_EVAL +# if _MSC_VER < 1400 +/* HandleToLong() only exists in compilers that can do 64 bit builds */ +# define HandleToLong(h) ((long)(h)) +# endif /* set the v:windowid variable */ set_vim_var_nr(VV_WINDOWID, HandleToLong(s_hwnd)); #endif diff --git a/src/version.c b/src/version.c index ae75308e51..423b24b869 100644 --- a/src/version.c +++ b/src/version.c @@ -709,6 +709,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 244, /**/ 243, /**/ From ff3e697c621deafdab056c808c7cdbc2b47713e1 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 7 Jul 2011 17:43:42 +0200 Subject: [PATCH 14/34] Added tag v7-3-244 for changeset be6b65096362 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index f4f1846a93..0a93c151b6 100644 --- a/.hgtags +++ b/.hgtags @@ -1578,3 +1578,4 @@ bf283e37792b4b557a2b9081e4fdb0e10acb9655 v7-3-240 0a650db0265381b540df8ca6bd716c4b2d47dfc9 v7-3-241 3d96ddbeb3b0003de29b736f63b76675909f133c v7-3-242 512ddd87f1a817749c8362bd043682a7bbd87014 v7-3-243 +be6b6509636242cd7e6fab9a4b8772e97fc9a0db v7-3-244 From 5aa313472ee80795aec52bae3b8792c77a77f487 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 15 Jul 2011 13:09:51 +0200 Subject: [PATCH 15/34] updated for version 7.3.245 Problem: Python 3.2 libraries not correctly detected. Solution: Add the suffix to the library name. (Niclas Zeising) --- src/auto/configure | 2 +- src/configure.in | 2 +- src/version.c | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/auto/configure b/src/auto/configure index 115664fa8a..ea39c3f259 100755 --- a/src/auto/configure +++ b/src/auto/configure @@ -5611,7 +5611,7 @@ __: eof eval "`cd ${PYTHON3_CONFDIR} && make -f "${tmp_mkf}" __ | sed '/ directory /d'`" rm -f -- "${tmp_mkf}" - vi_cv_path_python3_plibs="-L${PYTHON3_CONFDIR} -lpython${vi_cv_var_python3_version}" + vi_cv_path_python3_plibs="-L${PYTHON3_CONFDIR} -lpython${vi_cv_var_python3_version}${vi_cv_var_python3_abiflags}" vi_cv_path_python3_plibs="${vi_cv_path_python3_plibs} ${python3_BASEMODLIBS} ${python3_LIBS} ${python3_SYSLIBS}" vi_cv_path_python3_plibs=`echo $vi_cv_path_python3_plibs | sed s/-ltermcap//` vi_cv_path_python3_plibs=`echo $vi_cv_path_python3_plibs | sed s/-lffi//` diff --git a/src/configure.in b/src/configure.in index 173818805a..52e0600c89 100644 --- a/src/configure.in +++ b/src/configure.in @@ -1068,7 +1068,7 @@ eof dnl -- delete the lines from make about Entering/Leaving directory eval "`cd ${PYTHON3_CONFDIR} && make -f "${tmp_mkf}" __ | sed '/ directory /d'`" rm -f -- "${tmp_mkf}" - vi_cv_path_python3_plibs="-L${PYTHON3_CONFDIR} -lpython${vi_cv_var_python3_version}" + vi_cv_path_python3_plibs="-L${PYTHON3_CONFDIR} -lpython${vi_cv_var_python3_version}${vi_cv_var_python3_abiflags}" vi_cv_path_python3_plibs="${vi_cv_path_python3_plibs} ${python3_BASEMODLIBS} ${python3_LIBS} ${python3_SYSLIBS}" dnl remove -ltermcap, it can conflict with an earlier -lncurses vi_cv_path_python3_plibs=`echo $vi_cv_path_python3_plibs | sed s/-ltermcap//` diff --git a/src/version.c b/src/version.c index 423b24b869..77d3dc0eb7 100644 --- a/src/version.c +++ b/src/version.c @@ -709,6 +709,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 245, /**/ 244, /**/ From f752a1288f0e3a3ebf1093ff68313a702903f38e Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 15 Jul 2011 13:09:51 +0200 Subject: [PATCH 16/34] Added tag v7-3-245 for changeset 52512eddb876 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 0a93c151b6..ac8f91a2e7 100644 --- a/.hgtags +++ b/.hgtags @@ -1579,3 +1579,4 @@ bf283e37792b4b557a2b9081e4fdb0e10acb9655 v7-3-240 3d96ddbeb3b0003de29b736f63b76675909f133c v7-3-242 512ddd87f1a817749c8362bd043682a7bbd87014 v7-3-243 be6b6509636242cd7e6fab9a4b8772e97fc9a0db v7-3-244 +52512eddb876f64399e98d12643233a87c9f2823 v7-3-245 From 78f1705c399e77bcc016d63234721f479a2fea2c Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 15 Jul 2011 13:21:30 +0200 Subject: [PATCH 17/34] updated for version 7.3.246 Problem: Repeating "f4" in "4444" skips one 4. Solution: Check the t_cmd flag. (Christian Brabandt) --- src/search.c | 2 +- src/version.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/search.c b/src/search.c index 6c9e1dae91..0d0d26d810 100644 --- a/src/search.c +++ b/src/search.c @@ -1585,7 +1585,7 @@ searchc(cap, t_cmd) /* Force a move of at least one char, so ";" and "," will move the * cursor, even if the cursor is right in front of char we are looking * at. */ - if (vim_strchr(p_cpo, CPO_SCOLON) == NULL && count == 1) + if (vim_strchr(p_cpo, CPO_SCOLON) == NULL && count == 1 && t_cmd) stop = FALSE; } diff --git a/src/version.c b/src/version.c index 77d3dc0eb7..2f4e229d83 100644 --- a/src/version.c +++ b/src/version.c @@ -709,6 +709,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 246, /**/ 245, /**/ From be9bf38b00d0aad28b673b5cf916009905c9295e Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 15 Jul 2011 13:21:30 +0200 Subject: [PATCH 18/34] Added tag v7-3-246 for changeset 3f1a4ed36d1b --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index ac8f91a2e7..b7680c4ab4 100644 --- a/.hgtags +++ b/.hgtags @@ -1580,3 +1580,4 @@ bf283e37792b4b557a2b9081e4fdb0e10acb9655 v7-3-240 512ddd87f1a817749c8362bd043682a7bbd87014 v7-3-243 be6b6509636242cd7e6fab9a4b8772e97fc9a0db v7-3-244 52512eddb876f64399e98d12643233a87c9f2823 v7-3-245 +3f1a4ed36d1b520a1ad5aa6cbf50d68bc8b9c7a5 v7-3-246 From 9d86f0c5430fdb07423067146ef47a02d56ca33a Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 15 Jul 2011 13:33:21 +0200 Subject: [PATCH 19/34] updated for version 7.3.247 Problem: Running tests changes the users viminfo file. Test for patch 7.3.245 missing. Solution: Add "nviminfo" to the 'viminfo' option. Include the test. --- src/testdir/test78.in | 2 +- src/testdir/test81.in | 6 +++++- src/version.c | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/testdir/test78.in b/src/testdir/test78.in index bcbc972432..1850bd9236 100644 --- a/src/testdir/test78.in +++ b/src/testdir/test78.in @@ -6,7 +6,7 @@ blocks. STARTTEST :so small.vim -:set nocp fileformat=unix undolevels=-1 +:set nocp fileformat=unix undolevels=-1 viminfo+=nviminfo :e! Xtest ggdG :let text = "\tabcdefghijklmnoparstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnoparstuvwxyz0123456789" diff --git a/src/testdir/test81.in b/src/testdir/test81.in index e47653fd9e..82a6892a1d 100644 --- a/src/testdir/test81.in +++ b/src/testdir/test81.in @@ -1,10 +1,12 @@ Test for t movement command and 'cpo-;' setting STARTTEST -:set nocompatible +:set nocompatible viminfo+=nviminfo :set cpo-=; /firstline/ j0tt;D +0fz;D +$Fy;D $Ty;D:set cpo+=; j0tt;;D $Ty;;D:?firstline?+1,$w! test.out @@ -13,6 +15,8 @@ ENDTEST firstline aaa two three four + zzz +yyy bbb yee yoo four ccc two three four ddd yee yoo four diff --git a/src/version.c b/src/version.c index 2f4e229d83..fcc37ccb0d 100644 --- a/src/version.c +++ b/src/version.c @@ -709,6 +709,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 247, /**/ 246, /**/ From 7322c3ba4b8f2a5831ba3a18b952bd1bf674a8a4 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 15 Jul 2011 13:33:21 +0200 Subject: [PATCH 20/34] Added tag v7-3-247 for changeset 7fe2c092913e --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index b7680c4ab4..0b8d4dd998 100644 --- a/.hgtags +++ b/.hgtags @@ -1581,3 +1581,4 @@ bf283e37792b4b557a2b9081e4fdb0e10acb9655 v7-3-240 be6b6509636242cd7e6fab9a4b8772e97fc9a0db v7-3-244 52512eddb876f64399e98d12643233a87c9f2823 v7-3-245 3f1a4ed36d1b520a1ad5aa6cbf50d68bc8b9c7a5 v7-3-246 +7fe2c092913e84e6717782da1f1a220069eebbe7 v7-3-247 From 7c4547bf99b8d0100990c0511cfd540596f9de2b Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 15 Jul 2011 13:52:04 +0200 Subject: [PATCH 21/34] updated for version 7.3.248 Problem: PC Install instructions missing install instructions. Solution: Step-by-step explanation. (Michael Soyka) --- src/INSTALLpc.txt | 65 ++++++++++++++++++++++++++++++++++++++++++++--- src/version.c | 2 ++ 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/src/INSTALLpc.txt b/src/INSTALLpc.txt index 124bdc3b9d..aeabda6de6 100644 --- a/src/INSTALLpc.txt +++ b/src/INSTALLpc.txt @@ -11,9 +11,9 @@ The file "feature.h" can be edited to match your preferences. You can skip this, then you will get the default behavior as is documented, which should be fine for most people. -With the exception of the last two sections (Windows 3.1 and MS-DOS), -this document assumes that you are building Vim for Win32 -(Windows NT/2000/XP/2003/Vista and Windows 95/98/Me) +With the exception of two sections (Windows 3.1 and MS-DOS), this document +assumes that you are building Vim for Win32 or later. +(Windows 95/98/Me/NT/2000/XP/2003/Vista/7) Contents: @@ -27,6 +27,9 @@ Contents: 8. Windows 3.1 9. MS-DOS +10. Installing after building from sources + + The currently preferred method is using the free Visual C++ Toolkit 2008 |msvc-2008-express|, the produced binary runs on most MS-Windows systems. If you need the executable to run on Windows 98 or ME, use the 2003 one @@ -409,3 +412,59 @@ will work properly! Esp. handling multi-byte file names. If you get all kinds of strange error messages when compiling, try adding changing the file format from "unix" to "dos". + + +10. Installing after building from sources +========================================== + +[provided by Michael Soyka] + +After you've built the Vim binaries as described above, you're ready to +install Vim on your system. However, if you've obtained the Vim sources +using Mercurial or by downloading them as a unix tar file, you must first +create a "vim73" directory. If you instead downloaded the sources as +zip files, you can skip this setup as the zip archives already have the +correct directory structure. + + A. Create a Vim "runtime" subdirectory named "vim73" + ----------------------------------------------------- + If you obtained your Vim sources as zip files, you can skip this step. + Otherwise, continue reading. + + Go to the directory that contains the Vim "src" and "runtime" + directories and create a new subdirectory named "vim73". + + Copy the "runtime" files into "vim73": + copy runtime\* vim73 + + B. Copy the new binaries into the "vim73" directory + ---------------------------------------------------- + Regardless of how you installed the Vim sources, you need to copy the + new binaries you created above into "vim73": + + copy src\*.exe vim73 + copy src\GvimExt\gvimext.dll vim73 + copy src\xxd\xxd.exe vim73 + + C. Move the "vim73" directory into the Vim installation subdirectory + --------------------------------------------------------------------- + Move the "vim73" subdirectory into the subdirectory where you want Vim + to be installed. Typically, this subdirectory will be named "vim". + If you already have a "vim73" subdirectory in "vim", delete it first + by running its unstal.exe program. + + D. Install Vim + --------------- + "cd" to your Vim installation subdirectory "vim\vim73" and run the + "install.exe" program. It will ask you a number of questions about + how you would like to have your Vim setup. Among these are: + - You can tell it to write a "_vimrc" file with your preferences in the + parent directory. + - It can also install an "Edit with Vim" entry in the Windows Explorer + popup menu. + - You can have it create batch files, so that you can run Vim from the + console or in a shell. You can select one of the directories in your + PATH or add the directory to PATH using the Windows Control Panel. + - Create entries for Vim on the desktop and in the Start menu. + +Happy Vimming! diff --git a/src/version.c b/src/version.c index fcc37ccb0d..a501f5e14a 100644 --- a/src/version.c +++ b/src/version.c @@ -709,6 +709,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 248, /**/ 247, /**/ From 1f1e41911ef7753e1cb3fdcb62e9effbe6b482b3 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 15 Jul 2011 13:52:04 +0200 Subject: [PATCH 22/34] Added tag v7-3-248 for changeset 57a7998e0fa8 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 0b8d4dd998..7e76b3d666 100644 --- a/.hgtags +++ b/.hgtags @@ -1582,3 +1582,4 @@ be6b6509636242cd7e6fab9a4b8772e97fc9a0db v7-3-244 52512eddb876f64399e98d12643233a87c9f2823 v7-3-245 3f1a4ed36d1b520a1ad5aa6cbf50d68bc8b9c7a5 v7-3-246 7fe2c092913e84e6717782da1f1a220069eebbe7 v7-3-247 +57a7998e0fa8854a7a8c3946df1d4c9b1ee220e5 v7-3-248 From ddc01469a8d4e770ad0c5aec0ded667a1a84b7f6 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 15 Jul 2011 14:12:30 +0200 Subject: [PATCH 23/34] updated for version 7.3.249 Problem: Wrong indenting for array initializer. Solution: Detect '}' in a better way. (Lech Lorens) --- src/misc1.c | 3 +-- src/testdir/test3.in | 30 ++++++++++++++++++++++++++++++ src/testdir/test3.ok | 25 +++++++++++++++++++++++++ src/version.c | 2 ++ 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/misc1.c b/src/misc1.c index d69f12fd29..c7f2f80596 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -7945,8 +7945,7 @@ term_again: * If we're at the end of a block, skip to the start of * that block. */ - curwin->w_cursor.col = 0; - if (*cin_skipcomment(l) == '}' + if (find_last_paren(l, '{', '}') && (trypos = find_start_brace(ind_maxcomment)) != NULL) /* XXX */ { diff --git a/src/testdir/test3.in b/src/testdir/test3.in index 1cfd8f23ee..aea055fb3a 100644 --- a/src/testdir/test3.in +++ b/src/testdir/test3.in @@ -1450,6 +1450,36 @@ void func3(void) printf("Don't you dare indent this line incorrectly!\n); } +STARTTEST +:set cino& +:set cino+=l1 +2kdd=][ +ENDTEST + +void func(void) +{ + int tab[] = + { + 1, 2, 3, + 4, 5, 6}; + + printf("Indent this line correctly!\n"); + + switch (foo) + { + case bar: + printf("bar"); + break; + case baz: { + printf("baz"); + break; + } + case quux: +printf("But don't break the indentation of this instruction\n"); +break; + } +} + STARTTEST :set cino& 2kdd=][ diff --git a/src/testdir/test3.ok b/src/testdir/test3.ok index 8475aff9fe..a475669310 100644 --- a/src/testdir/test3.ok +++ b/src/testdir/test3.ok @@ -1308,6 +1308,31 @@ void func3(void) } +void func(void) +{ + int tab[] = + { + 1, 2, 3, + 4, 5, 6}; + + printf("Indent this line correctly!\n"); + + switch (foo) + { + case bar: + printf("bar"); + break; + case baz: { + printf("baz"); + break; + } + case quux: + printf("But don't break the indentation of this instruction\n"); + break; + } +} + + void func(void) { cout << "a" diff --git a/src/version.c b/src/version.c index a501f5e14a..a138681069 100644 --- a/src/version.c +++ b/src/version.c @@ -709,6 +709,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 249, /**/ 248, /**/ From bea434d7ad0def7ac89dc1e1ee50edfb8b012152 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 15 Jul 2011 14:12:31 +0200 Subject: [PATCH 24/34] Added tag v7-3-249 for changeset 9f71f5a526af --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 7e76b3d666..68b29cf4c5 100644 --- a/.hgtags +++ b/.hgtags @@ -1583,3 +1583,4 @@ be6b6509636242cd7e6fab9a4b8772e97fc9a0db v7-3-244 3f1a4ed36d1b520a1ad5aa6cbf50d68bc8b9c7a5 v7-3-246 7fe2c092913e84e6717782da1f1a220069eebbe7 v7-3-247 57a7998e0fa8854a7a8c3946df1d4c9b1ee220e5 v7-3-248 +9f71f5a526aff4f1e0eefe1068d9534aee427afa v7-3-249 From 187319ac73c3d6ea8b67f0f8b833c9c0beb90676 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 15 Jul 2011 15:54:44 +0200 Subject: [PATCH 25/34] updated for version 7.3.250 Problem: Python: Errors in Unicode characters not handled nicely. Solution: Add the surrogateescape error handler. (lilydjwg) --- src/if_python3.c | 16 ++++++++++++---- src/version.c | 2 ++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/if_python3.c b/src/if_python3.c index b16dfc68ab..023a773e21 100644 --- a/src/if_python3.c +++ b/src/if_python3.c @@ -68,9 +68,16 @@ static void init_structs(void); +/* The "surrogateescape" error handler is new in Python 3.1 */ +#if PY_VERSION_HEX >= 0x030100f0 +# define CODEC_ERROR_HANDLER "surrogateescape" +#else +# define CODEC_ERROR_HANDLER NULL +#endif + #define PyInt Py_ssize_t #define PyString_Check(obj) PyUnicode_Check(obj) -#define PyString_AsBytes(obj) PyUnicode_AsEncodedString(obj, (char *)ENC_OPT, NULL); +#define PyString_AsBytes(obj) PyUnicode_AsEncodedString(obj, (char *)ENC_OPT, CODEC_ERROR_HANDLER); #define PyString_FreeBytes(obj) Py_XDECREF(bytes) #define PyString_AsString(obj) PyBytes_AsString(obj) #define PyString_Size(obj) PyBytes_GET_SIZE(bytes) @@ -661,8 +668,9 @@ DoPy3Command(exarg_T *eap, const char *cmd) /* PyRun_SimpleString expects a UTF-8 string. Wrong encoding may cause * SyntaxError (unicode error). */ - cmdstr = PyUnicode_Decode(cmd, strlen(cmd), (char *)ENC_OPT, NULL); - cmdbytes = PyUnicode_AsEncodedString(cmdstr, "utf-8", NULL); + cmdstr = PyUnicode_Decode(cmd, strlen(cmd), + (char *)ENC_OPT, CODEC_ERROR_HANDLER); + cmdbytes = PyUnicode_AsEncodedString(cmdstr, "utf-8", CODEC_ERROR_HANDLER); Py_XDECREF(cmdstr); PyRun_SimpleString(PyBytes_AsString(cmdbytes)); Py_XDECREF(cmdbytes); @@ -1463,7 +1471,7 @@ LineToString(const char *str) } *p = '\0'; - result = PyUnicode_Decode(tmp, len, (char *)ENC_OPT, NULL); + result = PyUnicode_Decode(tmp, len, (char *)ENC_OPT, CODEC_ERROR_HANDLER); vim_free(tmp); return result; diff --git a/src/version.c b/src/version.c index a138681069..ffed791cfd 100644 --- a/src/version.c +++ b/src/version.c @@ -709,6 +709,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 250, /**/ 249, /**/ From 44d2f391c9c43e1453fb3a9a38669afa29a02a5f Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 15 Jul 2011 15:54:44 +0200 Subject: [PATCH 26/34] Added tag v7-3-250 for changeset f909f4f0f38c --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 68b29cf4c5..2f178016b8 100644 --- a/.hgtags +++ b/.hgtags @@ -1584,3 +1584,4 @@ be6b6509636242cd7e6fab9a4b8772e97fc9a0db v7-3-244 7fe2c092913e84e6717782da1f1a220069eebbe7 v7-3-247 57a7998e0fa8854a7a8c3946df1d4c9b1ee220e5 v7-3-248 9f71f5a526aff4f1e0eefe1068d9534aee427afa v7-3-249 +f909f4f0f38c71594266b3595d31ce04d4ebe3ec v7-3-250 From 37573a22d4ba2a12cb9902ce8ae6c4cd3d459993 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 15 Jul 2011 17:51:34 +0200 Subject: [PATCH 27/34] updated for version 7.3.251 Problem: "gH" deletes the current line, except when it's the last line. Solution: Set the "include" flag to indicate the last line is to be deleted. --- src/normal.c | 24 ++++++++++++++++-------- src/ops.c | 41 ++++++++++++++++++++++++++++++++--------- src/version.c | 2 ++ 3 files changed, 50 insertions(+), 17 deletions(-) diff --git a/src/normal.c b/src/normal.c index 522480fc4a..c028feaaaf 100644 --- a/src/normal.c +++ b/src/normal.c @@ -1795,17 +1795,25 @@ do_pending_operator(cap, old_col, gui_yank) { oap->inclusive = FALSE; /* Try to include the newline, unless it's an operator - * that works on lines only */ - if (*p_sel != 'o' - && !op_on_lines(oap->op_type) - && oap->end.lnum < curbuf->b_ml.ml_line_count) + * that works on lines only. */ + if (*p_sel != 'o' && !op_on_lines(oap->op_type)) { - ++oap->end.lnum; - oap->end.col = 0; + if (oap->end.lnum < curbuf->b_ml.ml_line_count) + { + ++oap->end.lnum; + oap->end.col = 0; # ifdef FEAT_VIRTUALEDIT - oap->end.coladd = 0; + oap->end.coladd = 0; # endif - ++oap->line_count; + ++oap->line_count; + } + else + { + /* Cannot move below the last line, make the op + * inclusive to tell the operation to include the + * line break. */ + oap->inclusive = TRUE; + } } } } diff --git a/src/ops.c b/src/ops.c index 8c235220e5..bdc53de33b 100644 --- a/src/ops.c +++ b/src/ops.c @@ -1650,7 +1650,9 @@ op_delete(oap) && oap->line_count > 1 && oap->op_type == OP_DELETE) { - ptr = ml_get(oap->end.lnum) + oap->end.col + oap->inclusive; + ptr = ml_get(oap->end.lnum) + oap->end.col; + if (*ptr != NUL) + ptr += oap->inclusive; ptr = skipwhite(ptr); if (*ptr == NUL && inindent(0)) oap->motion_type = MLINE; @@ -1920,11 +1922,20 @@ op_delete(oap) curwin->w_cursor.coladd = 0; } #endif - (void)del_bytes((long)n, !virtual_op, oap->op_type == OP_DELETE + if (oap->inclusive && oap->end.lnum == curbuf->b_ml.ml_line_count + && n > (int)STRLEN(ml_get(oap->end.lnum))) + { + /* Special case: gH deletes the last line. */ + del_lines(1L, FALSE); + } + else + { + (void)del_bytes((long)n, !virtual_op, oap->op_type == OP_DELETE #ifdef FEAT_VISUAL && !oap->is_VIsual #endif ); + } } else /* delete characters between lines */ { @@ -1941,17 +1952,29 @@ op_delete(oap) ++curwin->w_cursor.lnum; del_lines((long)(oap->line_count - 2), FALSE); - /* delete from start of line until op_end */ - curwin->w_cursor.col = 0; - (void)del_bytes((long)(oap->end.col + 1 - !oap->inclusive), - !virtual_op, oap->op_type == OP_DELETE + n = (oap->end.col + 1 - !oap->inclusive); + if (oap->inclusive && oap->end.lnum == curbuf->b_ml.ml_line_count + && n > (int)STRLEN(ml_get(oap->end.lnum))) + { + /* Special case: gH deletes the last line. */ + del_lines(1L, FALSE); + curwin->w_cursor = curpos; /* restore curwin->w_cursor */ + if (curwin->w_cursor.lnum > 1) + --curwin->w_cursor.lnum; + } + else + { + /* delete from start of line until op_end */ + curwin->w_cursor.col = 0; + (void)del_bytes((long)n, !virtual_op, oap->op_type == OP_DELETE #ifdef FEAT_VISUAL && !oap->is_VIsual #endif ); - curwin->w_cursor = curpos; /* restore curwin->w_cursor */ - - (void)do_join(2, FALSE, FALSE); + curwin->w_cursor = curpos; /* restore curwin->w_cursor */ + } + if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) + (void)do_join(2, FALSE, FALSE); } } diff --git a/src/version.c b/src/version.c index ffed791cfd..170e2fecf3 100644 --- a/src/version.c +++ b/src/version.c @@ -709,6 +709,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 251, /**/ 250, /**/ From 4616dfcd3af842ffe909af71a17eefeaeb87ef35 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 15 Jul 2011 17:51:34 +0200 Subject: [PATCH 28/34] Added tag v7-3-251 for changeset fe6ad3fd8532 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 2f178016b8..780bfd7546 100644 --- a/.hgtags +++ b/.hgtags @@ -1585,3 +1585,4 @@ be6b6509636242cd7e6fab9a4b8772e97fc9a0db v7-3-244 57a7998e0fa8854a7a8c3946df1d4c9b1ee220e5 v7-3-248 9f71f5a526aff4f1e0eefe1068d9534aee427afa v7-3-249 f909f4f0f38c71594266b3595d31ce04d4ebe3ec v7-3-250 +fe6ad3fd85322b394824a5c495a78061a747b074 v7-3-251 From 803d8bdfb435fbcdaf92077daf597687e5b283b2 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 15 Jul 2011 17:56:16 +0200 Subject: [PATCH 29/34] updated for version 7.3.252 Problem: Tests fail. (David Northfield) Solution: Add missing update for .ok file. --- src/testdir/test81.ok | 2 ++ src/version.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/testdir/test81.ok b/src/testdir/test81.ok index 8f86b521ee..e9f17dc4f8 100644 --- a/src/testdir/test81.ok +++ b/src/testdir/test81.ok @@ -1,4 +1,6 @@ aaa two + z +y bbb y ccc ddd yee y diff --git a/src/version.c b/src/version.c index 170e2fecf3..f206664f58 100644 --- a/src/version.c +++ b/src/version.c @@ -709,6 +709,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 252, /**/ 251, /**/ From c9cf2496c75bfae37efee0ed389788b63240a789 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 15 Jul 2011 17:56:16 +0200 Subject: [PATCH 30/34] Added tag v7-3-252 for changeset 0b4289bcf836 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 780bfd7546..b5dd752fdf 100644 --- a/.hgtags +++ b/.hgtags @@ -1586,3 +1586,4 @@ be6b6509636242cd7e6fab9a4b8772e97fc9a0db v7-3-244 9f71f5a526aff4f1e0eefe1068d9534aee427afa v7-3-249 f909f4f0f38c71594266b3595d31ce04d4ebe3ec v7-3-250 fe6ad3fd85322b394824a5c495a78061a747b074 v7-3-251 +0b4289bcf8364854dd5f94c42d0252504103e5b9 v7-3-252 From fa6185ce5251d31dead16ceb66506d0451b314ff Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 15 Jul 2011 21:16:59 +0200 Subject: [PATCH 31/34] updated for version 7.3.253 Problem: "echo 'abc' > ''" returns 0 or 1, depending on 'ignorecase'. Checks in mb_strnicmp() for illegal and truncated bytes are wrong. Should not assume that byte length is equal before case folding. Solution: Add utf_safe_read_char_adv() and utf_strnicmp(). Add a test for this. (Ivan Krasilnikov) --- src/mbyte.c | 186 +++++++++++++++++++++++++++++-------- src/testdir/Make_amiga.mak | 3 +- src/testdir/Make_dos.mak | 2 +- src/testdir/Make_ming.mak | 2 +- src/testdir/Make_os2.mak | 2 +- src/testdir/Make_vms.mms | 5 +- src/testdir/Makefile | 2 +- src/version.c | 2 + 8 files changed, 158 insertions(+), 46 deletions(-) diff --git a/src/mbyte.c b/src/mbyte.c index 6e0dbf6549..88599264b0 100644 --- a/src/mbyte.c +++ b/src/mbyte.c @@ -132,6 +132,7 @@ static int utf_ptr2cells_len __ARGS((char_u *p, int size)); static int dbcs_char2cells __ARGS((int c)); static int dbcs_ptr2cells_len __ARGS((char_u *p, int size)); static int dbcs_ptr2char __ARGS((char_u *p)); +static int utf_safe_read_char_adv __ARGS((char_u **s, size_t *n)); /* * Lookup table to quickly get the length in bytes of a UTF-8 character from @@ -1700,6 +1701,66 @@ utf_ptr2char(p) return p[0]; } +/* + * Convert a UTF-8 byte sequence to a wide character. + * String is assumed to be terminated by NUL or after "n" bytes, whichever + * comes first. + * The function is safe in the sense that it never accesses memory beyond the + * first "n" bytes of "s". + * + * On success, returns decoded codepoint, advances "s" to the beginning of + * next character and decreases "n" accordingly. + * + * If end of string was reached, returns 0 and, if "n" > 0, advances "s" past + * NUL byte. + * + * If byte sequence is illegal or incomplete, returns -1 and does not advance + * "s". + */ + static int +utf_safe_read_char_adv(s, n) + char_u **s; + size_t *n; +{ + int c, k; + + if (*n == 0) /* end of buffer */ + return 0; + + k = utf8len_tab_zero[**s]; + + if (k == 1) + { + /* ASCII character or NUL */ + (*n)--; + return *(*s)++; + } + + if ((size_t)k <= *n) + { + /* We have a multibyte sequence and it isn't truncated by buffer + * limits so utf_ptr2char() is safe to use. Or the first byte is + * illegal (k=0), and it's also safe to use utf_ptr2char(). */ + c = utf_ptr2char(*s); + + /* On failure, utf_ptr2char() returns the first byte, so here we + * check equality with the first byte. The only non-ASCII character + * which equals the first byte of its own UTF-8 representation is + * U+00C3 (UTF-8: 0xC3 0x83), so need to check that special case too. + * It's safe even if n=1, else we would have k=2 > n. */ + if (c != (int)(**s) || (c == 0xC3 && (*s)[1] == 0x83)) + { + /* byte sequence was successfully decoded */ + *s += k; + *n -= k; + return c; + } + } + + /* byte sequence is incomplete or illegal */ + return -1; +} + /* * Get character at **pp and advance *pp to the next character. * Note: composing characters are skipped! @@ -2667,7 +2728,8 @@ static convertStruct foldCase[] = {0x10400,0x10427,1,40} }; -static int utf_convert(int a, convertStruct table[], int tableSize); +static int utf_convert __ARGS((int a, convertStruct table[], int tableSize)); +static int utf_strnicmp __ARGS((char_u *s1, char_u *s2, size_t n1, size_t n2)); /* * Generic conversion function for case operations. @@ -3079,6 +3141,80 @@ utf_isupper(a) return (utf_tolower(a) != a); } + static int +utf_strnicmp(s1, s2, n1, n2) + char_u *s1, *s2; + size_t n1, n2; +{ + int c1, c2, cdiff; + char_u buffer[6]; + + for (;;) + { + c1 = utf_safe_read_char_adv(&s1, &n1); + c2 = utf_safe_read_char_adv(&s2, &n2); + + if (c1 <= 0 || c2 <= 0) + break; + + if (c1 == c2) + continue; + + cdiff = utf_fold(c1) - utf_fold(c2); + if (cdiff != 0) + return cdiff; + } + + /* some string ended or has an incomplete/illegal character sequence */ + + if (c1 == 0 || c2 == 0) + { + /* some string ended. shorter string is smaller */ + if (c1 == 0 && c2 == 0) + return 0; + return c1 == 0 ? -1 : 1; + } + + /* Continue with bytewise comparison to produce some result that + * would make comparison operations involving this function transitive. + * + * If only one string had an error, comparison should be made with + * folded version of the other string. In this case it is enough + * to fold just one character to determine the result of comparison. */ + + if (c1 != -1 && c2 == -1) + { + n1 = utf_char2bytes(utf_fold(c1), buffer); + s1 = buffer; + } + else if (c2 != -1 && c1 == -1) + { + n2 = utf_char2bytes(utf_fold(c2), buffer); + s2 = buffer; + } + + while (n1 > 0 && n2 > 0 && *s1 != NUL && *s2 != NUL) + { + cdiff = (int)(*s1) - (int)(*s2); + if (cdiff != 0) + return cdiff; + + s1++; + s2++; + n1--; + n2--; + } + + if (n1 > 0 && *s1 == NUL) + n1 = 0; + if (n2 > 0 && *s2 == NUL) + n2 = 0; + + if (n1 == 0 && n2 == 0) + return 0; + return n1 == 0 ? -1 : 1; +} + /* * Version of strnicmp() that handles multi-byte characters. * Needed for Big5, Sjift-JIS and UTF-8 encoding. Other DBCS encodings can @@ -3092,49 +3228,21 @@ mb_strnicmp(s1, s2, nn) char_u *s1, *s2; size_t nn; { - int i, j, l; + int i, l; int cdiff; - int incomplete = FALSE; int n = (int)nn; - for (i = 0; i < n; i += l) + if (enc_utf8) { - if (s1[i] == NUL && s2[i] == NUL) /* both strings end */ - return 0; - if (enc_utf8) - { - l = utf_byte2len(s1[i]); - if (l > n - i) - { - l = n - i; /* incomplete character */ - incomplete = TRUE; - } - /* Check directly first, it's faster. */ - for (j = 0; j < l; ++j) - { - if (s1[i + j] != s2[i + j]) - break; - if (s1[i + j] == 0) - /* Both stings have the same bytes but are incomplete or - * have illegal bytes, accept them as equal. */ - l = j; - } - if (j < l) - { - /* If one of the two characters is incomplete return -1. */ - if (incomplete || i + utf_byte2len(s2[i]) > n) - return -1; - /* Don't case-fold illegal bytes or truncated characters. */ - if (utf_ptr2len(s1 + i) < l || utf_ptr2len(s2 + i) < l) - return -1; - cdiff = utf_fold(utf_ptr2char(s1 + i)) - - utf_fold(utf_ptr2char(s2 + i)); - if (cdiff != 0) - return cdiff; - } - } - else + return utf_strnicmp(s1, s2, nn, nn); + } + else + { + for (i = 0; i < n; i += l) { + if (s1[i] == NUL && s2[i] == NUL) /* both strings end */ + return 0; + l = (*mb_ptr2len)(s1 + i); if (l <= 1) { diff --git a/src/testdir/Make_amiga.mak b/src/testdir/Make_amiga.mak index f3035b18fc..55d13e48f3 100644 --- a/src/testdir/Make_amiga.mak +++ b/src/testdir/Make_amiga.mak @@ -29,7 +29,7 @@ SCRIPTS = test1.out test3.out test4.out test5.out test6.out \ test66.out test67.out test68.out test69.out test70.out \ test71.out test72.out test73.out test74.out test75.out \ test76.out test77.out test78.out test79.out test80.out \ - test81.out + test81.out test82.out .SUFFIXES: .in .out @@ -130,3 +130,4 @@ test78.out: test78.in test79.out: test79.in test80.out: test80.in test81.out: test81.in +test82.out: test82.in diff --git a/src/testdir/Make_dos.mak b/src/testdir/Make_dos.mak index 9ece4b5179..ba77d22682 100644 --- a/src/testdir/Make_dos.mak +++ b/src/testdir/Make_dos.mak @@ -29,7 +29,7 @@ SCRIPTS = test3.out test4.out test5.out test6.out test7.out \ test42.out test52.out test65.out test66.out test67.out \ test68.out test69.out test71.out test72.out test73.out \ test74.out test75.out test76.out test77.out test78.out \ - test79.out test80.out test81.out + test79.out test80.out test81.out test82.out SCRIPTS32 = test50.out test70.out diff --git a/src/testdir/Make_ming.mak b/src/testdir/Make_ming.mak index 2ff20ad1b2..d844c3926f 100644 --- a/src/testdir/Make_ming.mak +++ b/src/testdir/Make_ming.mak @@ -49,7 +49,7 @@ SCRIPTS = test3.out test4.out test5.out test6.out test7.out \ test42.out test52.out test65.out test66.out test67.out \ test68.out test69.out test71.out test72.out test73.out \ test74.out test75.out test76.out test77.out test78.out \ - test79.out test80.out test81.out + test79.out test80.out test81.out test82.out SCRIPTS32 = test50.out test70.out diff --git a/src/testdir/Make_os2.mak b/src/testdir/Make_os2.mak index 4442a41de0..bd11d7f263 100644 --- a/src/testdir/Make_os2.mak +++ b/src/testdir/Make_os2.mak @@ -29,7 +29,7 @@ SCRIPTS = test1.out test3.out test4.out test5.out test6.out \ test66.out test67.out test68.out test69.out test70.out \ test71.out test72.out test73.out test74.out test75.out \ test76.out test77.out test78.out test79.out test80.out \ - test81.out + test81.out test82.out .SUFFIXES: .in .out diff --git a/src/testdir/Make_vms.mms b/src/testdir/Make_vms.mms index d4101ed959..fe062c30ab 100644 --- a/src/testdir/Make_vms.mms +++ b/src/testdir/Make_vms.mms @@ -4,7 +4,7 @@ # Authors: Zoltan Arpadffy, # Sandor Kopanyi, # -# Last change: 2011 Jun 26 +# Last change: 2011 Jul 15 # # This has been tested on VMS 6.2 to 8.3 on DEC Alpha, VAX and IA64. # Edit the lines in the Configuration section below to select. @@ -75,7 +75,8 @@ SCRIPT = test1.out test2.out test3.out test4.out test5.out \ test61.out test62.out test63.out test64.out test65.out \ test66.out test67.out test68.out test69.out \ test71.out test72.out test74.out test75.out test76.out \ - test77.out test78.out test79.out test80.out test81.out + test77.out test78.out test79.out test80.out test81.out \ + test82.out # Known problems: # Test 30: a problem around mac format - unknown reason diff --git a/src/testdir/Makefile b/src/testdir/Makefile index 2eea86e265..c776c15f95 100644 --- a/src/testdir/Makefile +++ b/src/testdir/Makefile @@ -26,7 +26,7 @@ SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \ test64.out test65.out test66.out test67.out test68.out \ test69.out test70.out test71.out test72.out test73.out \ test74.out test75.out test76.out test77.out test78.out \ - test79.out test80.out test81.out + test79.out test80.out test81.out test82.out SCRIPTS_GUI = test16.out diff --git a/src/version.c b/src/version.c index f206664f58..94d71aedef 100644 --- a/src/version.c +++ b/src/version.c @@ -709,6 +709,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 253, /**/ 252, /**/ From cee4357a5b045cf867974f8d31db0fee3e38d775 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 15 Jul 2011 21:16:59 +0200 Subject: [PATCH 32/34] Added tag v7-3-253 for changeset c21429d7768c --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index b5dd752fdf..911d1fb0fb 100644 --- a/.hgtags +++ b/.hgtags @@ -1587,3 +1587,4 @@ be6b6509636242cd7e6fab9a4b8772e97fc9a0db v7-3-244 f909f4f0f38c71594266b3595d31ce04d4ebe3ec v7-3-250 fe6ad3fd85322b394824a5c495a78061a747b074 v7-3-251 0b4289bcf8364854dd5f94c42d0252504103e5b9 v7-3-252 +c21429d7768cd4b834a086dd47881d01bca74e8c v7-3-253 From c3d99f427de9aa5ee7dbe13200b84105b5cfa1ca Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 15 Jul 2011 21:24:11 +0200 Subject: [PATCH 33/34] updated for version 7.3.254 Problem: The coladd field is not reset when setting the line number for a ":call" command. Solution: Reset it. --- src/eval.c | 3 +++ src/version.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/eval.c b/src/eval.c index 0ee5b7a0e9..c29462480d 100644 --- a/src/eval.c +++ b/src/eval.c @@ -3430,6 +3430,9 @@ ex_call(eap) { curwin->w_cursor.lnum = lnum; curwin->w_cursor.col = 0; +#ifdef FEAT_VIRTUALEDIT + curwin->w_cursor.coladd = 0; +#endif } arg = startarg; if (get_func_tv(name, (int)STRLEN(name), &rettv, &arg, diff --git a/src/version.c b/src/version.c index 94d71aedef..276bccbf71 100644 --- a/src/version.c +++ b/src/version.c @@ -709,6 +709,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 254, /**/ 253, /**/ From 155ee7b0ca0e07ff41cf9f422abb6aa32ce40840 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 15 Jul 2011 21:24:12 +0200 Subject: [PATCH 34/34] Added tag v7-3-254 for changeset 1eb805225de7 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 911d1fb0fb..a055c8ada1 100644 --- a/.hgtags +++ b/.hgtags @@ -1588,3 +1588,4 @@ f909f4f0f38c71594266b3595d31ce04d4ebe3ec v7-3-250 fe6ad3fd85322b394824a5c495a78061a747b074 v7-3-251 0b4289bcf8364854dd5f94c42d0252504103e5b9 v7-3-252 c21429d7768cd4b834a086dd47881d01bca74e8c v7-3-253 +1eb805225de7750c03af7b0f7ac2f5dd18d032be v7-3-254