cmd: Introduce return code to indicate abort of current instruction.

Use that return code for WCMD_exit() and WCMD_goto().

Signed-off-by: Eric Pouech <epouech@codeweavers.com>
This commit is contained in:
Eric Pouech 2024-05-01 09:51:04 +02:00 committed by Alexandre Julliard
parent 844d6b553a
commit 411cce36b1
4 changed files with 23 additions and 20 deletions

View file

@ -77,7 +77,7 @@ void WCMD_batch (WCHAR *file, WCHAR *command, BOOL called, WCHAR *startLabel, HA
/* If processing a call :label, 'goto' the label in question */
if (startLabel) {
lstrcpyW(param1, startLabel);
WCMD_goto(NULL);
WCMD_goto();
}
/*

View file

@ -1926,7 +1926,7 @@ void WCMD_give_help (const WCHAR *args)
}
/****************************************************************************
* WCMD_go_to
* WCMD_goto
*
* Batch file jump instruction. Not the most efficient algorithm ;-)
* Prints error message if the specified label cannot be found - the file pointer is
@ -1934,27 +1934,24 @@ void WCMD_give_help (const WCHAR *args)
* FIXME: DOS is supposed to allow labels with spaces - we don't.
*/
void WCMD_goto (CMD_NODE **cmdList) {
RETURN_CODE WCMD_goto(void)
{
WCHAR string[MAX_PATH];
WCHAR *labelend = NULL;
const WCHAR labelEndsW[] = L"><|& :\t";
/* Do not process any more parts of a processed multipart or multilines command */
if (cmdList) *cmdList = NULL;
if (context != NULL) {
WCHAR *paramStart = param1, *str;
if (param1[0] == 0x00) {
WCMD_output_stderr(WCMD_LoadMessage(WCMD_NOARG));
return;
return ERROR_INVALID_FUNCTION;
}
/* Handle special :EOF label */
if (lstrcmpiW(L":eof", param1) == 0) {
context -> skip_rest = TRUE;
return;
return RETURN_CODE_ABORTED;
}
/* Support goto :label as well as goto label plus remove trailing chars */
@ -2000,7 +1997,7 @@ void WCMD_goto (CMD_NODE **cmdList) {
if (labelend) *labelend = 0x00;
WINE_TRACE("comparing found label %s\n", wine_dbgstr_w(str));
if (lstrcmpiW (str, paramStart) == 0) return;
if (lstrcmpiW (str, paramStart) == 0) return RETURN_CODE_ABORTED;
}
/* See if we have gone beyond the end point if second time through */
@ -2021,7 +2018,7 @@ void WCMD_goto (CMD_NODE **cmdList) {
WCMD_output_stderr(WCMD_LoadMessage(WCMD_NOTARGET));
context -> skip_rest = TRUE;
}
return;
return ERROR_INVALID_FUNCTION;
}
/*****************************************************************************
@ -3966,16 +3963,17 @@ int WCMD_volume(BOOL set_label, const WCHAR *path)
*
*/
void WCMD_exit (CMD_NODE **cmdList) {
RETURN_CODE WCMD_exit(void)
{
int rc = wcstol(param1, NULL, 10); /* Note: wcstol of empty parameter is 0 */
if (context && lstrcmpiW(quals, L"/B") == 0) {
if (context && lstrcmpiW(quals, L"/B") == 0)
{
errorlevel = rc;
context -> skip_rest = TRUE;
*cmdList = NULL;
} else {
ExitProcess(rc);
return RETURN_CODE_ABORTED;
}
ExitProcess(rc);
}

View file

@ -176,10 +176,12 @@ struct _DIRECTORY_STACK *WCMD_dir_stack_free(struct _DIRECTORY_STACK *dir);
/* The return code:
* - some of them are directly mapped to kernel32's errors
* - some others are cmd.exe specific
* - ABORTED if used to break out of FOR/IF blocks (to handle GOTO, EXIT commands)
*/
typedef int RETURN_CODE;
#define RETURN_CODE_SYNTAX_ERROR 255
#define RETURN_CODE_CANT_LAUNCH 9009
#define RETURN_CODE_ABORTED (-999999)
void WCMD_assoc (const WCHAR *, BOOL);
void WCMD_batch (WCHAR *, WCHAR *, BOOL, WCHAR *, HANDLE);
@ -195,11 +197,11 @@ void WCMD_directory (WCHAR *);
void WCMD_echo (const WCHAR *);
void WCMD_endlocal (void);
void WCMD_enter_paged_mode(const WCHAR *);
void WCMD_exit (CMD_NODE **cmdList);
RETURN_CODE WCMD_exit(void);
void WCMD_for (WCHAR *, CMD_NODE **cmdList);
BOOL WCMD_get_fullpath(const WCHAR *, SIZE_T, WCHAR *, WCHAR **);
void WCMD_give_help (const WCHAR *args);
void WCMD_goto (CMD_NODE **cmdList);
RETURN_CODE WCMD_goto(void);
void WCMD_if (WCHAR *, CMD_NODE **cmdList);
void WCMD_leave_paged_mode(void);
void WCMD_more (WCHAR *);

View file

@ -1695,6 +1695,7 @@ static BOOL set_std_redirections(CMD_REDIRECTION *redir, WCHAR *in_pipe)
*/
static void execute_single_command(const WCHAR *command, CMD_NODE **cmdList, BOOL retrycall)
{
RETURN_CODE return_code = NO_ERROR;
WCHAR *cmd, *parms_start;
int status, cmd_index, count;
WCHAR *whichcmd;
@ -1797,7 +1798,7 @@ static void execute_single_command(const WCHAR *command, CMD_NODE **cmdList, BOO
WCMD_echo(&whichcmd[count]);
break;
case WCMD_GOTO:
WCMD_goto (cmdList);
return_code = WCMD_goto();
break;
case WCMD_HELP:
WCMD_give_help (parms_start);
@ -1891,7 +1892,7 @@ static void execute_single_command(const WCHAR *command, CMD_NODE **cmdList, BOO
WCMD_mklink(parms_start);
break;
case WCMD_EXIT:
WCMD_exit (cmdList);
return_code = WCMD_exit();
break;
case WCMD_FOR:
case WCMD_IF:
@ -1911,6 +1912,8 @@ static void execute_single_command(const WCHAR *command, CMD_NODE **cmdList, BOO
}
cleanup:
free(cmd);
if (return_code == RETURN_CODE_ABORTED && cmdList)
*cmdList = NULL;
}
/*****************************************************************************