Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
1ee75382
Commit
1ee75382
authored
Sep 11, 2007
by
Jason Edmeades
Committed by
Alexandre Julliard
Sep 12, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cmd.exe: Fix redirect ordering on a command line.
parent
c7b88e95
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
232 additions
and
133 deletions
+232
-133
batch.c
programs/cmd/batch.c
+1
-0
builtins.c
programs/cmd/builtins.c
+7
-5
directory.c
programs/cmd/directory.c
+1
-0
wcmd.h
programs/cmd/wcmd.h
+4
-1
wcmdmain.c
programs/cmd/wcmdmain.c
+219
-127
No files found.
programs/cmd/batch.c
View file @
1ee75382
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
* CMD - Wine-compatible command line interface - batch interface.
* CMD - Wine-compatible command line interface - batch interface.
*
*
* Copyright (C) 1999 D A Pickles
* Copyright (C) 1999 D A Pickles
* Copyright (C) 2007 J Edmeades
*
*
* This library is free software; you can redistribute it and/or
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* modify it under the terms of the GNU Lesser General Public
...
...
programs/cmd/builtins.c
View file @
1ee75382
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
* CMD - Wine-compatible command line interface - built-in functions.
* CMD - Wine-compatible command line interface - built-in functions.
*
*
* Copyright (C) 1999 D A Pickles
* Copyright (C) 1999 D A Pickles
* Copyright (C) 2007 J Edmeades
*
*
* This library is free software; you can redistribute it and/or
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* modify it under the terms of the GNU Lesser General Public
...
@@ -832,7 +833,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
...
@@ -832,7 +833,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
if
(
*
itemStart
==
'`'
||
*
itemStart
==
'\''
)
{
if
(
*
itemStart
==
'`'
||
*
itemStart
==
'\''
)
{
WCHAR
temp_path
[
MAX_PATH
],
temp_cmd
[
MAXSTRING
];
WCHAR
temp_path
[
MAX_PATH
],
temp_cmd
[
MAXSTRING
];
static
const
WCHAR
redirOut
[]
=
{
'
%'
,
's'
,
' '
,
'>'
,
'
'
,
'%'
,
's'
,
'\0'
};
static
const
WCHAR
redirOut
[]
=
{
'
>
'
,
'%'
,
's'
,
'\0'
};
static
const
WCHAR
cmdW
[]
=
{
'C'
,
'M'
,
'D'
,
'\0'
};
static
const
WCHAR
cmdW
[]
=
{
'C'
,
'M'
,
'D'
,
'\0'
};
/* Remove trailing character */
/* Remove trailing character */
...
@@ -844,7 +845,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
...
@@ -844,7 +845,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
/* Execute program and redirect output */
/* Execute program and redirect output */
wsprintf
(
temp_cmd
,
redirOut
,
(
itemStart
+
1
),
temp_file
);
wsprintf
(
temp_cmd
,
redirOut
,
(
itemStart
+
1
),
temp_file
);
WCMD_execute
(
temp_cmd
,
NULL
,
NULL
,
NULL
);
WCMD_execute
(
itemStart
,
temp_cmd
,
NULL
,
NULL
,
NULL
);
/* Open the file, read line by line and process */
/* Open the file, read line by line and process */
input
=
CreateFile
(
temp_file
,
GENERIC_READ
,
FILE_SHARE_READ
,
input
=
CreateFile
(
temp_file
,
GENERIC_READ
,
FILE_SHARE_READ
,
...
@@ -977,7 +978,7 @@ void WCMD_part_execute(CMD_LIST **cmdList, WCHAR *firstcmd, WCHAR *variable,
...
@@ -977,7 +978,7 @@ void WCMD_part_execute(CMD_LIST **cmdList, WCHAR *firstcmd, WCHAR *variable,
/* Process the first command, if there is one */
/* Process the first command, if there is one */
if
(
conditionTRUE
&&
firstcmd
&&
*
firstcmd
)
{
if
(
conditionTRUE
&&
firstcmd
&&
*
firstcmd
)
{
WCHAR
*
command
=
WCMD_strdupW
(
firstcmd
);
WCHAR
*
command
=
WCMD_strdupW
(
firstcmd
);
WCMD_execute
(
firstcmd
,
variable
,
value
,
cmdList
);
WCMD_execute
(
firstcmd
,
(
*
cmdList
)
->
redirects
,
variable
,
value
,
cmdList
);
free
(
command
);
free
(
command
);
}
}
...
@@ -1005,7 +1006,8 @@ void WCMD_part_execute(CMD_LIST **cmdList, WCHAR *firstcmd, WCHAR *variable,
...
@@ -1005,7 +1006,8 @@ void WCMD_part_execute(CMD_LIST **cmdList, WCHAR *firstcmd, WCHAR *variable,
/* Execute any appended to the statement with &&'s */
/* Execute any appended to the statement with &&'s */
if
((
*
cmdList
)
->
isAmphersand
)
{
if
((
*
cmdList
)
->
isAmphersand
)
{
if
(
processThese
)
{
if
(
processThese
)
{
WCMD_execute
((
*
cmdList
)
->
command
,
variable
,
value
,
cmdList
);
WCMD_execute
((
*
cmdList
)
->
command
,
(
*
cmdList
)
->
redirects
,
variable
,
value
,
cmdList
);
}
}
if
(
curPosition
==
*
cmdList
)
*
cmdList
=
(
*
cmdList
)
->
nextcommand
;
if
(
curPosition
==
*
cmdList
)
*
cmdList
=
(
*
cmdList
)
->
nextcommand
;
...
@@ -1033,7 +1035,7 @@ void WCMD_part_execute(CMD_LIST **cmdList, WCHAR *firstcmd, WCHAR *variable,
...
@@ -1033,7 +1035,7 @@ void WCMD_part_execute(CMD_LIST **cmdList, WCHAR *firstcmd, WCHAR *variable,
/* Skip leading whitespace between condition and the command */
/* Skip leading whitespace between condition and the command */
while
(
*
cmd
&&
(
*
cmd
==
' '
||
*
cmd
==
'\t'
))
cmd
++
;
while
(
*
cmd
&&
(
*
cmd
==
' '
||
*
cmd
==
'\t'
))
cmd
++
;
if
(
*
cmd
)
{
if
(
*
cmd
)
{
WCMD_execute
(
cmd
,
variable
,
value
,
cmdList
);
WCMD_execute
(
cmd
,
(
*
cmdList
)
->
redirects
,
variable
,
value
,
cmdList
);
}
}
}
}
if
(
curPosition
==
*
cmdList
)
*
cmdList
=
(
*
cmdList
)
->
nextcommand
;
if
(
curPosition
==
*
cmdList
)
*
cmdList
=
(
*
cmdList
)
->
nextcommand
;
...
...
programs/cmd/directory.c
View file @
1ee75382
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
* CMD - Wine-compatible command line interface - Directory functions.
* CMD - Wine-compatible command line interface - Directory functions.
*
*
* Copyright (C) 1999 D A Pickles
* Copyright (C) 1999 D A Pickles
* Copyright (C) 2007 J Edmeades
*
*
* This library is free software; you can redistribute it and/or
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* modify it under the terms of the GNU Lesser General Public
...
...
programs/cmd/wcmd.h
View file @
1ee75382
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
* CMD - Wine-compatible command line interface.
* CMD - Wine-compatible command line interface.
*
*
* Copyright (C) 1999 D A Pickles
* Copyright (C) 1999 D A Pickles
* Copyright (C) 2007 J Edmeades
*
*
* This library is free software; you can redistribute it and/or
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* modify it under the terms of the GNU Lesser General Public
...
@@ -32,6 +33,7 @@
...
@@ -32,6 +33,7 @@
typedef
struct
_CMD_LIST
{
typedef
struct
_CMD_LIST
{
WCHAR
*
command
;
/* Command string to execute */
WCHAR
*
command
;
/* Command string to execute */
WCHAR
*
redirects
;
/* Redirects in place */
struct
_CMD_LIST
*
nextcommand
;
/* Next command string to execute */
struct
_CMD_LIST
*
nextcommand
;
/* Next command string to execute */
BOOL
isAmphersand
;
/* Whether follows && */
BOOL
isAmphersand
;
/* Whether follows && */
int
bracketDepth
;
/* How deep bracketing have we got to */
int
bracketDepth
;
/* How deep bracketing have we got to */
...
@@ -103,7 +105,8 @@ BOOL WCMD_ReadFile(const HANDLE hIn, WCHAR *intoBuf, const DWORD maxChars,
...
@@ -103,7 +105,8 @@ BOOL WCMD_ReadFile(const HANDLE hIn, WCHAR *intoBuf, const DWORD maxChars,
WCHAR
*
WCMD_ReadAndParseLine
(
WCHAR
*
initialcmd
,
CMD_LIST
**
output
,
HANDLE
readFrom
);
WCHAR
*
WCMD_ReadAndParseLine
(
WCHAR
*
initialcmd
,
CMD_LIST
**
output
,
HANDLE
readFrom
);
CMD_LIST
*
WCMD_process_commands
(
CMD_LIST
*
thisCmd
,
BOOL
oneBracket
,
WCHAR
*
var
,
WCHAR
*
val
);
CMD_LIST
*
WCMD_process_commands
(
CMD_LIST
*
thisCmd
,
BOOL
oneBracket
,
WCHAR
*
var
,
WCHAR
*
val
);
void
WCMD_free_commands
(
CMD_LIST
*
cmds
);
void
WCMD_free_commands
(
CMD_LIST
*
cmds
);
void
WCMD_execute
(
WCHAR
*
orig_command
,
WCHAR
*
parameter
,
WCHAR
*
substitution
,
CMD_LIST
**
cmdList
);
void
WCMD_execute
(
WCHAR
*
orig_command
,
WCHAR
*
redirects
,
WCHAR
*
parameter
,
WCHAR
*
substitution
,
CMD_LIST
**
cmdList
);
/* Data structure to hold context when executing batch files */
/* Data structure to hold context when executing batch files */
...
...
programs/cmd/wcmdmain.c
View file @
1ee75382
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
* CMD - Wine-compatible command line interface.
* CMD - Wine-compatible command line interface.
*
*
* Copyright (C) 1999 - 2001 D A Pickles
* Copyright (C) 1999 - 2001 D A Pickles
* Copyright (C) 2007 J Edmeades
*
*
* This library is free software; you can redistribute it and/or
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* modify it under the terms of the GNU Lesser General Public
...
@@ -96,6 +97,7 @@ static char *output_bufA = NULL;
...
@@ -96,6 +97,7 @@ static char *output_bufA = NULL;
BOOL
unicodePipes
=
FALSE
;
BOOL
unicodePipes
=
FALSE
;
static
WCHAR
*
WCMD_expand_envvar
(
WCHAR
*
start
,
WCHAR
*
forvar
,
WCHAR
*
forVal
);
static
WCHAR
*
WCMD_expand_envvar
(
WCHAR
*
start
,
WCHAR
*
forvar
,
WCHAR
*
forVal
);
static
void
WCMD_output_asis_len
(
const
WCHAR
*
message
,
int
len
,
HANDLE
device
);
/*****************************************************************************
/*****************************************************************************
* Main entry point. This is a console application so we have a main() not a
* Main entry point. This is a console application so we have a main() not a
...
@@ -544,7 +546,7 @@ void handleExpansion(WCHAR *cmd, BOOL justFors, WCHAR *forVariable, WCHAR *forVa
...
@@ -544,7 +546,7 @@ void handleExpansion(WCHAR *cmd, BOOL justFors, WCHAR *forVariable, WCHAR *forVa
*/
*/
void
WCMD_execute
(
WCHAR
*
command
,
void
WCMD_execute
(
WCHAR
*
command
,
WCHAR
*
redirects
,
WCHAR
*
forVariable
,
WCHAR
*
forValue
,
WCHAR
*
forVariable
,
WCHAR
*
forValue
,
CMD_LIST
**
cmdList
)
CMD_LIST
**
cmdList
)
{
{
...
@@ -555,7 +557,6 @@ void WCMD_execute (WCHAR *command,
...
@@ -555,7 +557,6 @@ void WCMD_execute (WCHAR *command,
WCHAR
*
whichcmd
;
WCHAR
*
whichcmd
;
SECURITY_ATTRIBUTES
sa
;
SECURITY_ATTRIBUTES
sa
;
WCHAR
*
new_cmd
;
WCHAR
*
new_cmd
;
WCHAR
*
first_redir
=
NULL
;
HANDLE
old_stdhandles
[
3
]
=
{
INVALID_HANDLE_VALUE
,
HANDLE
old_stdhandles
[
3
]
=
{
INVALID_HANDLE_VALUE
,
INVALID_HANDLE_VALUE
,
INVALID_HANDLE_VALUE
,
INVALID_HANDLE_VALUE
};
INVALID_HANDLE_VALUE
};
...
@@ -614,8 +615,7 @@ void WCMD_execute (WCHAR *command,
...
@@ -614,8 +615,7 @@ void WCMD_execute (WCHAR *command,
* Redirect stdin, stdout and/or stderr if required.
* Redirect stdin, stdout and/or stderr if required.
*/
*/
if
((
p
=
strchrW
(
cmd
,
'<'
))
!=
NULL
)
{
if
((
p
=
strchrW
(
redirects
,
'<'
))
!=
NULL
)
{
if
(
first_redir
==
NULL
)
first_redir
=
p
;
h
=
CreateFile
(
WCMD_parameter
(
++
p
,
0
,
NULL
),
GENERIC_READ
,
FILE_SHARE_READ
,
&
sa
,
OPEN_EXISTING
,
h
=
CreateFile
(
WCMD_parameter
(
++
p
,
0
,
NULL
),
GENERIC_READ
,
FILE_SHARE_READ
,
&
sa
,
OPEN_EXISTING
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
FILE_ATTRIBUTE_NORMAL
,
NULL
);
if
(
h
==
INVALID_HANDLE_VALUE
)
{
if
(
h
==
INVALID_HANDLE_VALUE
)
{
...
@@ -628,15 +628,13 @@ void WCMD_execute (WCHAR *command,
...
@@ -628,15 +628,13 @@ void WCMD_execute (WCHAR *command,
}
}
/* Scan the whole command looking for > and 2> */
/* Scan the whole command looking for > and 2> */
redir
=
cmd
;
redir
=
redirects
;
while
(
redir
!=
NULL
&&
((
p
=
strchrW
(
redir
,
'>'
))
!=
NULL
))
{
while
(
redir
!=
NULL
&&
((
p
=
strchrW
(
redir
,
'>'
))
!=
NULL
))
{
int
handle
=
0
;
int
handle
=
0
;
if
(
*
(
p
-
1
)
!=
'2'
)
{
if
(
*
(
p
-
1
)
!=
'2'
)
{
if
(
first_redir
==
NULL
)
first_redir
=
p
;
handle
=
1
;
handle
=
1
;
}
else
{
}
else
{
if
(
first_redir
==
NULL
)
first_redir
=
(
p
-
1
);
handle
=
2
;
handle
=
2
;
}
}
...
@@ -683,9 +681,6 @@ void WCMD_execute (WCHAR *command,
...
@@ -683,9 +681,6 @@ void WCMD_execute (WCHAR *command,
SetStdHandle
(
idx_stdhandles
[
handle
],
h
);
SetStdHandle
(
idx_stdhandles
[
handle
],
h
);
}
}
/* Terminate the command string at <, or first 2> or > */
if
(
first_redir
!=
NULL
)
*
first_redir
=
'\0'
;
/*
/*
* Strip leading whitespaces, and a '@' if supplied
* Strip leading whitespaces, and a '@' if supplied
*/
*/
...
@@ -1267,9 +1262,12 @@ void WCMD_print_error (void) {
...
@@ -1267,9 +1262,12 @@ void WCMD_print_error (void) {
error_code
,
GetLastError
());
error_code
,
GetLastError
());
return
;
return
;
}
}
WCMD_output_asis
(
lpMsgBuf
);
WCMD_output_asis_len
(
lpMsgBuf
,
lstrlen
(
lpMsgBuf
),
GetStdHandle
(
STD_ERROR_HANDLE
));
LocalFree
((
HLOCAL
)
lpMsgBuf
);
LocalFree
((
HLOCAL
)
lpMsgBuf
);
WCMD_output_asis
(
newline
);
WCMD_output_asis_len
(
newline
,
lstrlen
(
newline
),
GetStdHandle
(
STD_ERROR_HANDLE
));
return
;
return
;
}
}
...
@@ -1338,7 +1336,7 @@ int p = 0;
...
@@ -1338,7 +1336,7 @@ int p = 0;
* and hence required WriteConsoleW to output it, however if file i/o is
* and hence required WriteConsoleW to output it, however if file i/o is
* redirected, it needs to be WriteFile'd using OEM (not ANSI) format
* redirected, it needs to be WriteFile'd using OEM (not ANSI) format
*/
*/
static
void
WCMD_output_asis_len
(
const
WCHAR
*
message
,
int
len
)
{
static
void
WCMD_output_asis_len
(
const
WCHAR
*
message
,
int
len
,
HANDLE
device
)
{
DWORD
nOut
=
0
;
DWORD
nOut
=
0
;
DWORD
res
=
0
;
DWORD
res
=
0
;
...
@@ -1347,8 +1345,7 @@ static void WCMD_output_asis_len(const WCHAR *message, int len) {
...
@@ -1347,8 +1345,7 @@ static void WCMD_output_asis_len(const WCHAR *message, int len) {
if
(
!
len
)
return
;
if
(
!
len
)
return
;
/* Try to write as unicode assuming it is to a console */
/* Try to write as unicode assuming it is to a console */
res
=
WriteConsoleW
(
GetStdHandle
(
STD_OUTPUT_HANDLE
),
res
=
WriteConsoleW
(
device
,
message
,
len
,
&
nOut
,
NULL
);
message
,
len
,
&
nOut
,
NULL
);
/* If writing to console fails, assume its file
/* If writing to console fails, assume its file
i/o so convert to OEM codepage and output */
i/o so convert to OEM codepage and output */
...
@@ -1371,10 +1368,10 @@ static void WCMD_output_asis_len(const WCHAR *message, int len) {
...
@@ -1371,10 +1368,10 @@ static void WCMD_output_asis_len(const WCHAR *message, int len) {
convertedChars
=
WideCharToMultiByte
(
GetConsoleOutputCP
(),
0
,
message
,
convertedChars
=
WideCharToMultiByte
(
GetConsoleOutputCP
(),
0
,
message
,
len
,
output_bufA
,
MAX_WRITECONSOLE_SIZE
,
len
,
output_bufA
,
MAX_WRITECONSOLE_SIZE
,
"?"
,
&
usedDefaultChar
);
"?"
,
&
usedDefaultChar
);
WriteFile
(
GetStdHandle
(
STD_OUTPUT_HANDLE
)
,
output_bufA
,
convertedChars
,
WriteFile
(
device
,
output_bufA
,
convertedChars
,
&
nOut
,
FALSE
);
&
nOut
,
FALSE
);
}
else
{
}
else
{
WriteFile
(
GetStdHandle
(
STD_OUTPUT_HANDLE
)
,
message
,
len
*
sizeof
(
WCHAR
),
WriteFile
(
device
,
message
,
len
*
sizeof
(
WCHAR
),
&
nOut
,
FALSE
);
&
nOut
,
FALSE
);
}
}
}
}
...
@@ -1400,7 +1397,7 @@ void WCMD_output (const WCHAR *format, ...) {
...
@@ -1400,7 +1397,7 @@ void WCMD_output (const WCHAR *format, ...) {
string
[
ret
]
=
'\0'
;
string
[
ret
]
=
'\0'
;
}
}
va_end
(
ap
);
va_end
(
ap
);
WCMD_output_asis_len
(
string
,
ret
);
WCMD_output_asis_len
(
string
,
ret
,
GetStdHandle
(
STD_OUTPUT_HANDLE
)
);
}
}
...
@@ -1451,19 +1448,22 @@ void WCMD_output_asis (const WCHAR *message) {
...
@@ -1451,19 +1448,22 @@ void WCMD_output_asis (const WCHAR *message) {
ptr
++
;
ptr
++
;
};
};
if
(
*
ptr
==
'\n'
)
ptr
++
;
if
(
*
ptr
==
'\n'
)
ptr
++
;
WCMD_output_asis_len
(
message
,
(
ptr
)
?
ptr
-
message
:
strlenW
(
message
));
WCMD_output_asis_len
(
message
,
(
ptr
)
?
ptr
-
message
:
strlenW
(
message
),
GetStdHandle
(
STD_OUTPUT_HANDLE
));
if
(
ptr
)
{
if
(
ptr
)
{
numChars
=
0
;
numChars
=
0
;
if
(
++
line_count
>=
max_height
-
1
)
{
if
(
++
line_count
>=
max_height
-
1
)
{
line_count
=
0
;
line_count
=
0
;
WCMD_output_asis_len
(
pagedMessage
,
strlenW
(
pagedMessage
));
WCMD_output_asis_len
(
pagedMessage
,
strlenW
(
pagedMessage
),
GetStdHandle
(
STD_OUTPUT_HANDLE
));
WCMD_ReadFile
(
GetStdHandle
(
STD_INPUT_HANDLE
),
string
,
WCMD_ReadFile
(
GetStdHandle
(
STD_INPUT_HANDLE
),
string
,
sizeof
(
string
)
/
sizeof
(
WCHAR
),
&
count
,
NULL
);
sizeof
(
string
)
/
sizeof
(
WCHAR
),
&
count
,
NULL
);
}
}
}
}
}
while
(((
message
=
ptr
)
!=
NULL
)
&&
(
*
ptr
));
}
while
(((
message
=
ptr
)
!=
NULL
)
&&
(
*
ptr
));
}
else
{
}
else
{
WCMD_output_asis_len
(
message
,
lstrlen
(
message
));
WCMD_output_asis_len
(
message
,
lstrlen
(
message
),
GetStdHandle
(
STD_OUTPUT_HANDLE
));
}
}
}
}
...
@@ -1544,19 +1544,19 @@ void WCMD_pipe (CMD_LIST **cmdEntry, WCHAR *var, WCHAR *val) {
...
@@ -1544,19 +1544,19 @@ void WCMD_pipe (CMD_LIST **cmdEntry, WCHAR *var, WCHAR *val) {
p
=
strchrW
(
command
,
'|'
);
p
=
strchrW
(
command
,
'|'
);
*
p
++
=
'\0'
;
*
p
++
=
'\0'
;
wsprintf
(
temp_cmd
,
redirOut
,
command
,
temp_file
);
wsprintf
(
temp_cmd
,
redirOut
,
command
,
temp_file
);
WCMD_execute
(
temp_cmd
,
var
,
val
,
cmdEntry
);
WCMD_execute
(
temp_cmd
,
(
*
cmdEntry
)
->
redirects
,
var
,
val
,
cmdEntry
);
command
=
p
;
command
=
p
;
while
((
p
=
strchrW
(
command
,
'|'
)))
{
while
((
p
=
strchrW
(
command
,
'|'
)))
{
*
p
++
=
'\0'
;
*
p
++
=
'\0'
;
GetTempFileName
(
temp_path
,
cmdW
,
0
,
temp_file2
);
GetTempFileName
(
temp_path
,
cmdW
,
0
,
temp_file2
);
wsprintf
(
temp_cmd
,
redirBoth
,
command
,
temp_file
,
temp_file2
);
wsprintf
(
temp_cmd
,
redirBoth
,
command
,
temp_file
,
temp_file2
);
WCMD_execute
(
temp_cmd
,
var
,
val
,
cmdEntry
);
WCMD_execute
(
temp_cmd
,
(
*
cmdEntry
)
->
redirects
,
var
,
val
,
cmdEntry
);
DeleteFile
(
temp_file
);
DeleteFile
(
temp_file
);
strcpyW
(
temp_file
,
temp_file2
);
strcpyW
(
temp_file
,
temp_file2
);
command
=
p
;
command
=
p
;
}
}
wsprintf
(
temp_cmd
,
redirIn
,
command
,
temp_file
);
wsprintf
(
temp_cmd
,
redirIn
,
command
,
temp_file
);
WCMD_execute
(
temp_cmd
,
var
,
val
,
cmdEntry
);
WCMD_execute
(
temp_cmd
,
(
*
cmdEntry
)
->
redirects
,
var
,
val
,
cmdEntry
);
DeleteFile
(
temp_file
);
DeleteFile
(
temp_file
);
}
}
...
@@ -1936,7 +1936,8 @@ void WCMD_DumpCommands(CMD_LIST *commands) {
...
@@ -1936,7 +1936,8 @@ void WCMD_DumpCommands(CMD_LIST *commands) {
WCHAR
buffer
[
MAXSTRING
];
WCHAR
buffer
[
MAXSTRING
];
CMD_LIST
*
thisCmd
=
commands
;
CMD_LIST
*
thisCmd
=
commands
;
const
WCHAR
fmt
[]
=
{
'%'
,
'p'
,
' '
,
'%'
,
'c'
,
' '
,
'%'
,
'2'
,
'.'
,
'2'
,
'd'
,
' '
,
const
WCHAR
fmt
[]
=
{
'%'
,
'p'
,
' '
,
'%'
,
'c'
,
' '
,
'%'
,
'2'
,
'.'
,
'2'
,
'd'
,
' '
,
'%'
,
'p'
,
' '
,
'%'
,
's'
,
'\0'
};
'%'
,
'p'
,
' '
,
'%'
,
's'
,
' '
,
'R'
,
'e'
,
'd'
,
'i'
,
'r'
,
':'
,
'%'
,
's'
,
'\0'
};
WINE_TRACE
(
"Parsed line:
\n
"
);
WINE_TRACE
(
"Parsed line:
\n
"
);
while
(
thisCmd
!=
NULL
)
{
while
(
thisCmd
!=
NULL
)
{
...
@@ -1945,13 +1946,65 @@ void WCMD_DumpCommands(CMD_LIST *commands) {
...
@@ -1945,13 +1946,65 @@ void WCMD_DumpCommands(CMD_LIST *commands) {
thisCmd
->
isAmphersand
?
'Y'
:
'N'
,
thisCmd
->
isAmphersand
?
'Y'
:
'N'
,
thisCmd
->
bracketDepth
,
thisCmd
->
bracketDepth
,
thisCmd
->
nextcommand
,
thisCmd
->
nextcommand
,
thisCmd
->
command
);
thisCmd
->
command
,
thisCmd
->
redirects
);
WINE_TRACE
(
"%s
\n
"
,
wine_dbgstr_w
(
buffer
));
WINE_TRACE
(
"%s
\n
"
,
wine_dbgstr_w
(
buffer
));
thisCmd
=
thisCmd
->
nextcommand
;
thisCmd
=
thisCmd
->
nextcommand
;
}
}
}
}
/***************************************************************************
/***************************************************************************
* WCMD_addCommand
*
* Adds a command to the current command list
*/
void
WCMD_addCommand
(
WCHAR
*
command
,
int
*
commandLen
,
WCHAR
*
redirs
,
int
*
redirLen
,
WCHAR
**
copyTo
,
int
**
copyToLen
,
BOOL
isAmphersand
,
int
curDepth
,
CMD_LIST
**
lastEntry
,
CMD_LIST
**
output
)
{
CMD_LIST
*
thisEntry
=
NULL
;
/* Allocate storage for command */
thisEntry
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
CMD_LIST
));
/* Copy in the command */
if
(
command
)
{
thisEntry
->
command
=
HeapAlloc
(
GetProcessHeap
(),
0
,
(
*
commandLen
+
1
)
*
sizeof
(
WCHAR
));
memcpy
(
thisEntry
->
command
,
command
,
*
commandLen
*
sizeof
(
WCHAR
));
thisEntry
->
command
[
*
commandLen
]
=
0x00
;
/* Copy in the redirects */
thisEntry
->
redirects
=
HeapAlloc
(
GetProcessHeap
(),
0
,
(
*
redirLen
+
1
)
*
sizeof
(
WCHAR
));
memcpy
(
thisEntry
->
redirects
,
redirs
,
*
redirLen
*
sizeof
(
WCHAR
));
thisEntry
->
redirects
[
*
redirLen
]
=
0x00
;
/* Reset the lengths */
*
commandLen
=
0
;
*
redirLen
=
0
;
*
copyToLen
=
commandLen
;
*
copyTo
=
command
;
}
else
{
thisEntry
->
command
=
NULL
;
}
/* Fill in other fields */
thisEntry
->
nextcommand
=
NULL
;
thisEntry
->
isAmphersand
=
isAmphersand
;
thisEntry
->
bracketDepth
=
curDepth
;
if
(
*
lastEntry
)
{
(
*
lastEntry
)
->
nextcommand
=
thisEntry
;
}
else
{
*
output
=
thisEntry
;
}
*
lastEntry
=
thisEntry
;
}
/***************************************************************************
* WCMD_ReadAndParseLine
* WCMD_ReadAndParseLine
*
*
* Either uses supplied input or
* Either uses supplied input or
...
@@ -1970,9 +2023,12 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
...
@@ -1970,9 +2023,12 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
WCHAR
*
curPos
;
WCHAR
*
curPos
;
BOOL
inQuotes
=
FALSE
;
BOOL
inQuotes
=
FALSE
;
WCHAR
curString
[
MAXSTRING
];
WCHAR
curString
[
MAXSTRING
];
int
curLen
=
0
;
int
curStringLen
=
0
;
WCHAR
curRedirs
[
MAXSTRING
];
int
curRedirsLen
=
0
;
WCHAR
*
curCopyTo
;
int
*
curLen
;
int
curDepth
=
0
;
int
curDepth
=
0
;
CMD_LIST
*
thisEntry
=
NULL
;
CMD_LIST
*
lastEntry
=
NULL
;
CMD_LIST
*
lastEntry
=
NULL
;
BOOL
isAmphersand
=
FALSE
;
BOOL
isAmphersand
=
FALSE
;
static
WCHAR
*
extraSpace
=
NULL
;
/* Deliberately never freed */
static
WCHAR
*
extraSpace
=
NULL
;
/* Deliberately never freed */
...
@@ -1990,6 +2046,7 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
...
@@ -1990,6 +2046,7 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
BOOL
lastWasDo
=
FALSE
;
BOOL
lastWasDo
=
FALSE
;
BOOL
lastWasIn
=
FALSE
;
BOOL
lastWasIn
=
FALSE
;
BOOL
lastWasElse
=
FALSE
;
BOOL
lastWasElse
=
FALSE
;
BOOL
lastWasRedirect
=
TRUE
;
/* Allocate working space for a command read from keyboard, file etc */
/* Allocate working space for a command read from keyboard, file etc */
if
(
!
extraSpace
)
if
(
!
extraSpace
)
...
@@ -2015,8 +2072,12 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
...
@@ -2015,8 +2072,12 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
/* Replace env vars if in a batch context */
/* Replace env vars if in a batch context */
if
(
context
)
handleExpansion
(
extraSpace
,
FALSE
,
NULL
,
NULL
);
if
(
context
)
handleExpansion
(
extraSpace
,
FALSE
,
NULL
,
NULL
);
/* Start with an empty string */
/* Start with an empty string, copying to the command string */
curLen
=
0
;
curStringLen
=
0
;
curRedirsLen
=
0
;
curCopyTo
=
curString
;
curLen
=
&
curStringLen
;
lastWasRedirect
=
FALSE
;
/* Required for eg spaces between > and filename */
/* Parse every character on the line being processed */
/* Parse every character on the line being processed */
while
(
*
curPos
!=
0x00
)
{
while
(
*
curPos
!=
0x00
)
{
...
@@ -2024,12 +2085,12 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
...
@@ -2024,12 +2085,12 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
WCHAR
thisChar
;
WCHAR
thisChar
;
/* Debugging AID:
/* Debugging AID:
WINE_TRACE("Looking at '%c' (len:%d, lws:%d, ows:%d)\n", *curPos, curLen,
WINE_TRACE("Looking at '%c' (len:%d, lws:%d, ows:%d)\n", *curPos,
*
curLen,
lastWasWhiteSpace, onlyWhiteSpace);
lastWasWhiteSpace, onlyWhiteSpace);
*/
*/
/* Certain commands need special handling */
/* Certain commands need special handling */
if
(
cur
Len
==
0
)
{
if
(
cur
StringLen
==
0
&&
curCopyTo
==
curString
)
{
const
WCHAR
forDO
[]
=
{
'd'
,
'o'
,
' '
,
'\0'
};
const
WCHAR
forDO
[]
=
{
'd'
,
'o'
,
' '
,
'\0'
};
/* If command starts with 'rem', ignore any &&, ( etc */
/* If command starts with 'rem', ignore any &&, ( etc */
...
@@ -2057,8 +2118,8 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
...
@@ -2057,8 +2118,8 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
inElse
=
TRUE
;
inElse
=
TRUE
;
lastWasElse
=
TRUE
;
lastWasElse
=
TRUE
;
onlyWhiteSpace
=
TRUE
;
onlyWhiteSpace
=
TRUE
;
memcpy
(
&
cur
String
[
curLen
],
curPos
,
5
*
sizeof
(
WCHAR
));
memcpy
(
&
cur
CopyTo
[
*
curLen
],
curPos
,
5
*
sizeof
(
WCHAR
));
curLen
+=
5
;
(
*
curLen
)
+=
5
;
curPos
+=
5
;
curPos
+=
5
;
continue
;
continue
;
...
@@ -2071,12 +2132,12 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
...
@@ -2071,12 +2132,12 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
WINE_TRACE
(
"Found DO
\n
"
);
WINE_TRACE
(
"Found DO
\n
"
);
lastWasDo
=
TRUE
;
lastWasDo
=
TRUE
;
onlyWhiteSpace
=
TRUE
;
onlyWhiteSpace
=
TRUE
;
memcpy
(
&
cur
String
[
curLen
],
curPos
,
3
*
sizeof
(
WCHAR
));
memcpy
(
&
cur
CopyTo
[
*
curLen
],
curPos
,
3
*
sizeof
(
WCHAR
));
curLen
+=
3
;
(
*
curLen
)
+=
3
;
curPos
+=
3
;
curPos
+=
3
;
continue
;
continue
;
}
}
}
else
{
}
else
if
(
curCopyTo
==
curString
)
{
/* Special handling for the 'FOR' command */
/* Special handling for the 'FOR' command */
if
(
inFor
&&
lastWasWhiteSpace
)
{
if
(
inFor
&&
lastWasWhiteSpace
)
{
...
@@ -2089,8 +2150,8 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
...
@@ -2089,8 +2150,8 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
WINE_TRACE
(
"Found IN
\n
"
);
WINE_TRACE
(
"Found IN
\n
"
);
lastWasIn
=
TRUE
;
lastWasIn
=
TRUE
;
onlyWhiteSpace
=
TRUE
;
onlyWhiteSpace
=
TRUE
;
memcpy
(
&
cur
String
[
curLen
],
curPos
,
3
*
sizeof
(
WCHAR
));
memcpy
(
&
cur
CopyTo
[
*
curLen
],
curPos
,
3
*
sizeof
(
WCHAR
));
curLen
+=
3
;
(
*
curLen
)
+=
3
;
curPos
+=
3
;
curPos
+=
3
;
continue
;
continue
;
}
}
...
@@ -2107,17 +2168,84 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
...
@@ -2107,17 +2168,84 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
switch
(
thisChar
)
{
switch
(
thisChar
)
{
case
'\t'
:
/* drop through - ignore whitespace at the start of a command */
case
'='
:
/* drop through - ignore token delimiters at the start of a command */
case
' '
:
if
(
curLen
>
0
)
case
','
:
/* drop through - ignore token delimiters at the start of a command */
curString
[
curLen
++
]
=
*
curPos
;
case
'\t'
:
/* drop through - ignore token delimiters at the start of a command */
case
' '
:
/* If a redirect in place, it ends here */
if
(
!
inQuotes
&&
!
lastWasRedirect
)
{
/* If finishing off a redirect, add a whitespace delimiter */
if
(
curCopyTo
==
curRedirs
)
{
curCopyTo
[(
*
curLen
)
++
]
=
' '
;
}
curCopyTo
=
curString
;
curLen
=
&
curStringLen
;
}
if
(
*
curLen
>
0
)
{
curCopyTo
[(
*
curLen
)
++
]
=
*
curPos
;
}
/* Remember just processed whitespace */
/* Remember just processed whitespace */
lastWasWhiteSpace
=
TRUE
;
lastWasWhiteSpace
=
TRUE
;
break
;
break
;
case
'>'
:
/* drop through - handle redirect chars the same */
case
'<'
:
/* Make a redirect start here */
if
(
!
inQuotes
)
{
curCopyTo
=
curRedirs
;
curLen
=
&
curRedirsLen
;
lastWasRedirect
=
TRUE
;
}
/* See if 1>, 2> etc, in which case we have some patching up
to do */
if
(
curPos
!=
extraSpace
&&
*
(
curPos
-
1
)
>=
'1'
&&
*
(
curPos
-
1
)
<=
'9'
)
{
curStringLen
--
;
curString
[
curStringLen
]
=
0x00
;
curCopyTo
[(
*
curLen
)
++
]
=
*
(
curPos
-
1
);
}
curCopyTo
[(
*
curLen
)
++
]
=
*
curPos
;
break
;
case
'|'
:
/* Pipe character only if not || */
if
(
!
inQuotes
&&
*
(
curPos
++
)
==
'|'
)
{
/* || is an alternative form of && but runs regardless */
/* If finishing off a redirect, add a whitespace delimiter */
if
(
curCopyTo
==
curRedirs
)
{
curCopyTo
[(
*
curLen
)
++
]
=
' '
;
}
/* If a redirect in place, it ends here */
curCopyTo
=
curString
;
curLen
=
&
curStringLen
;
curCopyTo
[(
*
curLen
)
++
]
=
*
curPos
;
lastWasRedirect
=
FALSE
;
}
else
if
(
inQuotes
)
{
curCopyTo
[(
*
curLen
)
++
]
=
*
curPos
;
lastWasRedirect
=
FALSE
;
}
else
{
/* Make a redirect start here */
curCopyTo
=
curRedirs
;
curLen
=
&
curRedirsLen
;
curCopyTo
[(
*
curLen
)
++
]
=
*
curPos
;
lastWasRedirect
=
TRUE
;
}
break
;
case
'"'
:
inQuotes
=
!
inQuotes
;
case
'"'
:
inQuotes
=
!
inQuotes
;
curString
[
curLen
++
]
=
*
curPos
;
curCopyTo
[(
*
curLen
)
++
]
=
*
curPos
;
lastWasRedirect
=
FALSE
;
break
;
break
;
case
'('
:
/* If a '(' is the first non whitespace in a command portion
case
'('
:
/* If a '(' is the first non whitespace in a command portion
...
@@ -2126,18 +2254,19 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
...
@@ -2126,18 +2254,19 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
WINE_TRACE
(
"Found '(' conditions: curLen(%d), inQ(%d), onlyWS(%d)"
WINE_TRACE
(
"Found '(' conditions: curLen(%d), inQ(%d), onlyWS(%d)"
", for(%d, In:%d, Do:%d)"
", for(%d, In:%d, Do:%d)"
", if(%d, else:%d, lwe:%d)
\n
"
,
", if(%d, else:%d, lwe:%d)
\n
"
,
curLen
,
inQuotes
,
*
curLen
,
inQuotes
,
onlyWhiteSpace
,
onlyWhiteSpace
,
inFor
,
lastWasIn
,
lastWasDo
,
inFor
,
lastWasIn
,
lastWasDo
,
inIf
,
inElse
,
lastWasElse
);
inIf
,
inElse
,
lastWasElse
);
lastWasRedirect
=
FALSE
;
/* Ignore open brackets inside the for set */
/* Ignore open brackets inside the for set */
if
(
curLen
==
0
&&
!
inIn
)
{
if
(
*
curLen
==
0
&&
!
inIn
)
{
curDepth
++
;
curDepth
++
;
/* If in quotes, ignore brackets */
/* If in quotes, ignore brackets */
}
else
if
(
inQuotes
)
{
}
else
if
(
inQuotes
)
{
cur
String
[
curLen
++
]
=
*
curPos
;
cur
CopyTo
[(
*
curLen
)
++
]
=
*
curPos
;
/* In a FOR loop, an unquoted '(' may occur straight after
/* In a FOR loop, an unquoted '(' may occur straight after
IN or DO
IN or DO
...
@@ -2157,98 +2286,71 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
...
@@ -2157,98 +2286,71 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
}
}
/* Add the current command */
/* Add the current command */
thisEntry
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
CMD_LIST
));
WCMD_addCommand
(
curString
,
&
curStringLen
,
thisEntry
->
command
=
HeapAlloc
(
GetProcessHeap
(),
0
,
curRedirs
,
&
curRedirsLen
,
(
curLen
+
1
)
*
sizeof
(
WCHAR
));
&
curCopyTo
,
&
curLen
,
memcpy
(
thisEntry
->
command
,
curString
,
curLen
*
sizeof
(
WCHAR
));
isAmphersand
,
curDepth
,
thisEntry
->
command
[
curLen
]
=
0x00
;
&
lastEntry
,
output
);
curLen
=
0
;
thisEntry
->
nextcommand
=
NULL
;
thisEntry
->
isAmphersand
=
isAmphersand
;
thisEntry
->
bracketDepth
=
curDepth
;
if
(
lastEntry
)
{
lastEntry
->
nextcommand
=
thisEntry
;
}
else
{
*
output
=
thisEntry
;
}
lastEntry
=
thisEntry
;
curDepth
++
;
curDepth
++
;
}
else
{
}
else
{
cur
String
[
curLen
++
]
=
*
curPos
;
cur
CopyTo
[(
*
curLen
)
++
]
=
*
curPos
;
}
}
break
;
break
;
case
'&'
:
if
(
!
inQuotes
&&
*
(
curPos
+
1
)
==
'&'
)
{
case
'&'
:
if
(
!
inQuotes
&&
*
(
curPos
+
1
)
==
'&'
)
{
curPos
++
;
/* Skip other & */
curPos
++
;
/* Skip other & */
lastWasRedirect
=
FALSE
;
/* Add an entry to the command list */
/* Add an entry to the command list */
if
(
curLen
>
0
)
{
if
(
curStringLen
>
0
)
{
thisEntry
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
CMD_LIST
));
thisEntry
->
command
=
HeapAlloc
(
GetProcessHeap
(),
0
,
/* Add the current command */
(
curLen
+
1
)
*
sizeof
(
WCHAR
));
WCMD_addCommand
(
curString
,
&
curStringLen
,
memcpy
(
thisEntry
->
command
,
curString
,
curLen
*
sizeof
(
WCHAR
));
curRedirs
,
&
curRedirsLen
,
thisEntry
->
command
[
curLen
]
=
0x00
;
&
curCopyTo
,
&
curLen
,
curLen
=
0
;
isAmphersand
,
curDepth
,
thisEntry
->
nextcommand
=
NULL
;
&
lastEntry
,
output
);
thisEntry
->
isAmphersand
=
isAmphersand
;
thisEntry
->
bracketDepth
=
curDepth
;
if
(
lastEntry
)
{
lastEntry
->
nextcommand
=
thisEntry
;
}
else
{
*
output
=
thisEntry
;
}
lastEntry
=
thisEntry
;
}
}
isAmphersand
=
TRUE
;
isAmphersand
=
TRUE
;
}
else
{
}
else
{
cur
String
[
curLen
++
]
=
*
curPos
;
cur
CopyTo
[(
*
curLen
)
++
]
=
*
curPos
;
}
}
break
;
break
;
case
')'
:
if
(
!
inQuotes
&&
curDepth
>
0
)
{
case
')'
:
if
(
!
inQuotes
&&
curDepth
>
0
)
{
lastWasRedirect
=
FALSE
;
/* Add the current command if there is one */
/* Add the current command if there is one */
if
(
curLen
)
{
if
(
curStringLen
)
{
thisEntry
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
CMD_LIST
));
thisEntry
->
command
=
HeapAlloc
(
GetProcessHeap
(),
0
,
/* Add the current command */
(
curLen
+
1
)
*
sizeof
(
WCHAR
));
WCMD_addCommand
(
curString
,
&
curStringLen
,
memcpy
(
thisEntry
->
command
,
curString
,
curLen
*
sizeof
(
WCHAR
));
curRedirs
,
&
curRedirsLen
,
thisEntry
->
command
[
curLen
]
=
0x00
;
&
curCopyTo
,
&
curLen
,
curLen
=
0
;
isAmphersand
,
curDepth
,
thisEntry
->
nextcommand
=
NULL
;
&
lastEntry
,
output
);
thisEntry
->
isAmphersand
=
isAmphersand
;
thisEntry
->
bracketDepth
=
curDepth
;
if
(
lastEntry
)
{
lastEntry
->
nextcommand
=
thisEntry
;
}
else
{
*
output
=
thisEntry
;
}
lastEntry
=
thisEntry
;
}
}
/* Add an empty entry to the command list */
/* Add an empty entry to the command list */
thisEntry
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
CMD_LIST
));
isAmphersand
=
FALSE
;
thisEntry
->
command
=
NULL
;
WCMD_addCommand
(
NULL
,
&
curStringLen
,
thisEntry
->
nextcommand
=
NULL
;
curRedirs
,
&
curRedirsLen
,
thisEntry
->
isAmphersand
=
FALSE
;
&
curCopyTo
,
&
curLen
,
thisEntry
->
bracketDepth
=
curDepth
;
isAmphersand
,
curDepth
,
&
lastEntry
,
output
);
curDepth
--
;
curDepth
--
;
if
(
lastEntry
)
{
lastEntry
->
nextcommand
=
thisEntry
;
}
else
{
*
output
=
thisEntry
;
}
lastEntry
=
thisEntry
;
/* Leave inIn if necessary */
/* Leave inIn if necessary */
if
(
inIn
)
inIn
=
FALSE
;
if
(
inIn
)
inIn
=
FALSE
;
}
else
{
}
else
{
cur
String
[
curLen
++
]
=
*
curPos
;
cur
CopyTo
[(
*
curLen
)
++
]
=
*
curPos
;
}
}
break
;
break
;
default:
default:
curString
[
curLen
++
]
=
*
curPos
;
lastWasRedirect
=
FALSE
;
curCopyTo
[(
*
curLen
)
++
]
=
*
curPos
;
}
}
curPos
++
;
curPos
++
;
...
@@ -2264,24 +2366,14 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
...
@@ -2264,24 +2366,14 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
}
}
/* If we have reached the end, add this command into the list */
/* If we have reached the end, add this command into the list */
if
(
*
curPos
==
0x00
&&
curLen
>
0
)
{
if
(
*
curPos
==
0x00
&&
*
curLen
>
0
)
{
/* Add an entry to the command list */
/* Add an entry to the command list */
thisEntry
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
CMD_LIST
));
WCMD_addCommand
(
curString
,
&
curStringLen
,
thisEntry
->
command
=
HeapAlloc
(
GetProcessHeap
(),
0
,
curRedirs
,
&
curRedirsLen
,
(
curLen
+
1
)
*
sizeof
(
WCHAR
));
&
curCopyTo
,
&
curLen
,
memcpy
(
thisEntry
->
command
,
curString
,
curLen
*
sizeof
(
WCHAR
));
isAmphersand
,
curDepth
,
thisEntry
->
command
[
curLen
]
=
0x00
;
&
lastEntry
,
output
);
curLen
=
0
;
thisEntry
->
nextcommand
=
NULL
;
thisEntry
->
isAmphersand
=
isAmphersand
;
thisEntry
->
bracketDepth
=
curDepth
;
if
(
lastEntry
)
{
lastEntry
->
nextcommand
=
thisEntry
;
}
else
{
*
output
=
thisEntry
;
}
lastEntry
=
thisEntry
;
}
}
/* If we have reached the end of the string, see if bracketing outstanding */
/* If we have reached the end of the string, see if bracketing outstanding */
...
@@ -2340,10 +2432,10 @@ CMD_LIST *WCMD_process_commands(CMD_LIST *thisCmd, BOOL oneBracket,
...
@@ -2340,10 +2432,10 @@ CMD_LIST *WCMD_process_commands(CMD_LIST *thisCmd, BOOL oneBracket,
WINE_TRACE
(
"Executing command: '%s'
\n
"
,
wine_dbgstr_w
(
thisCmd
->
command
));
WINE_TRACE
(
"Executing command: '%s'
\n
"
,
wine_dbgstr_w
(
thisCmd
->
command
));
if
(
strchrW
(
thisCmd
->
command
,
'|'
)
!=
NULL
)
{
if
(
strchrW
(
thisCmd
->
redirects
,
'|'
)
!=
NULL
)
{
WCMD_pipe
(
&
thisCmd
,
var
,
val
);
WCMD_pipe
(
&
thisCmd
,
var
,
val
);
}
else
{
}
else
{
WCMD_execute
(
thisCmd
->
command
,
var
,
val
,
&
thisCmd
);
WCMD_execute
(
thisCmd
->
command
,
thisCmd
->
redirects
,
var
,
val
,
&
thisCmd
);
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment