diff --git a/rosapps/cmd/choice.c b/rosapps/cmd/choice.c new file mode 100644 index 00000000000..1d1c6f39f8d --- /dev/null +++ b/rosapps/cmd/choice.c @@ -0,0 +1,247 @@ +/* + * CHOICE.C - internal command. + * + * + * History: + * + * 12 Aug 1999 (Eric Kohl) + * started. + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_CHOICE + +#include +#include +#include +#include +#include + +#include "cmd.h" +#include "batch.h" + + +static INT +IsKeyInString (LPTSTR lpString, TCHAR cKey, BOOL bCaseSensitive) +{ + PTCHAR p = lpString; + INT val = 0; + + while (*p) + { + if (bCaseSensitive) + { + if (*p == cKey) + return val; + } + else + { + if (_totlower (*p) == _totlower (cKey)) + return val; + } + + val++; + p++; + } + + return -1; +} + + +INT +CommandChoice (LPTSTR cmd, LPTSTR param) +{ + LPTSTR lpOptions = "YN"; + LPTSTR lpText = NULL; + BOOL bNoPrompt = FALSE; + BOOL bCaseSensitive = FALSE; + BOOL bTimeout = FALSE; + INT nTimeout = 0; + TCHAR cDefault = _T('\0'); + INPUT_RECORD ir; + LPTSTR p, np; + LPTSTR *arg; + INT argc; + INT i; + INT val; + + if (_tcsncmp (param, _T("/?"), 2) == 0) + { + ConOutPuts (_T("Prompts the user to select an option.\n" + "\n" + "CHOICE [/C[:]options][/N][/S][/T[:]c,nn][text]\n" + "\n" + " /C[:]options Allowed option characters. Default is YN.\n" + " /N The option characters and the question mark will\n" + " not be appended.\n" + " /S Input is case sensitive.\n" + " /T[:]c,nn Default to c after nn seconds.\n" + " text Displayed prompt.\n" + "\n" + "ERRORLEVEL ...\n")); + return 0; + } + + /* retrieve text */ + p = param; + + while (TRUE) + { + if (*p == _T('\0')) + break; + if (*p != _T('/')) + { + lpText = p; + break; + } + np = _tcschr (p, _T(' ')); + if (!np) + break; + p = np + 1; + } + + /* build parameter array */ + arg = split (param, &argc); + + /* evaluate arguments */ + if (argc > 0) + { + for (i = 0; i < argc; i++) + { + if (_tcsnicmp (arg[i], _T("/c"), 2) == 0) + { + if (arg[i][2] == _T(':')) + lpOptions = &arg[i][3]; + else + lpOptions = &arg[i][2]; + + if (_tcslen (lpOptions) == 0) + { + ConErrPuts (_T("CHOICE: Error!!")); + freep (arg); + return 1; + } + } + else if (_tcsnicmp (arg[i], _T("/n"), 2) == 0) + { + bNoPrompt = TRUE; + } + else if (_tcsnicmp (arg[i], _T("/s"), 2) == 0) + { + bCaseSensitive = TRUE; + } + else if (_tcsnicmp (arg[i], _T("/t"), 2) == 0) + { + LPTSTR s; + + if (arg[i][2] == _T(':')) + { + cDefault = arg[i][3]; + s = & arg[i][4]; + } + else + { + cDefault = arg[i][2]; + s = & arg[i][3]; + } + + if (*s != _T(',')) + { + ConErrPrintf (_T("Format Error: /T!!\n")); + freep (arg); + return 1; + } + + s++; + nTimeout = _ttoi(s); + bTimeout = TRUE; + } + else if (arg[i][0] == _T('/')) + { + ConErrPrintf (_T("Illegal Option: %s"), arg[i]); + freep (arg); + return 1; + } + } + } + + /* print text */ + if (lpText) + ConOutPrintf (_T("%s"), lpText); + + /* print options */ + if (bNoPrompt == FALSE) + { + ConOutPrintf (_T("[%c"), lpOptions[0]); + + for (i = 1; i < _tcslen (lpOptions); i++) + ConOutPrintf (_T(",%c"), lpOptions[i]); + + ConOutPrintf (_T("]?")); + } + + ConInFlush (); + + if (bTimeout) + { + if (WaitForSingleObject (GetStdHandle(STD_INPUT_HANDLE), + nTimeout * 1000) == WAIT_TIMEOUT) + { + val = IsKeyInString (lpOptions, + cDefault, + bCaseSensitive); + + if (val >= 0) + { + ConOutPrintf (_T("%c\n"), lpOptions[val]); + + nErrorLevel = val + 1; + + freep (arg); + +#ifdef DEBUG + DebugPrintf (_T("ErrorLevel: %d\n"), nErrorLevel); +#endif /* DEBUG */ + + return 0; + } + + } + } + + while (TRUE) + { + ConInKey (&ir); + + val = IsKeyInString (lpOptions, +#ifdef _UNICODE + ir.Event.KeyEvent.uChar.UnicodeChar, +#else + ir.Event.KeyEvent.uChar.AsciiChar, +#endif /* _UNICODE */ + bCaseSensitive); + + if (val >= 0) + { + ConOutPrintf (_T("%c\n"), lpOptions[val]); + + nErrorLevel = val + 1; + + break; + } + + Beep (440, 50); + } + + freep (arg); + +#ifdef DEBUG + DebugPrintf (_T("ErrorLevel: %d\n"), nErrorLevel); +#endif /* DEBUG */ + + return 0; +} +#endif /* INCLUDE_CMD_CHOICE */ + +/* EOF */ diff --git a/rosapps/cmd/cmd.c b/rosapps/cmd/cmd.c index e25c8bd6d24..5cc2c399b1b 100644 --- a/rosapps/cmd/cmd.c +++ b/rosapps/cmd/cmd.c @@ -854,10 +854,10 @@ static VOID Initialize (int argc, char *argv[]) #endif /* get version information */ - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx (&osvi); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx (&osvi); - InitLocale (); + InitLocale (); /* get default input and output console handles */ hOut = GetStdHandle (STD_OUTPUT_HANDLE); @@ -867,7 +867,7 @@ static VOID Initialize (int argc, char *argv[]) InitLastPath (); #endif - if (argc >= 2) + if (argc >= 2) { if (!_tcsncmp (argv[1], _T("/?"), 2)) { @@ -944,6 +944,9 @@ static VOID Initialize (int argc, char *argv[]) if (argv) SetEnvironmentVariable (_T("COMSPEC"), argv[0]); #endif + +#if 0 + /* Experimental ReactOS code */ ConOutPrintf("argc: %d\n", argc); if (!argv) { @@ -953,7 +956,7 @@ static VOID Initialize (int argc, char *argv[]) { } - +#endif /* 0 */ /* add ctrl handler */ #if 0 diff --git a/rosapps/cmd/cmd.h b/rosapps/cmd/cmd.h index 95313a36db7..38e9bcc37f6 100644 --- a/rosapps/cmd/cmd.h +++ b/rosapps/cmd/cmd.h @@ -30,7 +30,7 @@ #include -#define CMD_VER "0.1 pre 2" +#define CMD_VER "0.1 pre 5" #ifdef _MSC_VER #define SHELLVER "Version " CMD_VER " [" __DATE__ ", msc]" @@ -105,6 +105,10 @@ INT cmd_beep (LPTSTR, LPTSTR); INT cmd_call (LPTSTR, LPTSTR); +/* Prototypes for CHOICE.C */ +INT CommandChoice (LPTSTR, LPTSTR); + + /* Prototypes for CLS.C */ INT cmd_cls (LPTSTR, LPTSTR); @@ -136,6 +140,7 @@ VOID DebugPrintf (LPTSTR, ...); #endif /* _DEBUG */ VOID ConInDummy (VOID); +VOID ConInFlush (VOID); VOID ConInKey (PINPUT_RECORD); VOID ConInString (LPTSTR, DWORD); diff --git a/rosapps/cmd/cmdtable.c b/rosapps/cmd/cmdtable.c index 850b12a9246..d0f7d3a53c5 100644 --- a/rosapps/cmd/cmdtable.c +++ b/rosapps/cmd/cmdtable.c @@ -68,6 +68,11 @@ COMMAND cmds[] = {_T("chcp"), 0, CommandChcp}, #endif +#ifdef INCLUDE_CMD_CHOICE + {_T("choice"), 0, CommandChoice}, +#endif + + #ifdef INCLUDE_CMD_CLS {_T("cls"), 0, cmd_cls}, #endif diff --git a/rosapps/cmd/config.h b/rosapps/cmd/config.h index 27910cac438..0f7808bc8bd 100644 --- a/rosapps/cmd/config.h +++ b/rosapps/cmd/config.h @@ -9,11 +9,13 @@ * */ +/* undefine only if used under ReactOS */ #define __REACTOS__ #ifndef _CONFIG_H_INCLUDED_ #define _CONFIG_H_INCLUDED_ + #ifndef __REACTOS__ #define WIN32_LEAN_AND_MEAN #endif /* __REACTOS__ */ @@ -59,6 +61,7 @@ /*#define INCLUDE_CMD_BREAK*/ #define INCLUDE_CMD_CHCP #define INCLUDE_CMD_CHDIR +#define INCLUDE_CMD_CHOICE #define INCLUDE_CMD_CLS #define INCLUDE_CMD_COLOR #define INCLUDE_CMD_COPY @@ -86,7 +89,7 @@ #define INCLUDE_CMD_VOL /* -command that do not have a define: +commands that do not have a define: exit call diff --git a/rosapps/cmd/console.c b/rosapps/cmd/console.c index a4881d63442..51260fba548 100644 --- a/rosapps/cmd/console.c +++ b/rosapps/cmd/console.c @@ -52,6 +52,11 @@ VOID ConInDummy (VOID) ReadConsoleInput (hInput, &dummy, 1, &dwRead); } +VOID ConInFlush (VOID) +{ + FlushConsoleInputBuffer (GetStdHandle (STD_INPUT_HANDLE)); +} + VOID ConInKey (PINPUT_RECORD lpBuffer) { @@ -232,7 +237,7 @@ VOID SetCursorType (BOOL bInsert, BOOL bVisible) { CONSOLE_CURSOR_INFO cci; - cci.dwSize = bInsert ? 10 : 100; + cci.dwSize = bInsert ? 10 : 99; cci.bVisible = bVisible; SetConsoleCursorInfo (GetStdHandle (STD_OUTPUT_HANDLE), &cci);