mirror of
https://github.com/reactos/reactos.git
synced 2025-06-25 20:29:43 +00:00
Create a branch for header work.
svn path=/branches/header-work/; revision=45691
This commit is contained in:
parent
14fe274b1c
commit
9ea495ba33
19538 changed files with 0 additions and 1063950 deletions
540
base/shell/cmd/set.c
Normal file
540
base/shell/cmd/set.c
Normal file
|
@ -0,0 +1,540 @@
|
|||
/*
|
||||
* SET.C - set internal command.
|
||||
*
|
||||
*
|
||||
* History:
|
||||
*
|
||||
* 06/14/97 (Tim Norman)
|
||||
* changed static var in set() to a cmd_alloc'd space to pass to putenv.
|
||||
* need to find a better way to do this, since it seems it is wasting
|
||||
* memory when variables are redefined.
|
||||
*
|
||||
* 07/08/1998 (John P. Price)
|
||||
* removed call to show_environment in set command.
|
||||
* moved test for syntax before allocating memory in set command.
|
||||
* misc clean up and optimization.
|
||||
*
|
||||
* 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
|
||||
* added config.h include
|
||||
*
|
||||
* 28-Jul-1998 (John P Price <linux-guru@gcfl.net>)
|
||||
* added set_env function to set env. variable without needing set command
|
||||
*
|
||||
* 09-Dec-1998 (Eric Kohl)
|
||||
* Added help text ("/?").
|
||||
*
|
||||
* 24-Jan-1999 (Eric Kohl)
|
||||
* Fixed Win32 environment handling.
|
||||
* Unicode and redirection safe!
|
||||
*
|
||||
* 25-Feb-1999 (Eric Kohl)
|
||||
* Fixed little bug.
|
||||
*
|
||||
* 30-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
|
||||
* Remove all hardcode string to En.rc
|
||||
*/
|
||||
|
||||
#include <precomp.h>
|
||||
|
||||
#ifdef INCLUDE_CMD_SET
|
||||
|
||||
|
||||
/* initial size of environment variable buffer */
|
||||
#define ENV_BUFFER_SIZE 1024
|
||||
|
||||
static BOOL
|
||||
seta_eval ( LPCTSTR expr );
|
||||
|
||||
static LPCTSTR
|
||||
skip_ws ( LPCTSTR p )
|
||||
{
|
||||
while (*p && *p <= _T(' '))
|
||||
p++;
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Used to check for and handle:
|
||||
* SET "var=value", SET /P "var=prompt", and SET /P var="prompt" */
|
||||
static LPTSTR
|
||||
GetQuotedString(TCHAR *p)
|
||||
{
|
||||
TCHAR *end;
|
||||
if (*p == _T('"'))
|
||||
{
|
||||
p = (LPTSTR)skip_ws(p + 1);
|
||||
/* If a matching quote is found, truncate the string */
|
||||
end = _tcsrchr(p, _T('"'));
|
||||
if (end)
|
||||
*end = _T('\0');
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
INT cmd_set (LPTSTR param)
|
||||
{
|
||||
LPTSTR p;
|
||||
LPTSTR lpEnv;
|
||||
LPTSTR lpOutput;
|
||||
|
||||
if ( !_tcsncmp (param, _T("/?"), 2) )
|
||||
{
|
||||
ConOutResPaging(TRUE,STRING_SET_HELP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
param = (LPTSTR)skip_ws(param);
|
||||
|
||||
/* if no parameters, show the environment */
|
||||
if (param[0] == _T('\0'))
|
||||
{
|
||||
lpEnv = (LPTSTR)GetEnvironmentStrings ();
|
||||
if (lpEnv)
|
||||
{
|
||||
lpOutput = lpEnv;
|
||||
while (*lpOutput)
|
||||
{
|
||||
if (*lpOutput != _T('='))
|
||||
ConOutPuts(lpOutput);
|
||||
lpOutput += _tcslen(lpOutput) + 1;
|
||||
}
|
||||
FreeEnvironmentStrings (lpEnv);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the /A does *NOT* have to be followed by a whitespace */
|
||||
if ( !_tcsnicmp (param, _T("/A"), 2) )
|
||||
{
|
||||
BOOL Success;
|
||||
StripQuotes(param);
|
||||
Success = seta_eval ( skip_ws(param+2) );
|
||||
if(!Success)
|
||||
{
|
||||
/*might seem random but this is what windows xp does */
|
||||
nErrorLevel = 9165;
|
||||
}
|
||||
return !Success;
|
||||
}
|
||||
|
||||
if (!_tcsnicmp(param, _T("/P"), 2))
|
||||
{
|
||||
TCHAR value[1023];
|
||||
param = GetQuotedString((LPTSTR)skip_ws(param + 2));
|
||||
p = _tcschr(param, _T('='));
|
||||
if (!p)
|
||||
{
|
||||
ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT);
|
||||
nErrorLevel = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
*p++ = _T('\0');
|
||||
ConOutPrintf(_T("%s"), GetQuotedString(p));
|
||||
ConInString(value, 1023);
|
||||
|
||||
if (!*value || !SetEnvironmentVariable(param, value))
|
||||
{
|
||||
nErrorLevel = 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
param = GetQuotedString(param);
|
||||
|
||||
p = _tcschr (param, _T('='));
|
||||
if (p)
|
||||
{
|
||||
/* set or remove environment variable */
|
||||
if (p == param)
|
||||
{
|
||||
/* handle set =val case */
|
||||
ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT);
|
||||
nErrorLevel = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
*p++ = _T('\0');
|
||||
if (!SetEnvironmentVariable(param, *p ? p : NULL))
|
||||
{
|
||||
nErrorLevel = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* display all environment variable with the given prefix */
|
||||
BOOL bFound = FALSE;
|
||||
|
||||
while (_istspace(*param) || *param == _T(',') || *param == _T(';'))
|
||||
param++;
|
||||
|
||||
p = _tcsrchr(param, _T(' '));
|
||||
if (!p)
|
||||
p = param + _tcslen(param);
|
||||
*p = _T('\0');
|
||||
|
||||
lpEnv = GetEnvironmentStrings();
|
||||
if (lpEnv)
|
||||
{
|
||||
lpOutput = lpEnv;
|
||||
while (*lpOutput)
|
||||
{
|
||||
if (!_tcsnicmp(lpOutput, param, p - param))
|
||||
{
|
||||
ConOutPuts(lpOutput);
|
||||
bFound = TRUE;
|
||||
}
|
||||
lpOutput += _tcslen(lpOutput) + 1;
|
||||
}
|
||||
FreeEnvironmentStrings(lpEnv);
|
||||
}
|
||||
|
||||
if (!bFound)
|
||||
{
|
||||
ConErrResPrintf (STRING_PATH_ERROR, param);
|
||||
nErrorLevel = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static INT
|
||||
ident_len ( LPCTSTR p )
|
||||
{
|
||||
LPCTSTR p2 = p;
|
||||
if ( __iscsymf(*p) )
|
||||
{
|
||||
++p2;
|
||||
while ( __iscsym(*p2) )
|
||||
++p2;
|
||||
}
|
||||
return p2-p;
|
||||
}
|
||||
|
||||
#define PARSE_IDENT(ident,identlen,p) \
|
||||
identlen = ident_len(p); \
|
||||
ident = (LPTSTR)alloca ( ( identlen + 1 ) * sizeof(TCHAR) ); \
|
||||
memmove ( ident, p, identlen * sizeof(TCHAR) ); \
|
||||
ident[identlen] = 0; \
|
||||
p += identlen;
|
||||
|
||||
static BOOL
|
||||
seta_identval ( LPCTSTR ident, INT* result )
|
||||
{
|
||||
LPCTSTR identVal = GetEnvVarOrSpecial ( ident );
|
||||
if ( !identVal )
|
||||
{
|
||||
/* TODO FIXME - what to do upon failure? */
|
||||
*result = 0;
|
||||
return FALSE;
|
||||
}
|
||||
*result = _tcstol ( identVal, NULL, 0 );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
calc ( INT* lval, TCHAR op, INT rval )
|
||||
{
|
||||
switch ( op )
|
||||
{
|
||||
case '*':
|
||||
*lval *= rval;
|
||||
break;
|
||||
case '/':
|
||||
*lval /= rval;
|
||||
break;
|
||||
case '%':
|
||||
*lval %= rval;
|
||||
break;
|
||||
case '+':
|
||||
*lval += rval;
|
||||
break;
|
||||
case '-':
|
||||
*lval -= rval;
|
||||
break;
|
||||
case '&':
|
||||
*lval &= rval;
|
||||
break;
|
||||
case '^':
|
||||
*lval ^= rval;
|
||||
break;
|
||||
case '|':
|
||||
*lval |= rval;
|
||||
break;
|
||||
default:
|
||||
ConErrResPuts ( STRING_INVALID_OPERAND );
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
seta_stmt ( LPCTSTR* p_, INT* result );
|
||||
|
||||
static BOOL
|
||||
seta_unaryTerm ( LPCTSTR* p_, INT* result )
|
||||
{
|
||||
LPCTSTR p = *p_;
|
||||
if ( *p == _T('(') )
|
||||
{
|
||||
INT rval;
|
||||
p = skip_ws ( p + 1 );
|
||||
if ( !seta_stmt ( &p, &rval ) )
|
||||
return FALSE;
|
||||
if ( *p++ != _T(')') )
|
||||
{
|
||||
ConErrResPuts ( STRING_EXPECTED_CLOSE_PAREN );
|
||||
return FALSE;
|
||||
}
|
||||
*result = rval;
|
||||
}
|
||||
else if ( isdigit(*p) )
|
||||
{
|
||||
*result = _tcstol ( p, (LPTSTR *)&p, 0 );
|
||||
}
|
||||
else if ( __iscsymf(*p) )
|
||||
{
|
||||
LPTSTR ident;
|
||||
INT identlen;
|
||||
PARSE_IDENT(ident,identlen,p);
|
||||
if ( !seta_identval ( ident, result ) )
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ConErrResPuts ( STRING_EXPECTED_NUMBER_OR_VARIABLE );
|
||||
return FALSE;
|
||||
}
|
||||
*p_ = skip_ws ( p );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
seta_mulTerm ( LPCTSTR* p_, INT* result )
|
||||
{
|
||||
LPCTSTR p = *p_;
|
||||
TCHAR op = 0;
|
||||
INT rval;
|
||||
if ( _tcschr(_T("!~-"),*p) )
|
||||
{
|
||||
op = *p;
|
||||
p = skip_ws ( p + 1 );
|
||||
}
|
||||
if ( !seta_unaryTerm ( &p, &rval ) )
|
||||
return FALSE;
|
||||
switch ( op )
|
||||
{
|
||||
case '!':
|
||||
rval = !rval;
|
||||
break;
|
||||
case '~':
|
||||
rval = ~rval;
|
||||
break;
|
||||
case '-':
|
||||
rval = -rval;
|
||||
break;
|
||||
}
|
||||
|
||||
*result = rval;
|
||||
*p_ = p;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
seta_ltorTerm ( LPCTSTR* p_, INT* result, LPCTSTR ops, BOOL (*subTerm)(LPCTSTR*,INT*) )
|
||||
{
|
||||
LPCTSTR p = *p_;
|
||||
INT lval;
|
||||
if ( !subTerm ( &p, &lval ) )
|
||||
return FALSE;
|
||||
while ( *p && _tcschr(ops,*p) )
|
||||
{
|
||||
INT rval;
|
||||
TCHAR op = *p;
|
||||
|
||||
p = skip_ws ( p+1 );
|
||||
|
||||
if ( !subTerm ( &p, &rval ) )
|
||||
return FALSE;
|
||||
|
||||
if ( !calc ( &lval, op, rval ) )
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*result = lval;
|
||||
*p_ = p;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
seta_addTerm ( LPCTSTR* p_, INT* result )
|
||||
{
|
||||
return seta_ltorTerm ( p_, result, _T("*/%"), seta_mulTerm );
|
||||
}
|
||||
|
||||
static BOOL
|
||||
seta_logShiftTerm ( LPCTSTR* p_, INT* result )
|
||||
{
|
||||
return seta_ltorTerm ( p_, result, _T("+-"), seta_addTerm );
|
||||
}
|
||||
|
||||
static BOOL
|
||||
seta_bitAndTerm ( LPCTSTR* p_, INT* result )
|
||||
{
|
||||
LPCTSTR p = *p_;
|
||||
INT lval;
|
||||
if ( !seta_logShiftTerm ( &p, &lval ) )
|
||||
return FALSE;
|
||||
while ( *p && _tcschr(_T("<>"),*p) && p[0] == p[1] )
|
||||
{
|
||||
INT rval;
|
||||
TCHAR op = *p;
|
||||
|
||||
p = skip_ws ( p+2 );
|
||||
|
||||
if ( !seta_logShiftTerm ( &p, &rval ) )
|
||||
return FALSE;
|
||||
|
||||
switch ( op )
|
||||
{
|
||||
case '<':
|
||||
lval <<= rval;
|
||||
break;
|
||||
case '>':
|
||||
lval >>= rval;
|
||||
break;
|
||||
default:
|
||||
ConErrResPuts ( STRING_INVALID_OPERAND );
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
*result = lval;
|
||||
*p_ = p;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
seta_bitExclOrTerm ( LPCTSTR* p_, INT* result )
|
||||
{
|
||||
return seta_ltorTerm ( p_, result, _T("&"), seta_bitAndTerm );
|
||||
}
|
||||
|
||||
static BOOL
|
||||
seta_bitOrTerm ( LPCTSTR* p_, INT* result )
|
||||
{
|
||||
return seta_ltorTerm ( p_, result, _T("^"), seta_bitExclOrTerm );
|
||||
}
|
||||
|
||||
static BOOL
|
||||
seta_expr ( LPCTSTR* p_, INT* result )
|
||||
{
|
||||
return seta_ltorTerm ( p_, result, _T("|"), seta_bitOrTerm );
|
||||
}
|
||||
|
||||
static BOOL
|
||||
seta_assignment ( LPCTSTR* p_, INT* result )
|
||||
{
|
||||
LPCTSTR p = *p_;
|
||||
LPTSTR ident;
|
||||
TCHAR op = 0;
|
||||
INT identlen, exprval;
|
||||
|
||||
PARSE_IDENT(ident,identlen,p);
|
||||
if ( identlen )
|
||||
{
|
||||
p = skip_ws(p);
|
||||
if ( *p == _T('=') )
|
||||
op = *p, p = skip_ws(p+1);
|
||||
else if ( _tcschr ( _T("*/%+-&^|"), *p ) && p[1] == _T('=') )
|
||||
op = *p, p = skip_ws(p+2);
|
||||
else if ( _tcschr ( _T("<>"), *p ) && *p == p[1] && p[2] == _T('=') )
|
||||
op = *p, p = skip_ws(p+3);
|
||||
}
|
||||
|
||||
/* allow to chain multiple assignments, such as: a=b=1 */
|
||||
if ( ident && op )
|
||||
{
|
||||
INT identval;
|
||||
LPTSTR buf;
|
||||
|
||||
if ( !seta_assignment ( &p, &exprval ) )
|
||||
return FALSE;
|
||||
|
||||
if ( !seta_identval ( ident, &identval ) )
|
||||
identval = 0;
|
||||
switch ( op )
|
||||
{
|
||||
case '=':
|
||||
identval = exprval;
|
||||
break;
|
||||
case '<':
|
||||
identval <<= exprval;
|
||||
break;
|
||||
case '>':
|
||||
identval >>= exprval;
|
||||
break;
|
||||
default:
|
||||
if ( !calc ( &identval, op, exprval ) )
|
||||
return FALSE;
|
||||
}
|
||||
buf = (LPTSTR)alloca ( 32 * sizeof(TCHAR) );
|
||||
_sntprintf ( buf, 32, _T("%i"), identval );
|
||||
SetEnvironmentVariable ( ident, buf ); // TODO FIXME - check return value
|
||||
exprval = identval;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* restore p in case we found an ident but not an op */
|
||||
p = *p_;
|
||||
if ( !seta_expr ( &p, &exprval ) )
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*result = exprval;
|
||||
*p_ = p;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
seta_stmt ( LPCTSTR* p_, INT* result )
|
||||
{
|
||||
LPCTSTR p = *p_;
|
||||
INT rval;
|
||||
|
||||
if ( !seta_assignment ( &p, &rval ) )
|
||||
return FALSE;
|
||||
while ( *p == _T(',') )
|
||||
{
|
||||
p = skip_ws ( p+1 );
|
||||
|
||||
if ( !seta_assignment ( &p, &rval ) )
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*result = rval;
|
||||
*p_ = p;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
seta_eval ( LPCTSTR p )
|
||||
{
|
||||
INT rval;
|
||||
if ( !*p )
|
||||
{
|
||||
ConErrResPuts ( STRING_SYNTAX_COMMAND_INCORRECT );
|
||||
return FALSE;
|
||||
}
|
||||
if ( !seta_stmt ( &p, &rval ) )
|
||||
return FALSE;
|
||||
if ( !bc )
|
||||
ConOutPrintf ( _T("%i"), rval );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue