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
d2e7b401
Commit
d2e7b401
authored
Jun 15, 2007
by
Jason Edmeades
Committed by
Alexandre Julliard
Jun 18, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cmd.exe: Support IF..ELSE processing tolerate multiline/part lines.
parent
345cb891
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
130 additions
and
24 deletions
+130
-24
batch.c
programs/cmd/batch.c
+1
-1
builtins.c
programs/cmd/builtins.c
+86
-3
wcmd.h
programs/cmd/wcmd.h
+1
-1
wcmdmain.c
programs/cmd/wcmdmain.c
+42
-19
No files found.
programs/cmd/batch.c
View file @
d2e7b401
...
...
@@ -109,7 +109,7 @@ void WCMD_batch (WCHAR *file, WCHAR *command, int called, WCHAR *startLabel, HAN
CMD_LIST
*
toExecute
=
NULL
;
/* Commands left to be executed */
if
(
WCMD_ReadAndParseLine
(
NULL
,
&
toExecute
,
h
)
==
NULL
)
break
;
WCMD_process_commands
(
toExecute
);
WCMD_process_commands
(
toExecute
,
FALSE
);
WCMD_free_commands
(
toExecute
);
toExecute
=
NULL
;
}
...
...
programs/cmd/builtins.c
View file @
d2e7b401
...
...
@@ -790,6 +790,14 @@ void WCMD_popd (void) {
* WCMD_if
*
* Batch file conditional.
*
* On entry, cmdlist will point to command containing the IF, and optionally
* the first command to execute (if brackets not found)
* If &&'s were found, this may be followed by a record flagged as isAmpersand
* If ('s were found, execute all within that bracket
* Command may optionally be followed by an ELSE - need to skip instructions
* in the else using the same logic
*
* FIXME: Much more syntax checking needed!
*/
...
...
@@ -802,6 +810,8 @@ void WCMD_if (WCHAR *p, CMD_LIST **cmdList) {
static
const
WCHAR
existW
[]
=
{
'e'
,
'x'
,
'i'
,
's'
,
't'
,
'\0'
};
static
const
WCHAR
defdW
[]
=
{
'd'
,
'e'
,
'f'
,
'i'
,
'n'
,
'e'
,
'd'
,
'\0'
};
static
const
WCHAR
eqeqW
[]
=
{
'='
,
'='
,
'\0'
};
CMD_LIST
*
curPosition
;
int
myDepth
;
if
(
!
lstrcmpiW
(
param1
,
notW
))
{
negate
=
1
;
...
...
@@ -835,10 +845,83 @@ void WCMD_if (WCHAR *p, CMD_LIST **cmdList) {
WCMD_output
(
WCMD_LoadMessage
(
WCMD_SYNTAXERR
));
return
;
}
/* Process rest of IF statement which is on the same line
Note: This may process all or some of the cmdList (eg a GOTO) */
curPosition
=
*
cmdList
;
myDepth
=
(
*
cmdList
)
->
bracketDepth
;
if
(
test
!=
negate
)
{
command
=
WCMD_strdupW
(
command
);
WCMD_process_command
(
command
,
cmdList
);
free
(
command
);
WCHAR
*
cmd
=
command
;
/* Skip leading whitespace between condition and the command */
while
(
cmd
&&
*
cmd
&&
(
*
cmd
==
' '
||
*
cmd
==
'\t'
))
cmd
++
;
if
(
cmd
&&
*
cmd
)
{
command
=
WCMD_strdupW
(
cmd
);
WCMD_process_command
(
command
,
cmdList
);
free
(
command
);
}
}
/* If it didnt move the position, step to next command */
if
(
curPosition
==
*
cmdList
)
*
cmdList
=
(
*
cmdList
)
->
nextcommand
;
/* Process any other parts of the IF */
if
(
*
cmdList
)
{
BOOL
processThese
=
(
test
!=
negate
);
while
(
*
cmdList
)
{
const
WCHAR
ifElse
[]
=
{
'e'
,
'l'
,
's'
,
'e'
,
' '
,
'\0'
};
/* execute all appropriate commands */
curPosition
=
*
cmdList
;
WINE_TRACE
(
"Processing cmdList(%p) - &(%d) bd(%d / %d)
\n
"
,
*
cmdList
,
(
*
cmdList
)
->
isAmphersand
,
(
*
cmdList
)
->
bracketDepth
,
myDepth
);
/* Execute any appended to the statement with &&'s */
if
((
*
cmdList
)
->
isAmphersand
)
{
if
(
processThese
)
{
WCMD_process_command
((
*
cmdList
)
->
command
,
cmdList
);
}
if
(
curPosition
==
*
cmdList
)
*
cmdList
=
(
*
cmdList
)
->
nextcommand
;
/* Execute any appended to the statement with (...) */
}
else
if
((
*
cmdList
)
->
bracketDepth
>
myDepth
)
{
if
(
processThese
)
{
*
cmdList
=
WCMD_process_commands
(
*
cmdList
,
TRUE
);
WINE_TRACE
(
"Back from processing commands, (next = %p)
\n
"
,
*
cmdList
);
}
if
(
curPosition
==
*
cmdList
)
*
cmdList
=
(
*
cmdList
)
->
nextcommand
;
/* End of the command - does 'ELSE ' follow as the next command? */
}
else
{
if
(
CompareString
(
LOCALE_USER_DEFAULT
,
NORM_IGNORECASE
|
SORT_STRINGSORT
,
(
*
cmdList
)
->
command
,
5
,
ifElse
,
-
1
)
==
2
)
{
/* Swap between if and else processing */
processThese
=
!
processThese
;
/* Process the ELSE part */
if
(
processThese
)
{
WCHAR
*
cmd
=
((
*
cmdList
)
->
command
)
+
strlenW
(
ifElse
);
/* Skip leading whitespace between condition and the command */
while
(
*
cmd
&&
(
*
cmd
==
' '
||
*
cmd
==
'\t'
))
cmd
++
;
if
(
*
cmd
)
{
WCMD_process_command
(
cmd
,
cmdList
);
}
}
if
(
curPosition
==
*
cmdList
)
*
cmdList
=
(
*
cmdList
)
->
nextcommand
;
}
else
{
WINE_TRACE
(
"Found end of this IF statement (next = %p)
\n
"
,
*
cmdList
);
break
;
}
}
}
}
}
...
...
programs/cmd/wcmd.h
View file @
d2e7b401
...
...
@@ -102,7 +102,7 @@ BOOL WCMD_ReadFile(const HANDLE hIn, WCHAR *intoBuf, const DWORD maxChars,
LPDWORD
charsRead
,
const
LPOVERLAPPED
unused
);
WCHAR
*
WCMD_ReadAndParseLine
(
WCHAR
*
initialcmd
,
CMD_LIST
**
output
,
HANDLE
readFrom
);
void
WCMD_process_commands
(
CMD_LIST
*
thisCmd
);
CMD_LIST
*
WCMD_process_commands
(
CMD_LIST
*
thisCmd
,
BOOL
oneBracket
);
void
WCMD_free_commands
(
CMD_LIST
*
cmds
);
/* Data structure to hold context when executing batch files */
...
...
programs/cmd/wcmdmain.c
View file @
d2e7b401
...
...
@@ -324,7 +324,7 @@ int wmain (int argc, WCHAR *argvW[])
/* Parse the command string, without reading any more input */
WCMD_ReadAndParseLine
(
cmd
,
&
toExecute
,
INVALID_HANDLE_VALUE
);
WCMD_process_commands
(
toExecute
);
WCMD_process_commands
(
toExecute
,
FALSE
);
WCMD_free_commands
(
toExecute
);
toExecute
=
NULL
;
...
...
@@ -417,7 +417,7 @@ int wmain (int argc, WCHAR *argvW[])
if
(
opt_k
)
{
/* Parse the command string, without reading any more input */
WCMD_ReadAndParseLine
(
cmd
,
&
toExecute
,
INVALID_HANDLE_VALUE
);
WCMD_process_commands
(
toExecute
);
WCMD_process_commands
(
toExecute
,
FALSE
);
WCMD_free_commands
(
toExecute
);
toExecute
=
NULL
;
HeapFree
(
GetProcessHeap
(),
0
,
cmd
);
...
...
@@ -449,7 +449,7 @@ int wmain (int argc, WCHAR *argvW[])
if
(
WCMD_ReadAndParseLine
(
NULL
,
&
toExecute
,
GetStdHandle
(
STD_INPUT_HANDLE
))
==
NULL
)
break
;
WCMD_process_commands
(
toExecute
);
WCMD_process_commands
(
toExecute
,
FALSE
);
WCMD_free_commands
(
toExecute
);
toExecute
=
NULL
;
}
...
...
@@ -2044,6 +2044,7 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
break
;
case
'"'
:
inQuotes
=
!
inQuotes
;
curString
[
curLen
++
]
=
*
curPos
;
break
;
case
'('
:
/* If a '(' is the first non whitespace in a command portion
...
...
@@ -2101,21 +2102,23 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
curPos
++
;
/* Skip other & */
/* Add an entry to the command list */
thisEntry
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
CMD_LIST
));
thisEntry
->
command
=
HeapAlloc
(
GetProcessHeap
(),
0
,
(
curLen
+
1
)
*
sizeof
(
WCHAR
));
memcpy
(
thisEntry
->
command
,
curString
,
curLen
*
sizeof
(
WCHAR
));
thisEntry
->
command
[
curLen
]
=
0x00
;
curLen
=
0
;
thisEntry
->
nextcommand
=
NULL
;
thisEntry
->
isAmphersand
=
isAmphersand
;
thisEntry
->
bracketDepth
=
curDepth
;
if
(
lastEntry
)
{
lastEntry
->
nextcommand
=
thisEntry
;
}
else
{
*
output
=
thisEntry
;
if
(
curLen
>
0
)
{
thisEntry
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
CMD_LIST
));
thisEntry
->
command
=
HeapAlloc
(
GetProcessHeap
(),
0
,
(
curLen
+
1
)
*
sizeof
(
WCHAR
));
memcpy
(
thisEntry
->
command
,
curString
,
curLen
*
sizeof
(
WCHAR
));
thisEntry
->
command
[
curLen
]
=
0x00
;
curLen
=
0
;
thisEntry
->
nextcommand
=
NULL
;
thisEntry
->
isAmphersand
=
isAmphersand
;
thisEntry
->
bracketDepth
=
curDepth
;
if
(
lastEntry
)
{
lastEntry
->
nextcommand
=
thisEntry
;
}
else
{
*
output
=
thisEntry
;
}
lastEntry
=
thisEntry
;
}
lastEntry
=
thisEntry
;
isAmphersand
=
TRUE
;
}
else
{
curString
[
curLen
++
]
=
*
curPos
;
...
...
@@ -2224,24 +2227,44 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
*
* Process all the commands read in so far
*/
void
WCMD_process_commands
(
CMD_LIST
*
thisCmd
)
{
CMD_LIST
*
WCMD_process_commands
(
CMD_LIST
*
thisCmd
,
BOOL
oneBracket
)
{
int
bdepth
=
-
1
;
if
(
thisCmd
&&
oneBracket
)
bdepth
=
thisCmd
->
bracketDepth
;
/* Loop through the commands, processing them one by one */
while
(
thisCmd
)
{
CMD_LIST
*
origCmd
=
thisCmd
;
/* If processing one bracket only, and we find the end bracket
entry (or less), return */
if
(
oneBracket
&&
!
thisCmd
->
command
&&
bdepth
<=
thisCmd
->
bracketDepth
)
{
WINE_TRACE
(
"Finished bracket @ %p, next command is %p
\n
"
,
thisCmd
,
thisCmd
->
nextcommand
);
return
thisCmd
->
nextcommand
;
}
/* Ignore the NULL entries a ')' inserts (Only 'if' cares
about them and it will be handled in there)
Also, skip over any batch labels (eg. :fred) */
if
(
thisCmd
->
command
&&
thisCmd
->
command
[
0
]
!=
':'
)
{
WINE_TRACE
(
"Executing command: '%s'
\n
"
,
wine_dbgstr_w
(
thisCmd
->
command
));
if
(
strchrW
(
thisCmd
->
command
,
'|'
)
!=
NULL
)
{
WCMD_pipe
(
&
thisCmd
);
}
else
{
WCMD_process_command
(
thisCmd
->
command
,
&
thisCmd
);
}
}
if
(
thisCmd
)
thisCmd
=
thisCmd
->
nextcommand
;
/* Step on unless the command itself already stepped on */
if
(
thisCmd
==
origCmd
)
thisCmd
=
thisCmd
->
nextcommand
;
}
return
NULL
;
}
/***************************************************************************
...
...
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