From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/wcmdmain.c | 203 +++++++++++++++++++++------------------- 1 file changed, 108 insertions(+), 95 deletions(-)
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 0bdc062b63d..c8d939f55cd 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -1751,193 +1751,206 @@ static BOOL set_std_redirections(CMD_REDIRECTION *redir) return TRUE; }
-/***************************************************************************** - * 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. - */ -static RETURN_CODE execute_single_command(const WCHAR *command) +static RETURN_CODE run_builtin_command(int cmd_index, WCHAR *cmd) { + size_t count = wcslen(inbuilt[cmd_index]); + WCHAR *parms_start = WCMD_skip_leading_spaces(&cmd[count]); RETURN_CODE return_code; - WCHAR *cmd, *parms_start; - int cmd_index, count; - BOOL prev_echo_mode; - - TRACE("command on entry:%s\n", wine_dbgstr_w(command)); - - /* Move copy of the command onto the heap so it can be expanded */ - cmd = xalloc(MAXSTRING * sizeof(WCHAR)); - lstrcpyW(cmd, command); - handleExpansion(cmd, TRUE); - - TRACE("Command: '%s'\n", wine_dbgstr_w(cmd)); - - /* Changing default drive has to be handled as a special case, anything - * else if it exists after whitespace is ignored - */ - if (cmd[1] == L':' && (!cmd[2] || iswspace(cmd[2]))) { - cmd_index = WCMD_CHGDRIVE; - count = 0; - } - else - { - /* Check if the command entered is internal, and identify which one */ - count = 0; - while (IsCharAlphaNumericW(cmd[count])) { - count++; - } - for (cmd_index=0; cmd_index<=WCMD_EXIT; cmd_index++) { - if (count && CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, - cmd, count, inbuilt[cmd_index], -1) == CSTR_EQUAL) break; - } - } - parms_start = WCMD_skip_leading_spaces(&cmd[count]);
WCMD_parse(parms_start, quals, param1, param2); TRACE("param1: %s, param2: %s\n", wine_dbgstr_w(param1), wine_dbgstr_w(param2));
- if (cmd_index <= WCMD_EXIT && (parms_start[0] == '/') && (parms_start[1] == '?')) { - /* this is a help request for a builtin program */ - cmd_index = WCMD_HELP; - memcpy(parms_start, cmd, count * sizeof(WCHAR)); - parms_start[count] = '\0'; + if (cmd_index <= WCMD_EXIT && (parms_start[0] == '/') && (parms_start[1] == '?')) + { + /* this is a help request for a builtin program */ + cmd_index = WCMD_HELP; + wcscpy(parms_start, inbuilt[cmd_index]); }
- switch (cmd_index) { - - case WCMD_CALL: + switch (cmd_index) + { + case WCMD_CALL: return_code = WCMD_call(parms_start); break; - case WCMD_CD: - case WCMD_CHDIR: + case WCMD_CD: + case WCMD_CHDIR: return_code = WCMD_setshow_default(parms_start); break; - case WCMD_CLS: + case WCMD_CLS: return_code = WCMD_clear_screen(); break; - case WCMD_COPY: + case WCMD_COPY: return_code = WCMD_copy(parms_start); break; - case WCMD_DATE: + case WCMD_DATE: return_code = WCMD_setshow_date(); break; - case WCMD_DEL: - case WCMD_ERASE: + case WCMD_DEL: + case WCMD_ERASE: return_code = WCMD_delete(parms_start); break; - case WCMD_DIR: + case WCMD_DIR: return_code = WCMD_directory(parms_start); break; - case WCMD_ECHO: + case WCMD_ECHO: return_code = WCMD_echo(&cmd[count]); break; - case WCMD_GOTO: + case WCMD_GOTO: return_code = WCMD_goto(); break; - case WCMD_HELP: + case WCMD_HELP: return_code = WCMD_give_help(parms_start); break; - case WCMD_LABEL: + case WCMD_LABEL: return_code = WCMD_label(); break; - case WCMD_MD: - case WCMD_MKDIR: + case WCMD_MD: + case WCMD_MKDIR: return_code = WCMD_create_dir(parms_start); break; - case WCMD_MOVE: + case WCMD_MOVE: return_code = WCMD_move(); break; - case WCMD_PATH: + case WCMD_PATH: return_code = WCMD_setshow_path(parms_start); break; - case WCMD_PAUSE: + case WCMD_PAUSE: return_code = WCMD_pause(); break; - case WCMD_PROMPT: + case WCMD_PROMPT: return_code = WCMD_setshow_prompt(); break; - case WCMD_REM: + case WCMD_REM: return_code = NO_ERROR; break; - case WCMD_REN: - case WCMD_RENAME: + case WCMD_REN: + case WCMD_RENAME: return_code = WCMD_rename(); break; - case WCMD_RD: - case WCMD_RMDIR: + case WCMD_RD: + case WCMD_RMDIR: return_code = WCMD_remove_dir(parms_start); break; - case WCMD_SETLOCAL: + case WCMD_SETLOCAL: return_code = WCMD_setlocal(parms_start); break; - case WCMD_ENDLOCAL: + case WCMD_ENDLOCAL: return_code = WCMD_endlocal(); break; - case WCMD_SET: + case WCMD_SET: return_code = WCMD_setshow_env(parms_start); break; - case WCMD_SHIFT: + case WCMD_SHIFT: return_code = WCMD_shift(parms_start); break; - case WCMD_START: + case WCMD_START: return_code = WCMD_start(parms_start); break; - case WCMD_TIME: + case WCMD_TIME: return_code = WCMD_setshow_time(); break; - case WCMD_TITLE: + case WCMD_TITLE: return_code = WCMD_title(parms_start); break; - case WCMD_TYPE: + case WCMD_TYPE: return_code = WCMD_type(parms_start); break; - case WCMD_VER: + case WCMD_VER: return_code = WCMD_version(); break; - case WCMD_VERIFY: + case WCMD_VERIFY: return_code = WCMD_verify(); break; - case WCMD_VOL: + case WCMD_VOL: return_code = WCMD_volume(); break; - case WCMD_PUSHD: + case WCMD_PUSHD: return_code = WCMD_pushd(parms_start); break; - case WCMD_POPD: + case WCMD_POPD: return_code = WCMD_popd(); break; - case WCMD_ASSOC: + case WCMD_ASSOC: return_code = WCMD_assoc(parms_start, TRUE); break; - case WCMD_COLOR: + case WCMD_COLOR: return_code = WCMD_color(); break; - case WCMD_FTYPE: + case WCMD_FTYPE: return_code = WCMD_assoc(parms_start, FALSE); break; - case WCMD_MORE: + case WCMD_MORE: return_code = WCMD_more(parms_start); break; - case WCMD_CHOICE: + case WCMD_CHOICE: return_code = WCMD_choice(parms_start); break; - case WCMD_MKLINK: + case WCMD_MKLINK: return_code = WCMD_mklink(parms_start); break; case WCMD_CHGDRIVE: return_code = WCMD_change_drive(cmd[0]); break; - case WCMD_EXIT: + case WCMD_EXIT: return_code = WCMD_exit(); break; - default: - prev_echo_mode = echo_mode; + default: + FIXME("Shouldn't happen\n"); + return_code = RETURN_CODE_CANT_LAUNCH; + } + return return_code; +} + +/***************************************************************************** + * 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. + */ +static RETURN_CODE execute_single_command(const WCHAR *command) +{ + RETURN_CODE return_code; + WCHAR *cmd; + int cmd_index, count; + + TRACE("command on entry:%s\n", wine_dbgstr_w(command)); + + /* Move copy of the command onto the heap so it can be expanded */ + cmd = xalloc(MAXSTRING * sizeof(WCHAR)); + lstrcpyW(cmd, command); + handleExpansion(cmd, TRUE); + + TRACE("Command: '%s'\n", wine_dbgstr_w(cmd)); + + /* Changing default drive has to be handled as a special case, anything + * else if it exists after whitespace is ignored + */ + if (cmd[1] == L':' && (!cmd[2] || iswspace(cmd[2]))) { + cmd_index = WCMD_CHGDRIVE; + count = 0; + } + else + { + /* Check if the command entered is internal, and identify which one */ + count = 0; + while (IsCharAlphaNumericW(cmd[count])) { + count++; + } + for (cmd_index=0; cmd_index<=WCMD_EXIT; cmd_index++) { + if (count && CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, + cmd, count, inbuilt[cmd_index], -1) == CSTR_EQUAL) break; + } + } + + if (cmd_index <= WCMD_EXIT) + return_code = run_builtin_command(cmd_index, cmd); + else + { + BOOL prev_echo_mode = echo_mode; return_code = WCMD_run_program(cmd, FALSE); echo_mode = prev_echo_mode; } - free(cmd); return return_code; }