cmd's documentation says that env variables override the "built-ins" like %errorlevel% and such. also fixed a couple msvc6 warnings and added a little documentation to the set/a code Modified: trunk/reactos/subsys/system/cmd/choice.c Modified: trunk/reactos/subsys/system/cmd/cmd.c Modified: trunk/reactos/subsys/system/cmd/cmd.h Modified: trunk/reactos/subsys/system/cmd/misc.c Modified: trunk/reactos/subsys/system/cmd/precomp.h Modified: trunk/reactos/subsys/system/cmd/set.c _____
Modified: trunk/reactos/subsys/system/cmd/choice.c --- trunk/reactos/subsys/system/cmd/choice.c 2005-09-20 10:45:27 UTC (rev 17947) +++ trunk/reactos/subsys/system/cmd/choice.c 2005-09-20 16:38:02 UTC (rev 17948) @@ -254,7 +254,11 @@
{
val = IsKeyInString (lpOptions, +#ifdef _UNICODE
ir.Event.KeyEvent.uChar.UnicodeChar, +#else + ir.Event.KeyEvent.uChar.AsciiChar, +#endif bCaseSensitive); }
_____
Modified: trunk/reactos/subsys/system/cmd/cmd.c --- trunk/reactos/subsys/system/cmd/cmd.c 2005-09-20 10:45:27 UTC (rev 17947) +++ trunk/reactos/subsys/system/cmd/cmd.c 2005-09-20 16:38:02 UTC (rev 17948) @@ -142,6 +142,7 @@
*/
#include <precomp.h> +#include <malloc.h> #include "resource.h"
#ifndef NT_SUCCESS @@ -1061,7 +1062,189 @@ #endif /* FEATURE_REDIRECTION */ }
+BOOL +GrowIfNecessary ( UINT needed, LPTSTR* ret, UINT* retlen ) +{ + if ( *ret && needed < *retlen ) + return TRUE; + *retlen = needed; + if ( *ret ) + free ( *ret ); + *ret = (LPTSTR)malloc ( *retlen * sizeof(TCHAR) ); + if ( !*ret ) + SetLastError ( ERROR_OUTOFMEMORY ); + return *ret != NULL; +}
+LPCTSTR +GetParsedEnvVar ( LPCTSTR envName, UINT* envNameLen ) +{ + static LPTSTR ret = NULL; + static UINT retlen = 0; + LPTSTR p, tmp; + UINT size; + + if ( envNameLen ) + *envNameLen = 0; + SetLastError(0); + if ( *envName++ != '%' ) + return NULL; + switch ( *envName ) + { + case _T('0'): + case _T('1'): + case _T('2'): + case _T('3'): + case _T('4'): + case _T('5'): + case _T('6'): + case _T('7'): + case _T('8'): + case _T('9'): + if ((tmp = FindArg (*envName - _T('0')))) + { + if ( !GrowIfNecessary ( _tcslen(tmp), &ret, &retlen ) ) + return NULL; + _tcscpy ( ret, tmp ); + if ( envNameLen ) + *envNameLen = 2; + return ret; + } + if ( !GrowIfNecessary ( 3, &ret, &retlen ) ) + return NULL; + ret[0] = _T('%'); + ret[1] = *envName; + ret[2] = 0; + if ( envNameLen ) + *envNameLen = 2; + return ret; + + case _T('%'): + if ( !GrowIfNecessary ( 2, &ret, &retlen ) ) + return NULL; + ret[0] = _T('%'); + ret[1] = 0; + if ( envNameLen ) + *envNameLen = 2; + return ret; + + case _T('?'): + /* TODO FIXME 10 is only max size for 32-bit */ + if ( !GrowIfNecessary ( 11, &ret, &retlen ) ) + return NULL; + _sntprintf ( ret, retlen, _T("%u"), nErrorLevel); + ret[retlen-1] = 0; + if ( envNameLen ) + *envNameLen = 2; + return ret; + } + p = _tcschr ( envName, _T('%') ); + if ( !p ) + { + SetLastError ( ERROR_INVALID_PARAMETER ); + return NULL; + } + size = p-envName; + if ( envNameLen ) + *envNameLen = size + 2; + p = alloca ( (size+1) * sizeof(TCHAR) ); + memmove ( p, envName, size * sizeof(TCHAR) ); + p[size] = 0; + envName = p; + size = GetEnvironmentVariable ( envName, ret, retlen ); + if ( size > retlen ) + { + if ( !GrowIfNecessary ( size, &ret, &retlen ) ) + return NULL; + size = GetEnvironmentVariable ( envName, ret, retlen ); + } + if ( size ) + return ret; + + /* env var doesn't exist, look for a "special" one */ + /* %CD% */ + if (_tcsicmp(envName,_T("cd")) ==0) + { + size = GetCurrentDirectory ( retlen, ret ); + if ( size > retlen ) + { + if ( !GrowIfNecessary ( size, &ret, &retlen ) ) + return NULL; + size = GetCurrentDirectory ( retlen, ret ); + } + if ( !size ) + return NULL; + return ret; + } + /* %TIME% */ + else if (_tcsicmp(envName,_T("time")) ==0) + { + SYSTEMTIME t; + if ( !GrowIfNecessary ( MAX_PATH, &ret, &retlen ) ) + return NULL; + GetSystemTime(&t); + _sntprintf ( ret, retlen, _T("%02d%c%02d%c%02d%c%02d"), + t.wHour, cTimeSeparator, t.wMinute, cTimeSeparator, + t.wSecond, cDecimalSeparator, t.wMilliseconds ); + return ret; + } + /* %DATE% */ + else if (_tcsicmp(envName,_T("date")) ==0) + { + if ( !GrowIfNecessary ( MAX_PATH, &ret, &retlen ) ) + return NULL; + size = GetDateFormat(LOCALE_USER_DEFAULT, 0, NULL, _T("ddd"), ret, retlen ); + /* TODO FIXME - test whether GetDateFormat() can return a value indicating the buffer wasn't big enough */ + if ( !size ) + return NULL; + tmp = ret + _tcslen(ret); + *tmp++ = _T(' '); + size = GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, NULL, NULL, tmp, retlen-(tmp-ret)); + /* TODO FIXME - test whether GetDateFormat() can return a value indicating the buffer wasn't big enough */ + if ( !size ) + return NULL; + return ret; + } + + /* %RANDOM% */ + else if (_tcsicmp(envName,_T("random")) ==0) + { + if ( !GrowIfNecessary ( MAX_PATH, &ret, &retlen ) ) + return NULL; + /* Get random number */ + _itot(rand(),ret,10); + return ret; + } + + /* %CMDCMDLINE% */ + else if (_tcsicmp(envName,_T("cmdcmdline")) ==0) + { + return GetCommandLine(); + } + + /* %CMDEXTVERSION% */ + else if (_tcsicmp(envName,_T("cmdextversion")) ==0) + { + if ( !GrowIfNecessary ( MAX_PATH, &ret, &retlen ) ) + return NULL; + /* Set version number to 2 */ + _itot(2,ret,10); + return ret; + } + + /* %ERRORLEVEL% */ + else if (_tcsicmp(envName,_T("errorlevel")) ==0) + { + if ( !GrowIfNecessary ( MAX_PATH, &ret, &retlen ) ) + return NULL; + _itot(nErrorLevel,ret,10); + return ret; + } + + return _T(""); /* not found - return empty string */ +} + + /* * do the prompt/input/process loop * @@ -1072,7 +1255,6 @@ { TCHAR commandline[CMDLINE_LENGTH]; TCHAR readline[CMDLINE_LENGTH]; - LPTSTR tp = NULL; LPTSTR ip; LPTSTR cp; LPCTSTR tmp; @@ -1100,165 +1282,14 @@ bSubstitute = TRUE; while (*ip) { - if (bSubstitute && *ip == _T('%')) + if ( bSubstitute && *ip == _T('%') ) { - switch (*++ip) - { - case _T('%'): - *cp++ = *ip++; - break; - - case _T('0'): - case _T('1'): - case _T('2'): - case _T('3'): - case _T('4'): - case _T('5'): - case _T('6'): - case _T('7'): - case _T('8'): - case _T('9'): - if ((tp = FindArg (*ip - _T('0')))) - { - cp = _stpcpy (cp, tp); - ip++; - } - else - *cp++ = _T('%'); - break; - - case _T('?'): - cp += _stprintf (cp, _T("%u"), nErrorLevel); - ip++; - break; - - default: - tp = _tcschr(ip, _T('%')); - if ((tp != NULL) && - (tp <= _tcschr(ip, _T(' ')) - 1)) - { - INT size = 512; - TCHAR *evar; - *tp = _T('\0'); - - /* FIXME: Correct error handling when it can not alloc memmory */ - - /* %CD% */ - if (_tcsicmp(ip,_T("cd")) ==0) - { - TCHAR szPath[MAX_PATH]; - GetCurrentDirectory (MAX_PATH, szPath); - cp = _stpcpy (cp, szPath); - } - /* %TIME% */ - else if (_tcsicmp(ip,_T("time")) ==0) - { - TCHAR szTime[40]; - SYSTEMTIME t; - GetSystemTime(&t); - - _sntprintf(szTime ,40,_T("%02d%c%02d%c%02d%c%02d"), t.wHour, cTimeSeparator,t.wMinute , cTimeSeparator,t.wSecond , cDecimalSeparator, t.wMilliseconds ); - cp = _stpcpy (cp, szTime); - } - - /* %DATE% */ - else if (_tcsicmp(ip,_T("date")) ==0) - { - TCHAR szDate[40]; - - GetDateFormat(LOCALE_USER_DEFAULT, 0, NULL, _T("ddd"), szDate, sizeof (szDate)); - cp = _stpcpy (cp, szDate); - cp = _stpcpy (cp, _T(" ")); - GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, NULL, NULL, szDate, sizeof (szDate)); - cp = _stpcpy (cp, szDate); - } - - /* %RANDOM% */ - else if (_tcsicmp(ip,_T("random")) ==0) - { - TCHAR szRand[40]; - /* Get random number */ - _itot(rand(),szRand,10); - cp = _stpcpy (cp, szRand); - } - - /* %CMDCMDLINE% */ - else if (_tcsicmp(ip,_T("cmdcmdline")) ==0) - { - TCHAR *pargv; - /* Get random number */ - pargv = GetCommandLine(); - cp = _stpcpy (cp, pargv); - } - - /* %CMDEXTVERSION% */ - else if (_tcsicmp(ip,_T("cmdextversion")) ==0) - { - TCHAR szVER[40]; - /* Set version number to 2 */ - _itot(2,szVER,10); - cp = _stpcpy (cp, szVER); - } - - /* %ERRORLEVEL% */ - else if (_tcsicmp(ip,_T("errorlevel")) ==0) - { - evar = malloc ( size * sizeof(TCHAR)); - if (evar==NULL) - return 1; - - memset(evar,0,512 * sizeof(TCHAR)); - _itot(nErrorLevel,evar,10); - cp = _stpcpy (cp, evar); - - free(evar); - } - else - { - evar = malloc ( 512 * sizeof(TCHAR)); - if (evar==NULL) - return 1; - SetLastError(0); - size = GetEnvironmentVariable (ip, evar, 512); - if(GetLastError() == ERROR_ENVVAR_NOT_FOUND) - { - /* if no env var is found you must - continue with what was input*/ - cp = _stpcpy (cp, _T("%")); - cp = _stpcpy (cp, ip); - cp = _stpcpy (cp, _T("%")); - } - else - { - if (size > 512) - { - evar = realloc(evar,size * sizeof(TCHAR) ); - if (evar==NULL) - { - return 1; - } - size = GetEnvironmentVariable (ip, evar, size); - } - - if (size) - { - cp = _stpcpy (cp, evar); - } - } - - free(evar); - } - - ip = tp + 1; - - } - else - { - *cp++ = _T('%'); - } - - break; - } + UINT envNameLen; + LPCTSTR envVal = GetParsedEnvVar ( ip, &envNameLen ); + if ( !envVal ) + return 1; + ip += envNameLen; + cp = _stpcpy ( cp, envVal ); continue; }
_____
Modified: trunk/reactos/subsys/system/cmd/cmd.h --- trunk/reactos/subsys/system/cmd/cmd.h 2005-09-20 10:45:27 UTC (rev 17947) +++ trunk/reactos/subsys/system/cmd/cmd.h 2005-09-20 16:38:02 UTC (rev 17948) @@ -299,7 +299,7 @@
BOOL CheckCtrlBreak (INT); LPTSTR *split (LPTSTR, LPINT, BOOL); VOID freep (LPTSTR *); -LPTSTR _stpcpy (LPTSTR, LPTSTR); +LPTSTR _stpcpy (LPTSTR, LPCTSTR); BOOL IsValidPathName (LPCTSTR); BOOL IsExistingFile (LPCTSTR); BOOL IsExistingDirectory (LPCTSTR); _____
Modified: trunk/reactos/subsys/system/cmd/misc.c --- trunk/reactos/subsys/system/cmd/misc.c 2005-09-20 10:45:27 UTC (rev 17947) +++ trunk/reactos/subsys/system/cmd/misc.c 2005-09-20 16:38:02 UTC (rev 17948) @@ -322,7 +322,7 @@
}
-LPTSTR _stpcpy (LPTSTR dest, LPTSTR src) +LPTSTR _stpcpy (LPTSTR dest, LPCTSTR src) { _tcscpy (dest, src); return (dest + _tcslen (src)); _____
Modified: trunk/reactos/subsys/system/cmd/precomp.h --- trunk/reactos/subsys/system/cmd/precomp.h 2005-09-20 10:45:27 UTC (rev 17947) +++ trunk/reactos/subsys/system/cmd/precomp.h 2005-09-20 16:38:02 UTC (rev 17948) @@ -1,3 +1,9 @@
+#ifdef _MSC_VER +#pragma warning ( disable : 4103 ) /* use #pragma pack to change alignment */ +#endif//_MSC_VER + +#include <stdlib.h> + #include <windows.h> #include <winnt.h> #include <shellapi.h> @@ -8,7 +14,6 @@ #include <ctype.h> #include <string.h> #include <stdio.h> -#include <stdlib.h> #include <stdarg.h> #include <math.h> #include <time.h> _____
Modified: trunk/reactos/subsys/system/cmd/set.c --- trunk/reactos/subsys/system/cmd/set.c 2005-09-20 10:45:27 UTC (rev 17947) +++ trunk/reactos/subsys/system/cmd/set.c 2005-09-20 16:38:02 UTC (rev 17948) @@ -103,9 +103,10 @@
return 0; }
+ /* the /A does *NOT* have to be followed by a whitespace */ if ( !_tcsnicmp (param, _T("/A"), 2) ) { - // TODO FIXME - what are we supposed to return? + /* TODO FIXME - what are we supposed to return? */ return seta_eval ( skip_ws(param+2) ); }