Commit 7045e478 authored by Detlef Riekenberg's avatar Detlef Riekenberg Committed by Alexandre Julliard

cmd: Add CHOICE builtin with DOS6 to XP commandline parameter.

parent 2f30e3e4
...@@ -211,6 +211,10 @@ PUSHD.\n" ...@@ -211,6 +211,10 @@ PUSHD.\n"
WCMD_MORE, "MORE displays output of files or piped input in pages.\n" WCMD_MORE, "MORE displays output of files or piped input in pages.\n"
WCMD_CHOICE, "CHOICE displays a text and waits, until the User\n\
press an allowed Key from a selectable list.\n\
CHOICE is mainly used to build a menu selection in a batch file.\n"
WCMD_EXIT, WCMD_EXIT,
"EXIT terminates the current command session and returns\n\ "EXIT terminates the current command session and returns\n\
to the operating system or shell from which you invoked cmd.\n" to the operating system or shell from which you invoked cmd.\n"
...@@ -219,6 +223,7 @@ to the operating system or shell from which you invoked cmd.\n" ...@@ -219,6 +223,7 @@ to the operating system or shell from which you invoked cmd.\n"
ATTRIB\t\tShow or change DOS file attributes\n\ ATTRIB\t\tShow or change DOS file attributes\n\
CALL\t\tInvoke a batch file from inside another\n\ CALL\t\tInvoke a batch file from inside another\n\
CD (CHDIR)\tChange current default directory\n\ CD (CHDIR)\tChange current default directory\n\
CHOICE\t\tWait for an keypress from a selectable list\n\
CLS\t\tClear the console screen\n\ CLS\t\tClear the console screen\n\
COPY\t\tCopy file\n\ COPY\t\tCopy file\n\
CTTY\t\tChange input/output device\n\ CTTY\t\tChange input/output device\n\
......
...@@ -160,6 +160,174 @@ void WCMD_change_tty (void) { ...@@ -160,6 +160,174 @@ void WCMD_change_tty (void) {
} }
/**************************************************************************** /****************************************************************************
* WCMD_choice
*
*/
void WCMD_choice (WCHAR * command) {
static const WCHAR bellW[] = {7,0};
static const WCHAR commaW[] = {',',0};
static const WCHAR bracket_open[] = {'[',0};
static const WCHAR bracket_close[] = {']','?',0};
WCHAR answer[16];
WCHAR buffer[16];
WCHAR *ptr = NULL;
WCHAR *opt_c = NULL;
WCHAR *my_command = NULL;
WCHAR opt_default = 0;
DWORD opt_timeout = 0;
DWORD count;
DWORD oldmode;
DWORD have_console;
BOOL opt_n = FALSE;
BOOL opt_s = FALSE;
have_console = GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &oldmode);
errorlevel = 0;
my_command = WCMD_strdupW(WCMD_strtrim_leading_spaces(command));
if (!my_command)
return;
ptr = WCMD_strtrim_leading_spaces(my_command);
while (*ptr == '/') {
switch (toupperW(ptr[1])) {
case 'C':
ptr += 2;
/* the colon is optional */
if (*ptr == ':')
ptr++;
if (!*ptr || isspaceW(*ptr)) {
WINE_FIXME("bad parameter %s for /C\n", wine_dbgstr_w(ptr));
HeapFree(GetProcessHeap(), 0, my_command);
return;
}
/* remember the allowed keys (overwrite previous /C option) */
opt_c = ptr;
while (*ptr && (!isspaceW(*ptr)))
ptr++;
if (*ptr) {
/* terminate allowed chars */
*ptr = 0;
ptr = WCMD_strtrim_leading_spaces(&ptr[1]);
}
WINE_TRACE("answer-list: %s\n", wine_dbgstr_w(opt_c));
break;
case 'N':
opt_n = TRUE;
ptr = WCMD_strtrim_leading_spaces(&ptr[2]);
break;
case 'S':
opt_s = TRUE;
ptr = WCMD_strtrim_leading_spaces(&ptr[2]);
break;
case 'T':
ptr = &ptr[2];
/* the colon is optional */
if (*ptr == ':')
ptr++;
opt_default = *ptr++;
if (!opt_default || (*ptr != ',')) {
WINE_FIXME("bad option %s for /T\n", opt_default ? wine_dbgstr_w(ptr) : "");
HeapFree(GetProcessHeap(), 0, my_command);
return;
}
ptr++;
count = 0;
while (((answer[count] = *ptr)) && isdigitW(*ptr) && (count < 15)) {
count++;
ptr++;
}
answer[count] = 0;
opt_timeout = atoiW(answer);
ptr = WCMD_strtrim_leading_spaces(ptr);
break;
default:
WINE_FIXME("bad parameter: %s\n", wine_dbgstr_w(ptr));
HeapFree(GetProcessHeap(), 0, my_command);
return;
}
}
if (opt_timeout)
WINE_FIXME("timeout not supported: %c,%d\n", opt_default, opt_timeout);
if (have_console)
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), 0);
/* use default keys, when needed: localized versions of "Y"es and "No" */
if (!opt_c) {
LoadStringW(hinst, WCMD_YES, buffer, sizeof(buffer)/sizeof(WCHAR));
LoadStringW(hinst, WCMD_NO, buffer + 1, sizeof(buffer)/sizeof(WCHAR) - 1);
opt_c = buffer;
buffer[2] = 0;
}
/* print the question, when needed */
if (*ptr)
WCMD_output_asis(ptr);
if (!opt_s) {
struprW(opt_c);
WINE_TRACE("case insensitive answer-list: %s\n", wine_dbgstr_w(opt_c));
}
if (!opt_n) {
/* print a list of all allowed answers inside brackets */
WCMD_output_asis(bracket_open);
ptr = opt_c;
answer[1] = 0;
while ((answer[0] = *ptr++)) {
WCMD_output_asis(answer);
if (*ptr)
WCMD_output_asis(commaW);
}
WCMD_output_asis(bracket_close);
}
while (TRUE) {
/* FIXME: Add support for option /T */
WCMD_ReadFile(GetStdHandle(STD_INPUT_HANDLE), answer, 1, &count, NULL);
if (!opt_s)
answer[0] = toupperW(answer[0]);
ptr = strchrW(opt_c, answer[0]);
if (ptr) {
WCMD_output_asis(answer);
WCMD_output(newline);
if (have_console)
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), oldmode);
errorlevel = (ptr - opt_c) + 1;
WINE_TRACE("answer: %d\n", errorlevel);
HeapFree(GetProcessHeap(), 0, my_command);
return;
}
else
{
/* key not allowed: play the bell */
WINE_TRACE("key not allowed: %s\n", wine_dbgstr_w(answer));
WCMD_output_asis(bellW);
}
}
}
/****************************************************************************
* WCMD_copy * WCMD_copy
* *
* Copy a file or wildcarded set. * Copy a file or wildcarded set.
......
...@@ -52,6 +52,7 @@ void WCMD_assoc (WCHAR *, BOOL); ...@@ -52,6 +52,7 @@ void WCMD_assoc (WCHAR *, BOOL);
void WCMD_batch (WCHAR *, WCHAR *, int, WCHAR *, HANDLE); void WCMD_batch (WCHAR *, WCHAR *, int, WCHAR *, HANDLE);
void WCMD_call (WCHAR *command); void WCMD_call (WCHAR *command);
void WCMD_change_tty (void); void WCMD_change_tty (void);
void WCMD_choice (WCHAR *);
void WCMD_clear_screen (void); void WCMD_clear_screen (void);
void WCMD_color (void); void WCMD_color (void);
void WCMD_copy (void); void WCMD_copy (void);
...@@ -202,9 +203,10 @@ typedef struct _DIRECTORY_STACK ...@@ -202,9 +203,10 @@ typedef struct _DIRECTORY_STACK
#define WCMD_COLOR 41 #define WCMD_COLOR 41
#define WCMD_FTYPE 42 #define WCMD_FTYPE 42
#define WCMD_MORE 43 #define WCMD_MORE 43
#define WCMD_CHOICE 44
/* Must be last in list */ /* Must be last in list */
#define WCMD_EXIT 44 #define WCMD_EXIT 45
/* Some standard messages */ /* Some standard messages */
extern const WCHAR newline[]; extern const WCHAR newline[];
......
...@@ -76,6 +76,7 @@ const WCHAR inbuilt[][10] = { ...@@ -76,6 +76,7 @@ const WCHAR inbuilt[][10] = {
{'C','O','L','O','R','\0'}, {'C','O','L','O','R','\0'},
{'F','T','Y','P','E','\0'}, {'F','T','Y','P','E','\0'},
{'M','O','R','E','\0'}, {'M','O','R','E','\0'},
{'C','H','O','I','C','E','\0'},
{'E','X','I','T','\0'} {'E','X','I','T','\0'}
}; };
...@@ -1543,6 +1544,9 @@ void WCMD_execute (WCHAR *command, WCHAR *redirects, ...@@ -1543,6 +1544,9 @@ void WCMD_execute (WCHAR *command, WCHAR *redirects,
case WCMD_MORE: case WCMD_MORE:
WCMD_more(p); WCMD_more(p);
break; break;
case WCMD_CHOICE:
WCMD_choice(p);
break;
case WCMD_EXIT: case WCMD_EXIT:
WCMD_exit (cmdList); WCMD_exit (cmdList);
break; break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment