mirror of
https://github.com/reactos/reactos.git
synced 2024-06-27 16:31:30 +00:00
c49ed3a82c
- a hack in cmd_mkdir that was already obsolete a decade ago - to distinguish "echo" from "echo.", but that is the wrong way to implement this anyway. There's nothing particularly special about the period, "echo" is just one of those commands that is lenient about where its parameters begin, and when it echos a line, the first character (usually a space, but in the case of "echo." a period) is skipped. svn path=/trunk/; revision=35647
313 lines
5.4 KiB
C
313 lines
5.4 KiB
C
/*
|
|
* CHOICE.C - internal command.
|
|
*
|
|
*
|
|
* History:
|
|
*
|
|
* 12 Aug 1999 (Eric Kohl)
|
|
* started.
|
|
*
|
|
* 01 Sep 1999 (Eric Kohl)
|
|
* Fixed help text.
|
|
*
|
|
* 26 Sep 1999 (Paolo Pantaleo)
|
|
* Fixed timeout.
|
|
*
|
|
* 02 Apr 2005 (Magnus Olsen
|
|
* Remove Hardcode string so
|
|
* they can be translate
|
|
*
|
|
*/
|
|
|
|
#include <precomp.h>
|
|
|
|
#ifdef INCLUDE_CMD_CHOICE
|
|
|
|
|
|
#define GC_TIMEOUT -1
|
|
#define GC_NOKEY 0 //an event occurred but it wasn't a key pressed
|
|
#define GC_KEYREAD 1 //a key has been read
|
|
|
|
|
|
static INT
|
|
GetCharacterTimeout (LPTCH ch, DWORD dwMilliseconds)
|
|
{
|
|
//--------------------------------------------
|
|
// Get a character from standard input but with a timeout.
|
|
// The function will wait a limited amount
|
|
// of time, then the function returns GC_TIMEOUT.
|
|
//
|
|
// dwMilliseconds is the timeout value, that can
|
|
// be set to INFINITE, so the function works like
|
|
// stdio.h's getchar()
|
|
|
|
HANDLE hInput;
|
|
DWORD dwRead;
|
|
|
|
INPUT_RECORD lpBuffer;
|
|
|
|
hInput = GetStdHandle (STD_INPUT_HANDLE);
|
|
|
|
//if the timeout experied return GC_TIMEOUT
|
|
if (WaitForSingleObject (hInput, dwMilliseconds) == WAIT_TIMEOUT)
|
|
return GC_TIMEOUT;
|
|
|
|
//otherwise get the event
|
|
ReadConsoleInput (hInput, &lpBuffer, 1, &dwRead);
|
|
|
|
//if the event is a key pressed
|
|
if ((lpBuffer.EventType == KEY_EVENT) &&
|
|
(lpBuffer.Event.KeyEvent.bKeyDown == TRUE))
|
|
{
|
|
//read the key
|
|
#ifdef _UNICODE
|
|
*ch = lpBuffer.Event.KeyEvent.uChar.UnicodeChar;
|
|
#else
|
|
*ch = lpBuffer.Event.KeyEvent.uChar.AsciiChar;
|
|
#endif
|
|
return GC_KEYREAD;
|
|
}
|
|
|
|
//else return no key
|
|
return GC_NOKEY;
|
|
}
|
|
|
|
static INT
|
|
IsKeyInString (LPTSTR lpString, TCHAR cKey, BOOL bCaseSensitive)
|
|
{
|
|
LPTCH 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 param)
|
|
{
|
|
LPTSTR lpOptions;
|
|
TCHAR Options[6];
|
|
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;
|
|
|
|
INT GCret;
|
|
TCHAR Ch;
|
|
DWORD amount,clk;
|
|
|
|
LoadString(CMD_ModuleHandle, STRING_CHOICE_OPTION, Options, 4);
|
|
lpOptions = Options;
|
|
|
|
if (_tcsncmp (param, _T("/?"), 2) == 0)
|
|
{
|
|
ConOutResPaging(TRUE,STRING_CHOICE_HELP);
|
|
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, FALSE);
|
|
|
|
/* 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)
|
|
{
|
|
ConErrResPuts(STRING_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(','))
|
|
{
|
|
ConErrResPuts(STRING_CHOICE_ERROR_TXT);
|
|
freep (arg);
|
|
return 1;
|
|
}
|
|
|
|
s++;
|
|
nTimeout = _ttoi(s);
|
|
bTimeout = TRUE;
|
|
}
|
|
else if (arg[i][0] == _T('/'))
|
|
{
|
|
ConErrResPrintf(STRING_CHOICE_ERROR_OPTION, 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; (unsigned)i < _tcslen (lpOptions); i++)
|
|
ConOutPrintf (_T(",%c"), lpOptions[i]);
|
|
|
|
ConOutPrintf (_T("]?"));
|
|
}
|
|
|
|
ConInFlush ();
|
|
|
|
if(!bTimeout)
|
|
{
|
|
while (TRUE)
|
|
{
|
|
ConInKey (&ir);
|
|
|
|
val = IsKeyInString (lpOptions,
|
|
#ifdef _UNICODE
|
|
ir.Event.KeyEvent.uChar.UnicodeChar,
|
|
#else
|
|
ir.Event.KeyEvent.uChar.AsciiChar,
|
|
#endif
|
|
bCaseSensitive);
|
|
|
|
if (val >= 0)
|
|
{
|
|
ConOutPrintf (_T("%c\n"), lpOptions[val]);
|
|
|
|
nErrorLevel = val + 1;
|
|
|
|
break;
|
|
}
|
|
|
|
Beep (440, 50);
|
|
}
|
|
|
|
freep (arg);
|
|
TRACE ("ErrorLevel: %d\n", nErrorLevel);
|
|
return 0;
|
|
}
|
|
|
|
clk = GetTickCount ();
|
|
amount = nTimeout*1000;
|
|
|
|
loop:
|
|
GCret = GetCharacterTimeout (&Ch, amount - (GetTickCount () - clk));
|
|
|
|
switch (GCret)
|
|
{
|
|
case GC_TIMEOUT:
|
|
TRACE ("GC_TIMEOUT\n");
|
|
TRACE ("elapsed %d msecs\n", GetTickCount () - clk);
|
|
break;
|
|
|
|
case GC_NOKEY:
|
|
TRACE ("GC_NOKEY\n");
|
|
TRACE ("elapsed %d msecs\n", GetTickCount () - clk);
|
|
goto loop;
|
|
|
|
case GC_KEYREAD:
|
|
TRACE ("GC_KEYREAD\n");
|
|
TRACE ("elapsed %d msecs\n", GetTickCount () - clk);
|
|
TRACE ("read %c", Ch);
|
|
if ((val=IsKeyInString(lpOptions,Ch,bCaseSensitive))==-1)
|
|
{
|
|
Beep (440, 50);
|
|
goto loop;
|
|
}
|
|
cDefault=Ch;
|
|
break;
|
|
}
|
|
|
|
TRACE ("exiting wait loop after %d msecs\n",
|
|
GetTickCount () - clk);
|
|
|
|
val = IsKeyInString (lpOptions, cDefault, bCaseSensitive);
|
|
ConOutPrintf (_T("%c\n"), lpOptions[val]);
|
|
|
|
nErrorLevel = val + 1;
|
|
|
|
freep (arg);
|
|
|
|
TRACE ("ErrorLevel: %d\n", nErrorLevel);
|
|
|
|
return 0;
|
|
}
|
|
#endif /* INCLUDE_CMD_CHOICE */
|
|
|
|
/* EOF */
|