Skip to content

Commit 9d68c82

Browse files
committed
Merge remote-tracking branch 'vim/master'
2 parents 8d6721a + 45c7f05 commit 9d68c82

File tree

13 files changed

+139
-30
lines changed

13 files changed

+139
-30
lines changed

src/Make_mvc.mak

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@
113113
# Processor Version: CPUNR=[i386, i486, i586, i686, pentium4] (default is
114114
# i386)
115115
#
116-
# Version Support: WINVER=[0x0400, 0x0500] (default is 0x0400)
116+
# Version Support: WINVER=[0x0400, 0x0500] (default is 0x0500)
117117
#
118118
# Debug version: DEBUG=yes
119119
# Mapfile: MAP=[no, yes or lines] (default is yes)
@@ -370,9 +370,8 @@ CON_LIB = $(CON_LIB) /DELAYLOAD:comdlg32.dll /DELAYLOAD:ole32.dll DelayImp.lib
370370
!endif
371371

372372
### Set the default $(WINVER) to make it work with VC++7.0 (VS.NET)
373-
# When set to 0x0500 ":browse" stops working.
374373
!ifndef WINVER
375-
WINVER = 0x0400
374+
WINVER = 0x0500
376375
!endif
377376

378377
# If you have a fixed directory for $VIM or $VIMRUNTIME, other than the normal

src/eval.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7720,8 +7720,7 @@ get_dict_tv(char_u **arg, typval_T *rettv, int evaluate)
77207720
static void
77217721
job_free(job_T *job)
77227722
{
7723-
/* TODO: free any handles */
7724-
7723+
mch_clear_job(job);
77257724
vim_free(job);
77267725
}
77277726

@@ -14388,9 +14387,11 @@ f_job_start(typval_T *argvars UNUSED, typval_T *rettv)
1438814387
s = vim_strsave_shellescape(s, FALSE, TRUE);
1438914388
if (s == NULL)
1439014389
goto theend;
14390+
ga_concat(&ga, s);
14391+
vim_free(s);
1439114392
}
14392-
ga_concat(&ga, s);
14393-
vim_free(s);
14393+
else
14394+
ga_concat(&ga, s);
1439414395
if (li->li_next != NULL)
1439514396
ga_append(&ga, ' ');
1439614397
#endif
@@ -21650,7 +21651,8 @@ get_tv_string_buf_chk(typval_T *varp, char_u *buf)
2165021651
"process %ld %s", (long)job->jv_pid, status);
2165121652
# elif defined(WIN32)
2165221653
vim_snprintf((char *)buf, NUMBUFLEN,
21653-
"process %ld %s", (long)job->jv_pi.dwProcessId,
21654+
"process %ld %s",
21655+
(long)job->jv_proc_info.dwProcessId,
2165421656
status);
2165521657
# else
2165621658
/* fall-back */

src/os_unix.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5114,13 +5114,20 @@ mch_job_status(job_T *job)
51145114
job->jv_status = JOB_ENDED;
51155115
return "dead";
51165116
}
5117+
if (WIFSIGNALED(status))
5118+
{
5119+
job->jv_exitval = -1;
5120+
job->jv_status = JOB_ENDED;
5121+
return "dead";
5122+
}
51175123
return "run";
51185124
}
51195125

51205126
int
51215127
mch_stop_job(job_T *job, char_u *how)
51225128
{
51235129
int sig = -1;
5130+
pid_t job_pid;
51245131

51255132
if (STRCMP(how, "hup") == 0)
51265133
sig = SIGHUP;
@@ -5134,10 +5141,30 @@ mch_stop_job(job_T *job, char_u *how)
51345141
sig = atoi((char *)how);
51355142
else
51365143
return FAIL;
5144+
51375145
/* TODO: have an option to only kill the process, not the group? */
5138-
kill(-job->jv_pid, sig);
5146+
job_pid = job->jv_pid;
5147+
if (job_pid == getpgid(job_pid))
5148+
job_pid = -job_pid;
5149+
5150+
kill(job_pid, sig);
5151+
51395152
return OK;
51405153
}
5154+
5155+
/*
5156+
* Clear the data related to "job".
5157+
*/
5158+
void
5159+
mch_clear_job(job_T *job)
5160+
{
5161+
/* call waitpid because child process may become zombie */
5162+
# ifdef __NeXT__
5163+
wait4(job->jv_pid, NULL, WNOHANG, (struct rusage *)0);
5164+
# else
5165+
waitpid(job->jv_pid, NULL, WNOHANG);
5166+
# endif
5167+
}
51415168
#endif
51425169

51435170
/*

src/os_win32.c

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5038,19 +5038,44 @@ mch_start_job(char *cmd, job_T *job)
50385038
{
50395039
STARTUPINFO si;
50405040
PROCESS_INFORMATION pi;
5041+
HANDLE jo;
50415042

5043+
jo = CreateJobObject(NULL, NULL);
5044+
if (jo == NULL)
5045+
{
5046+
job->jv_status = JOB_FAILED;
5047+
return;
5048+
}
5049+
5050+
ZeroMemory(&pi, sizeof(pi));
50425051
ZeroMemory(&si, sizeof(si));
50435052
si.cb = sizeof(si);
5053+
si.dwFlags = STARTF_USESHOWWINDOW;
5054+
si.wShowWindow = SW_HIDE;
50445055

50455056
if (!vim_create_process(cmd, FALSE,
5057+
CREATE_SUSPENDED |
50465058
CREATE_DEFAULT_ERROR_MODE |
50475059
CREATE_NEW_PROCESS_GROUP |
5048-
CREATE_NO_WINDOW,
5060+
CREATE_NEW_CONSOLE,
50495061
&si, &pi))
5062+
{
5063+
CloseHandle(jo);
50505064
job->jv_status = JOB_FAILED;
5065+
}
50515066
else
50525067
{
5053-
job->jv_pi = pi;
5068+
if (!AssignProcessToJobObject(jo, pi.hProcess))
5069+
{
5070+
/* if failing, switch the way to terminate
5071+
* process with TerminateProcess. */
5072+
CloseHandle(jo);
5073+
jo = NULL;
5074+
}
5075+
ResumeThread(pi.hThread);
5076+
CloseHandle(job->jv_proc_info.hThread);
5077+
job->jv_proc_info = pi;
5078+
job->jv_job_object = jo;
50545079
job->jv_status = JOB_STARTED;
50555080
}
50565081
}
@@ -5060,12 +5085,10 @@ mch_job_status(job_T *job)
50605085
{
50615086
DWORD dwExitCode = 0;
50625087

5063-
if (!GetExitCodeProcess(job->jv_pi.hProcess, &dwExitCode))
5064-
return "dead";
5065-
if (dwExitCode != STILL_ACTIVE)
5088+
if (!GetExitCodeProcess(job->jv_proc_info.hProcess, &dwExitCode)
5089+
|| dwExitCode != STILL_ACTIVE)
50665090
{
5067-
CloseHandle(job->jv_pi.hProcess);
5068-
CloseHandle(job->jv_pi.hThread);
5091+
job->jv_status = JOB_ENDED;
50695092
return "dead";
50705093
}
50715094
return "run";
@@ -5074,14 +5097,39 @@ mch_job_status(job_T *job)
50745097
int
50755098
mch_stop_job(job_T *job, char_u *how)
50765099
{
5100+
int ret = 0;
5101+
int ctrl_c = STRCMP(how, "int") == 0;
5102+
50775103
if (STRCMP(how, "kill") == 0)
5078-
TerminateProcess(job->jv_pi.hProcess, 0);
5079-
else
5080-
return GenerateConsoleCtrlEvent(
5081-
STRCMP(how, "hup") == 0 ?
5082-
CTRL_BREAK_EVENT : CTRL_C_EVENT,
5083-
job->jv_pi.dwProcessId) ? OK : FAIL;
5084-
return OK;
5104+
{
5105+
if (job->jv_job_object != NULL)
5106+
return TerminateJobObject(job->jv_job_object, 0) ? OK : FAIL;
5107+
else
5108+
return TerminateProcess(job->jv_proc_info.hProcess, 0) ? OK : FAIL;
5109+
}
5110+
5111+
if (!AttachConsole(job->jv_proc_info.dwProcessId))
5112+
return FAIL;
5113+
ret = GenerateConsoleCtrlEvent(
5114+
ctrl_c ? CTRL_C_EVENT : CTRL_BREAK_EVENT,
5115+
job->jv_proc_info.dwProcessId)
5116+
? OK : FAIL;
5117+
FreeConsole();
5118+
return ret;
5119+
}
5120+
5121+
/*
5122+
* Clear the data related to "job".
5123+
*/
5124+
void
5125+
mch_clear_job(job_T *job)
5126+
{
5127+
if (job->jv_status != JOB_FAILED)
5128+
{
5129+
if (job->jv_job_object != NULL)
5130+
CloseHandle(job->jv_job_object);
5131+
CloseHandle(job->jv_proc_info.hProcess);
5132+
}
50855133
}
50865134
#endif
50875135

src/proto/os_unix.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ int mch_call_shell(char_u *cmd, int options);
6060
void mch_start_job(char **argv, job_T *job);
6161
char *mch_job_status(job_T *job);
6262
int mch_stop_job(job_T *job, char_u *how);
63+
void mch_clear_job(job_T *job);
6364
void mch_breakcheck(void);
6465
int mch_expandpath(garray_T *gap, char_u *path, int flags);
6566
int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file, char_u ***file, int flags);

src/proto/os_win32.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ int mch_call_shell(char_u *cmd, int options);
4343
void mch_start_job(char *cmd, job_T *job);
4444
char *mch_job_status(job_T *job);
4545
int mch_stop_job(job_T *job, char_u *how);
46+
void mch_clear_job(job_T *job);
4647
void mch_set_normal_colors(void);
4748
void mch_write(char_u *s, int len);
4849
void mch_delay(long msec, int ignoreinput);

src/regexp.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,6 +1500,10 @@ vim_regcomp_had_eol(void)
15001500
}
15011501
#endif
15021502

1503+
/* variables for parsing reginput */
1504+
static int at_start; /* True when on the first character */
1505+
static int prev_at_start; /* True when on the second character */
1506+
15031507
/*
15041508
* Parse regular expression, i.e. main body or parenthesized thing.
15051509
*
@@ -1918,6 +1922,7 @@ regatom(int *flagp)
19181922
int c;
19191923
char_u *p;
19201924
int extra = 0;
1925+
int save_prev_at_start = prev_at_start;
19211926

19221927
*flagp = WORST; /* Tentatively. */
19231928

@@ -2331,7 +2336,11 @@ regatom(int *flagp)
23312336
else if (c == 'l' || c == 'c' || c == 'v')
23322337
{
23332338
if (c == 'l')
2339+
{
23342340
ret = regnode(RE_LNUM);
2341+
if (save_prev_at_start)
2342+
at_start = TRUE;
2343+
}
23352344
else if (c == 'c')
23362345
ret = regnode(RE_COL);
23372346
else
@@ -2946,10 +2955,6 @@ regoptail(char_u *p, char_u *val)
29462955
/*
29472956
* Functions for getting characters from the regexp input.
29482957
*/
2949-
2950-
static int at_start; /* True when on the first character */
2951-
static int prev_at_start; /* True when on the second character */
2952-
29532958
/*
29542959
* Start parsing at "str".
29552960
*/

src/regexp_nfa.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,6 +1128,7 @@ nfa_regatom(void)
11281128
int startc = -1;
11291129
int endc = -1;
11301130
int oldstartc = -1;
1131+
int save_prev_at_start = prev_at_start;
11311132

11321133
c = getchr();
11331134
switch (c)
@@ -1467,9 +1468,13 @@ nfa_regatom(void)
14671468
if (c == 'l' || c == 'c' || c == 'v')
14681469
{
14691470
if (c == 'l')
1471+
{
14701472
/* \%{n}l \%{n}<l \%{n}>l */
14711473
EMIT(cmp == '<' ? NFA_LNUM_LT :
14721474
cmp == '>' ? NFA_LNUM_GT : NFA_LNUM);
1475+
if (save_prev_at_start)
1476+
at_start = TRUE;
1477+
}
14731478
else if (c == 'c')
14741479
/* \%{n}c \%{n}<c \%{n}>c */
14751480
EMIT(cmp == '<' ? NFA_COL_LT :

src/structs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1249,7 +1249,8 @@ struct jobvar_S
12491249
int jv_exitval;
12501250
#endif
12511251
#ifdef WIN32
1252-
PROCESS_INFORMATION jv_pi;
1252+
PROCESS_INFORMATION jv_proc_info;
1253+
HANDLE jv_job_object;
12531254
#endif
12541255
jobstatus_T jv_status;
12551256

src/testdir/test36.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ p:s/\%#=2\U//g
9898
p:s/\%#=0[^A-Z]//g
9999
p:s/\%#=1[^A-Z]//g
100100
p:s/\%#=2[^A-Z]//g
101+
p:s/\%#=0\%204l^\t...//g
102+
p:s/\%#=1\%205l^\t...//g
103+
p:s/\%#=2\%206l^\t...//g
101104
:/^start-here/+1,$wq! test.out
102105
ENDTEST
103106

0 commit comments

Comments
 (0)