+++ /dev/null
-/*
- * SET.C - set internal command.
- *
- *
- * History:
- *
- * 06/14/97 (Tim Norman)
- * changed static var in set() to a malloc'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 <ekohl@abo.rhein-zeitung.de>)
- * Added help text ("/?").
- *
- * 24-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
- * Fixed Win32 environment handling.
- * Unicode and redirection safe!
- *
- * 25-Feb-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
- * Fixed little bug.
- *
- * 30-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
- * Remove all hardcode string to En.rc
- */
-
-#include <precomp.h>
-#include <malloc.h>
-#include <stdio.h>
-#include "resource.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 )
-{
- return p + _tcsspn ( p, _T(" \t") );
-}
-
-INT cmd_set (LPTSTR cmd, LPTSTR param)
-{
- TCHAR szMsg[RC_STRING_MAX_SIZE];
- INT i;
- LPTSTR p;
-
- if ( !_tcsncmp (param, _T("/?"), 2) )
- {
- ConOutResPaging(TRUE,STRING_SET_HELP);
- return 0;
- }
-
- /* remove escapes */
- if ( param[0] ) for ( i = 0; param[i+1]; i++ )
- {
- if ( param[i] == _T('^') )
- {
- memmove ( ¶m[i], ¶m[i+1], _tcslen(¶m[i]) * sizeof(TCHAR) );
- }
- }
-
- /* if no parameters, show the environment */
- if (param[0] == _T('\0'))
- {
- LPTSTR lpEnv;
- LPTSTR lpOutput;
- INT len;
-
- lpEnv = (LPTSTR)GetEnvironmentStrings ();
- if (lpEnv)
- {
- lpOutput = lpEnv;
- while (*lpOutput)
- {
- len = _tcslen(lpOutput);
- if (len)
- {
- if (*lpOutput != _T('='))
- ConOutPuts (lpOutput);
- lpOutput += (len + 1);
- }
- }
- FreeEnvironmentStrings (lpEnv);
- }
-
- return 0;
- }
-
- /* the /A does *NOT* have to be followed by a whitespace */
- if ( !_tcsnicmp (param, _T("/A"), 2) )
- {
- BOOL Success = seta_eval ( skip_ws(param+2) );
- if(!Success)
- {
- /*might seem random but this is what windows xp does */
- nErrorLevel = 9165;
- }
- /* TODO FIXME - what are we supposed to return? */
- return Success;
- }
-
- p = _tcschr (param, _T('='));
- if (p)
- {
- /* set or remove environment variable */
- *p = _T('\0');
- p++;
- if (*p == _T('\0'))
- {
- p = NULL;
- }
- SetEnvironmentVariable (param, p);
- }
- else
- {
- /* display environment variable */
- LPTSTR pszBuffer;
- DWORD dwBuffer;
-
- pszBuffer = (LPTSTR)malloc (ENV_BUFFER_SIZE * sizeof(TCHAR));
- dwBuffer = GetEnvironmentVariable (param, pszBuffer, ENV_BUFFER_SIZE);
- if (dwBuffer == 0)
- {
- LoadString(CMD_ModuleHandle, STRING_PATH_ERROR, szMsg, RC_STRING_MAX_SIZE);
- ConErrPrintf (szMsg, param);
- return 0;
- }
- else if (dwBuffer > ENV_BUFFER_SIZE)
- {
- pszBuffer = (LPTSTR)realloc (pszBuffer, dwBuffer * sizeof (TCHAR));
- GetEnvironmentVariable (param, pszBuffer, dwBuffer);
- }
- ConOutPrintf (_T("%s\n"), pszBuffer);
-
- free (pszBuffer);
-
- return 0;
- }
-
- 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 = _ttoi ( identVal );
- 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;
- p = skip_ws ( p + 1 );
- }
- else if ( isdigit(*p) )
- {
- *result = _ttoi ( p );
- p = skip_ws ( p + _tcsspn ( p, _T("1234567890") ) );
- }
- 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_ = 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 )
- {
- 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;
- ConOutPrintf ( _T("%i"), rval );
- return TRUE;
-}
-
-#endif