Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
3c058185
Commit
3c058185
authored
Oct 14, 2012
by
Jason Edmeades
Committed by
Alexandre Julliard
Oct 17, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cmd: Add support for calling a built in command.
parent
9f83165e
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
79 additions
and
27 deletions
+79
-27
batch.c
programs/cmd/batch.c
+6
-1
builtins.c
programs/cmd/builtins.c
+5
-5
test_builtins.cmd
programs/cmd/tests/test_builtins.cmd
+16
-0
test_builtins.cmd.exp
programs/cmd/tests/test_builtins.cmd.exp
+12
-7
wcmd.h
programs/cmd/wcmd.h
+2
-2
wcmdmain.c
programs/cmd/wcmdmain.c
+38
-12
No files found.
programs/cmd/batch.c
View file @
3c058185
...
...
@@ -89,7 +89,10 @@ void WCMD_batch (WCHAR *file, WCHAR *command, BOOL called, WCHAR *startLabel, HA
CMD_LIST
*
toExecute
=
NULL
;
/* Commands left to be executed */
if
(
!
WCMD_ReadAndParseLine
(
NULL
,
&
toExecute
,
h
))
break
;
WCMD_process_commands
(
toExecute
,
FALSE
,
NULL
,
NULL
);
/* Note: although this batch program itself may be called, we are not retrying
the command as a result of a call failing to find a program, hence the
retryCall parameter below is FALSE */
WCMD_process_commands
(
toExecute
,
FALSE
,
NULL
,
NULL
,
FALSE
);
WCMD_free_commands
(
toExecute
);
toExecute
=
NULL
;
}
...
...
@@ -649,6 +652,8 @@ void WCMD_call (WCHAR *command) {
/* Run other program if no leading ':' */
if
(
*
command
!=
':'
)
{
WCMD_run_program
(
command
,
TRUE
);
/* If the thing we try to run does not exist, call returns 1 */
if
(
errorlevel
)
errorlevel
=
1
;
}
else
{
WCHAR
gotoLabel
[
MAX_PATH
];
...
...
programs/cmd/builtins.c
View file @
3c058185
...
...
@@ -1439,7 +1439,7 @@ static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd,
/* Process the first command, if there is one */
if
(
executecmds
&&
firstcmd
&&
*
firstcmd
)
{
WCHAR
*
command
=
WCMD_strdupW
(
firstcmd
);
WCMD_execute
(
firstcmd
,
(
*
cmdList
)
->
redirects
,
variable
,
value
,
cmdList
);
WCMD_execute
(
firstcmd
,
(
*
cmdList
)
->
redirects
,
variable
,
value
,
cmdList
,
FALSE
);
HeapFree
(
GetProcessHeap
(),
0
,
command
);
}
...
...
@@ -1468,14 +1468,14 @@ static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd,
(
*
cmdList
)
->
prevDelim
==
CMD_ONSUCCESS
)
{
if
(
processThese
&&
(
*
cmdList
)
->
command
)
{
WCMD_execute
((
*
cmdList
)
->
command
,
(
*
cmdList
)
->
redirects
,
variable
,
value
,
cmdList
);
value
,
cmdList
,
FALSE
);
}
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
,
variable
,
value
);
*
cmdList
=
WCMD_process_commands
(
*
cmdList
,
TRUE
,
variable
,
value
,
FALSE
);
WINE_TRACE
(
"Back from processing commands, (next = %p)
\n
"
,
*
cmdList
);
}
if
(
curPosition
==
*
cmdList
)
*
cmdList
=
(
*
cmdList
)
->
nextcommand
;
...
...
@@ -1497,7 +1497,7 @@ static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd,
/* Skip leading whitespace between condition and the command */
while
(
*
cmd
&&
(
*
cmd
==
' '
||
*
cmd
==
'\t'
))
cmd
++
;
if
(
*
cmd
)
{
WCMD_execute
(
cmd
,
(
*
cmdList
)
->
redirects
,
variable
,
value
,
cmdList
);
WCMD_execute
(
cmd
,
(
*
cmdList
)
->
redirects
,
variable
,
value
,
cmdList
,
FALSE
);
}
}
if
(
curPosition
==
*
cmdList
)
*
cmdList
=
(
*
cmdList
)
->
nextcommand
;
...
...
@@ -1809,7 +1809,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
/* Execute program and redirect output */
wsprintfW
(
temp_cmd
,
redirOut
,
(
itemStart
+
1
),
temp_file
);
WCMD_execute
(
itemStart
,
temp_cmd
,
NULL
,
NULL
,
NULL
);
WCMD_execute
(
itemStart
,
temp_cmd
,
NULL
,
NULL
,
NULL
,
FALSE
);
/* Open the file, read line by line and process */
input
=
CreateFileW
(
temp_file
,
GENERIC_READ
,
FILE_SHARE_READ
,
...
...
programs/cmd/tests/test_builtins.cmd
View file @
3c058185
...
...
@@ -1599,6 +1599,22 @@ echo %ErrorLevel%
rem First look for programs in the path before trying a builtin
echo echo non-builtin dir> dir.cmd
call dir /b
del dir.cmd
rem The below line equates to call (, which does nothing, then the
rem subsequent lines are executed.
call (
echo Line one
echo Line two
)
rem The below line equates to call if, which always fails, then the
rem subsequent lines are executed. Note cmd.exe swallows all lines
rem starting with )
call if 1==1 (
echo Get if
) else (
echo ... and else!
)
call call call echo passed
cd .. & rd /s/q foobar
echo ------------ Testing SHIFT ------------
...
...
programs/cmd/tests/test_builtins.cmd.exp
View file @
3c058185
...
...
@@ -824,14 +824,19 @@ foo ""
foo ''
'' bar
--- with builtins
@todo_wine@
0
@todo_wine@
foo created
@todo_wine@
Should expand foobaz
@todo_wine@
batfile
@todo_wine@
robinfile
@todo_wine@
1
@todo_wine@
1
0
foo created
Should expand foobaz
batfile
robinfile
1
1
non-builtin dir
Line one
Line two
Get if
... and else!
passed
------------ Testing SHIFT ------------
'p1' 'p2' 'p3' 'p4' 'p5'
'p2' 'p3' 'p4' 'p5' ''
...
...
programs/cmd/wcmd.h
View file @
3c058185
...
...
@@ -121,11 +121,11 @@ BOOL WCMD_ReadFile(const HANDLE hIn, WCHAR *intoBuf, const DWORD maxChars, LPDWO
WCHAR
*
WCMD_ReadAndParseLine
(
const
WCHAR
*
initialcmd
,
CMD_LIST
**
output
,
HANDLE
readFrom
);
CMD_LIST
*
WCMD_process_commands
(
CMD_LIST
*
thisCmd
,
BOOL
oneBracket
,
const
WCHAR
*
var
,
const
WCHAR
*
val
);
const
WCHAR
*
var
,
const
WCHAR
*
val
,
BOOL
retrycall
);
void
WCMD_free_commands
(
CMD_LIST
*
cmds
);
void
WCMD_execute
(
const
WCHAR
*
orig_command
,
const
WCHAR
*
redirects
,
const
WCHAR
*
parameter
,
const
WCHAR
*
substitution
,
CMD_LIST
**
cmdList
);
CMD_LIST
**
cmdList
,
BOOL
retrycall
);
/* Data structure to hold context when executing batch files */
...
...
programs/cmd/wcmdmain.c
View file @
3c058185
...
...
@@ -1000,6 +1000,9 @@ static void init_msvcrt_io_block(STARTUPINFOW* st)
* Launching
* Once a match has been found, it is launched - Code currently uses
* findexecutable to achieve this which is left untouched.
* If an executable has not been found, and we were launched through
* a call, we need to check if the command is an internal command,
* so go back through wcmd_execute.
*/
void
WCMD_run_program
(
WCHAR
*
command
,
BOOL
called
)
...
...
@@ -1197,6 +1200,8 @@ void WCMD_run_program (WCHAR *command, BOOL called)
if
(
!
status
)
break
;
called
=
FALSE
;
/* No need to retry as we launched something */
if
(
!
assumeInternal
&&
!
console
)
errorlevel
=
0
;
else
{
...
...
@@ -1212,6 +1217,18 @@ void WCMD_run_program (WCHAR *command, BOOL called)
}
}
/* Not found anywhere - were we called? */
if
(
called
)
{
CMD_LIST
*
toExecute
=
NULL
;
/* Commands left to be executed */
/* Parse the command string, without reading any more input */
WCMD_ReadAndParseLine
(
command
,
&
toExecute
,
INVALID_HANDLE_VALUE
);
WCMD_process_commands
(
toExecute
,
FALSE
,
NULL
,
NULL
,
called
);
WCMD_free_commands
(
toExecute
);
toExecute
=
NULL
;
return
;
}
/* Not found anywhere - give up */
SetLastError
(
ERROR_FILE_NOT_FOUND
);
WCMD_print_error
();
...
...
@@ -1226,10 +1243,13 @@ void WCMD_run_program (WCHAR *command, BOOL called)
/*****************************************************************************
* Process one command. If the command is EXIT this routine does not return.
* We will recurse through here executing batch files.
* Note: If call is used to a non-existing program, we reparse the line and
* try to run it as an internal command. 'retrycall' represents whether
* we are attempting this retry.
*/
void
WCMD_execute
(
const
WCHAR
*
command
,
const
WCHAR
*
redirects
,
const
WCHAR
*
forVariable
,
const
WCHAR
*
forValue
,
CMD_LIST
**
cmdList
)
CMD_LIST
**
cmdList
,
BOOL
retrycall
)
{
WCHAR
*
cmd
,
*
p
,
*
redir
;
int
status
,
i
;
...
...
@@ -1487,18 +1507,12 @@ void WCMD_execute (const WCHAR *command, const WCHAR *redirects,
case
WCMD_ECHO
:
WCMD_echo
(
&
whichcmd
[
count
]);
break
;
case
WCMD_FOR
:
WCMD_for
(
p
,
cmdList
);
break
;
case
WCMD_GOTO
:
WCMD_goto
(
cmdList
);
break
;
case
WCMD_HELP
:
WCMD_give_help
(
p
);
break
;
case
WCMD_IF
:
WCMD_if
(
p
,
cmdList
);
break
;
case
WCMD_LABEL
:
WCMD_volume
(
TRUE
,
p
);
break
;
...
...
@@ -1587,6 +1601,17 @@ void WCMD_execute (const WCHAR *command, const WCHAR *redirects,
case
WCMD_EXIT
:
WCMD_exit
(
cmdList
);
break
;
case
WCMD_FOR
:
case
WCMD_IF
:
/* Very oddly, probably because of all the special parsing required for
these two commands, neither for nor if are supported when called,
ie call if 1==1... will fail. */
if
(
!
retrycall
)
{
if
(
i
==
WCMD_FOR
)
WCMD_for
(
p
,
cmdList
);
else
if
(
i
==
WCMD_IF
)
WCMD_if
(
p
,
cmdList
);
break
;
}
/* else: drop through */
default:
prev_echo_mode
=
echo_mode
;
WCMD_run_program
(
whichcmd
,
FALSE
);
...
...
@@ -2240,7 +2265,8 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
* Process all the commands read in so far
*/
CMD_LIST
*
WCMD_process_commands
(
CMD_LIST
*
thisCmd
,
BOOL
oneBracket
,
const
WCHAR
*
var
,
const
WCHAR
*
val
)
{
const
WCHAR
*
var
,
const
WCHAR
*
val
,
BOOL
retrycall
)
{
int
bdepth
=
-
1
;
...
...
@@ -2265,7 +2291,7 @@ CMD_LIST *WCMD_process_commands(CMD_LIST *thisCmd, BOOL oneBracket,
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
));
WCMD_execute
(
thisCmd
->
command
,
thisCmd
->
redirects
,
var
,
val
,
&
thisCmd
);
WCMD_execute
(
thisCmd
->
command
,
thisCmd
->
redirects
,
var
,
val
,
&
thisCmd
,
retrycall
);
}
/* Step on unless the command itself already stepped on */
...
...
@@ -2555,7 +2581,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
,
FALSE
,
NULL
,
NULL
);
WCMD_process_commands
(
toExecute
,
FALSE
,
NULL
,
NULL
,
FALSE
);
WCMD_free_commands
(
toExecute
);
toExecute
=
NULL
;
...
...
@@ -2642,7 +2668,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
,
FALSE
,
NULL
,
NULL
);
WCMD_process_commands
(
toExecute
,
FALSE
,
NULL
,
NULL
,
FALSE
);
WCMD_free_commands
(
toExecute
);
toExecute
=
NULL
;
HeapFree
(
GetProcessHeap
(),
0
,
cmd
);
...
...
@@ -2662,7 +2688,7 @@ int wmain (int argc, WCHAR *argvW[])
if
(
echo_mode
)
WCMD_show_prompt
();
if
(
!
WCMD_ReadAndParseLine
(
NULL
,
&
toExecute
,
GetStdHandle
(
STD_INPUT_HANDLE
)))
break
;
WCMD_process_commands
(
toExecute
,
FALSE
,
NULL
,
NULL
);
WCMD_process_commands
(
toExecute
,
FALSE
,
NULL
,
NULL
,
FALSE
);
WCMD_free_commands
(
toExecute
);
toExecute
=
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