[CMD] Some code style and formatting fixes

This commit is contained in:
Hermès Bélusca-Maïto 2020-07-26 20:32:30 +02:00
parent 82bcb3f9f0
commit ca4523658c
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
3 changed files with 204 additions and 165 deletions

View file

@ -46,9 +46,9 @@ ErrorMessage(
va_end(arg_ptr); va_end(arg_ptr);
} }
if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, dwErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), NULL, dwErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&szError, 0, NULL)) (LPTSTR)&szError, 0, NULL))
{ {
ConErrPrintf(_T("%s %s\n"), szError, szMessage); ConErrPrintf(_T("%s %s\n"), szError, szMessage);
if (szError) if (szError)

View file

@ -141,41 +141,44 @@
#ifdef INCLUDE_CMD_CHDIR #ifdef INCLUDE_CMD_CHDIR
/* helper functions for getting current path from drive /*
without changing drive. Return code 0 = ok, 1 = fail. * Helper function for getting the current path from drive
INT GetRootPath("C:",outbuffer,chater size of outbuffer); * without changing the drive. Return code: 0 = ok, 1 = fail.
the first param can have any size, if the the two frist * 'InPath' can have any size; if the two first letters are
letter are not a drive with : it will get Currentpath on * not a drive with ':' it will get the current path on
current drive exactly as GetCurrentDirectory does. * the current drive exactly as GetCurrentDirectory() does.
*/ */
INT
INT GetRootPath(TCHAR *InPath,TCHAR *OutPath,INT size) GetRootPath(
IN LPTSTR InPath,
OUT LPTSTR OutPath,
IN INT size)
{ {
if (InPath[0] && InPath[1] == _T(':')) if (InPath[0] && InPath[1] == _T(':'))
{ {
INT t=0; INT t = 0;
if ((InPath[0] >= _T('0')) && (InPath[0] <= _T('9'))) if ((InPath[0] >= _T('0')) && (InPath[0] <= _T('9')))
{ {
t = (InPath[0] - _T('0')) +28; t = (InPath[0] - _T('0')) + 28;
} }
if ((InPath[0] >= _T('a')) && (InPath[0] <= _T('z'))) if ((InPath[0] >= _T('a')) && (InPath[0] <= _T('z')))
{ {
t = (InPath[0] - _T('a')) +1; t = (InPath[0] - _T('a')) + 1;
InPath[0] = t + _T('A') - 1; InPath[0] = t + _T('A') - 1;
} }
if ((InPath[0] >= _T('A')) && (InPath[0] <= _T('Z'))) if ((InPath[0] >= _T('A')) && (InPath[0] <= _T('Z')))
{ {
t = (InPath[0] - _T('A')) +1; t = (InPath[0] - _T('A')) + 1;
} }
return _tgetdcwd(t,OutPath,size) == NULL; return (_tgetdcwd(t, OutPath, size) == NULL);
} }
/* Get current directory */ /* Get current directory */
return !GetCurrentDirectory(size,OutPath); return !GetCurrentDirectory(size, OutPath);
} }
@ -187,19 +190,19 @@ BOOL SetRootPath(TCHAR *oldpath, TCHAR *InPath)
StripQuotes(InPath); StripQuotes(InPath);
/* Retrieve the full path name from the (possibly relative) InPath */ /* Retrieve the full path name from the (possibly relative) InPath */
if (GetFullPathName(InPath, MAX_PATH, OutPathTemp, NULL) == 0) if (GetFullPathName(InPath, ARRAYSIZE(OutPathTemp), OutPathTemp, NULL) == 0)
goto Fail; goto Fail;
/* Convert the full path to its correct case. /* Convert the full path to its correct case.
* Example: c:\windows\SYSTEM32 => C:\WINDOWS\System32 */ * Example: c:\windows\SYSTEM32 => C:\WINDOWS\System32 */
GetPathCase(OutPathTemp, OutPath); GetPathCase(OutPathTemp, OutPath);
/* Use _tchdir, since unlike SetCurrentDirectory it updates /* Use _tchdir(), since unlike SetCurrentDirectory() it updates
* the current-directory-on-drive environment variables. */ * the current-directory-on-drive environment variables. */
if (_tchdir(OutPath) != 0) if (_tchdir(OutPath) != 0)
goto Fail; goto Fail;
/* Keep original drive in ordinary CD/CHDIR (without /D switch). */ /* Keep the original drive in ordinary CD/CHDIR (without /D switch) */
if (oldpath != NULL && _tcsncicmp(OutPath, oldpath, 2) != 0) if (oldpath != NULL && _tcsncicmp(OutPath, oldpath, 2) != 0)
SetCurrentDirectory(oldpath); SetCurrentDirectory(oldpath);
@ -214,9 +217,8 @@ Fail:
/* /*
* CD / CHDIR * CD / CHDIR
*
*/ */
INT cmd_chdir (LPTSTR param) INT cmd_chdir(LPTSTR param)
{ {
BOOL bChangeDrive = FALSE; BOOL bChangeDrive = FALSE;
LPTSTR tmp; LPTSTR tmp;
@ -224,10 +226,10 @@ INT cmd_chdir (LPTSTR param)
/* Filter out special cases first */ /* Filter out special cases first */
/* Print Help */ /* Print help */
if (!_tcsncmp(param, _T("/?"), 2)) if (!_tcsncmp(param, _T("/?"), 2))
{ {
ConOutResPaging(TRUE,STRING_CD_HELP); ConOutResPaging(TRUE, STRING_CD_HELP);
return 0; return 0;
} }
@ -235,16 +237,16 @@ INT cmd_chdir (LPTSTR param)
StripQuotes(param); StripQuotes(param);
tmp = param + _tcslen(param) - 1; tmp = param + _tcslen(param) - 1;
while (tmp > param && _istspace(*tmp)) while (tmp > param && _istspace(*tmp))
tmp--; --tmp;
*(tmp + 1) = _T('\0'); *(tmp + 1) = _T('\0');
/* Set Error Level to Success */ /* Reset the error level */
nErrorLevel = 0; nErrorLevel = 0;
/* Print Current Directory on a disk */ /* Print the current directory on a disk */
if (_tcslen(param) == 2 && param[1] == _T(':')) if (_tcslen(param) == 2 && param[1] == _T(':'))
{ {
if (GetRootPath(param, szCurrent, MAX_PATH)) if (GetRootPath(param, szCurrent, ARRAYSIZE(szCurrent)))
{ {
error_invalid_drive(); error_invalid_drive();
return 1; return 1;
@ -253,21 +255,21 @@ INT cmd_chdir (LPTSTR param)
return 0; return 0;
} }
/* Get Current Directory */ /* Get the current directory */
GetCurrentDirectory(MAX_PATH, szCurrent); GetCurrentDirectory(ARRAYSIZE(szCurrent), szCurrent);
if (param[0] == _T('\0')) if (param[0] == _T('\0'))
{ {
ConOutPrintf(_T("%s\n"), szCurrent); ConOutPrintf(_T("%s\n"), szCurrent);
return 0; return 0;
} }
/* Input String Contains /D Switch */ /* If the input string is prefixed with the /D switch, change the drive */
if (!_tcsncicmp(param, _T("/D"), 2)) if (!_tcsncicmp(param, _T("/D"), 2))
{ {
bChangeDrive = TRUE; bChangeDrive = TRUE;
param += 2; param += 2;
while (_istspace(*param)) while (_istspace(*param))
param++; ++param;
} }
if (!SetRootPath(bChangeDrive ? NULL : szCurrent, param)) if (!SetRootPath(bChangeDrive ? NULL : szCurrent, param))
@ -362,7 +364,6 @@ INT cmd_mkdir (LPTSTR param)
} }
#endif #endif
#ifdef INCLUDE_CMD_RMDIR #ifdef INCLUDE_CMD_RMDIR
/* /*
* RD / RMDIR * RD / RMDIR
@ -373,8 +374,10 @@ BOOL DeleteFolder(LPTSTR FileName)
TCHAR TempFileName[MAX_PATH]; TCHAR TempFileName[MAX_PATH];
HANDLE hFile; HANDLE hFile;
WIN32_FIND_DATA f; WIN32_FIND_DATA f;
_tcscpy(Base,FileName);
_tcscat(Base,_T("\\*")); _tcscpy(Base, FileName);
_tcscat(Base, _T("\\*"));
hFile = FindFirstFile(Base, &f); hFile = FindFirstFile(Base, &f);
Base[_tcslen(Base) - 1] = _T('\0'); Base[_tcslen(Base) - 1] = _T('\0');
if (hFile != INVALID_HANDLE_VALUE) if (hFile != INVALID_HANDLE_VALUE)
@ -383,68 +386,70 @@ BOOL DeleteFolder(LPTSTR FileName)
{ {
if (!_tcscmp(f.cFileName, _T(".")) || if (!_tcscmp(f.cFileName, _T(".")) ||
!_tcscmp(f.cFileName, _T(".."))) !_tcscmp(f.cFileName, _T("..")))
{
continue; continue;
_tcscpy(TempFileName,Base); }
_tcscat(TempFileName,f.cFileName);
_tcscpy(TempFileName, Base);
_tcscat(TempFileName, f.cFileName);
if (f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) if (f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
DeleteFolder(TempFileName); DeleteFolder(TempFileName);
}
else else
{ {
SetFileAttributes(TempFileName,FILE_ATTRIBUTE_NORMAL); SetFileAttributes(TempFileName, FILE_ATTRIBUTE_NORMAL);
if (!DeleteFile(TempFileName)) if (!DeleteFile(TempFileName))
{ {
FindClose (hFile); FindClose(hFile);
return 0; return 0;
} }
} }
}while (FindNextFile (hFile, &f)); } while (FindNextFile(hFile, &f));
FindClose (hFile); FindClose(hFile);
} }
return RemoveDirectory(FileName); return RemoveDirectory(FileName);
} }
INT cmd_rmdir (LPTSTR param) INT cmd_rmdir(LPTSTR param)
{ {
TCHAR ch; INT nError = 0;
INT res;
LPTSTR *arg;
INT args; INT args;
INT dirCount; INT dirCount;
LPTSTR *arg;
INT i; INT i;
BOOL RD_SUB = FALSE; TCHAR ch;
BOOL RD_QUIET = FALSE; BOOL bRecurseDir = FALSE;
INT res; BOOL bQuiet = FALSE;
INT nError = 0;
TCHAR szFullPath[MAX_PATH]; TCHAR szFullPath[MAX_PATH];
if (!_tcsncmp (param, _T("/?"), 2)) if (!_tcsncmp(param, _T("/?"), 2))
{ {
ConOutResPaging(TRUE,STRING_RMDIR_HELP); ConOutResPaging(TRUE,STRING_RMDIR_HELP);
return 0; return 0;
} }
arg = split (param, &args, FALSE, FALSE); arg = split(param, &args, FALSE, FALSE);
dirCount = 0; dirCount = 0;
/* check for options anywhere in command line */ /* Check for options anywhere in command line */
for (i = 0; i < args; i++) for (i = 0; i < args; i++)
{ {
if (*arg[i] == _T('/')) if (*arg[i] == _T('/'))
{ {
/*found a command, but check to make sure it has something after it*/ /* Found an option, but check to make sure it has something after it */
if (_tcslen (arg[i]) == 2) if (_tcslen(arg[i]) == 2)
{ {
ch = _totupper (arg[i][1]); ch = _totupper(arg[i][1]);
if (ch == _T('S')) if (ch == _T('S'))
{ bRecurseDir = TRUE;
RD_SUB = TRUE;
}
else if (ch == _T('Q')) else if (ch == _T('Q'))
{ bQuiet = TRUE;
RD_QUIET = TRUE;
}
} }
} }
else else
@ -466,25 +471,26 @@ INT cmd_rmdir (LPTSTR param)
if (*arg[i] == _T('/')) if (*arg[i] == _T('/'))
continue; continue;
if (RD_SUB) if (bRecurseDir)
{ {
/* ask if they want to delete everything in the folder */ /* Ask the user whether to delete everything in the folder */
if (!RD_QUIET) if (!bQuiet)
{ {
res = FilePromptYNA (STRING_DEL_HELP2); res = FilePromptYNA(STRING_DEL_HELP2);
if (res == PROMPT_NO || res == PROMPT_BREAK) if (res == PROMPT_NO || res == PROMPT_BREAK)
{ {
nError = 1; nError = 1;
continue; continue;
} }
if (res == PROMPT_ALL) if (res == PROMPT_ALL)
RD_QUIET = TRUE; bQuiet = TRUE;
} }
/* get the folder name */
GetFullPathName(arg[i],MAX_PATH,szFullPath,NULL);
/* remove trailing \ if any, but ONLY if dir is not the root dir */ /* Get the folder name */
if (_tcslen (szFullPath) >= 2 && szFullPath[_tcslen (szFullPath) - 1] == _T('\\')) GetFullPathName(arg[i], ARRAYSIZE(szFullPath), szFullPath, NULL);
/* Remove trailing \ if any, but ONLY if dir is not the root dir */
if (_tcslen(szFullPath) >= 2 && szFullPath[_tcslen(szFullPath) - 1] == _T('\\'))
szFullPath[_tcslen(szFullPath) - 1] = _T('\0'); szFullPath[_tcslen(szFullPath) - 1] = _T('\0');
res = DeleteFolder(szFullPath); res = DeleteFolder(szFullPath);
@ -502,7 +508,7 @@ INT cmd_rmdir (LPTSTR param)
} }
} }
freep (arg); freep(arg);
return nError; return nError;
} }
#endif #endif
@ -601,7 +607,7 @@ INT CommandRem (LPTSTR param)
#endif /* INCLUDE_CMD_REM */ #endif /* INCLUDE_CMD_REM */
INT CommandShowCommands (LPTSTR param) INT CommandShowCommands(LPTSTR param)
{ {
PrintCommandList(); PrintCommandList();
return 0; return 0;

View file

@ -38,18 +38,17 @@
#ifdef INCLUDE_CMD_SET #ifdef INCLUDE_CMD_SET
/* Initial size of environment variable buffer */
/* initial size of environment variable buffer */
#define ENV_BUFFER_SIZE 1024 #define ENV_BUFFER_SIZE 1024
static BOOL static BOOL
seta_eval ( LPCTSTR expr ); seta_eval(LPCTSTR expr);
static LPCTSTR static LPCTSTR
skip_ws ( LPCTSTR p ) skip_ws(LPCTSTR p)
{ {
while (*p && *p <= _T(' ')) while (*p && *p <= _T(' '))
p++; ++p;
return p; return p;
} }
@ -70,13 +69,13 @@ GetQuotedString(TCHAR *p)
return p; return p;
} }
INT cmd_set (LPTSTR param) INT cmd_set(LPTSTR param)
{ {
LPTSTR p; LPTSTR p;
LPTSTR lpEnv; LPTSTR lpEnv;
LPTSTR lpOutput; LPTSTR lpOutput;
if ( !_tcsncmp (param, _T("/?"), 2) ) if (!_tcsncmp(param, _T("/?"), 2))
{ {
ConOutResPaging(TRUE,STRING_SET_HELP); ConOutResPaging(TRUE,STRING_SET_HELP);
return 0; return 0;
@ -84,10 +83,10 @@ INT cmd_set (LPTSTR param)
param = (LPTSTR)skip_ws(param); param = (LPTSTR)skip_ws(param);
/* if no parameters, show the environment */ /* If no parameters, show the environment */
if (param[0] == _T('\0')) if (param[0] == _T('\0'))
{ {
lpEnv = (LPTSTR)GetEnvironmentStrings (); lpEnv = (LPTSTR)GetEnvironmentStrings();
if (lpEnv) if (lpEnv)
{ {
lpOutput = lpEnv; lpOutput = lpEnv;
@ -98,21 +97,21 @@ INT cmd_set (LPTSTR param)
lpOutput += _tcslen(lpOutput) + 1; lpOutput += _tcslen(lpOutput) + 1;
ConOutChar(_T('\n')); ConOutChar(_T('\n'));
} }
FreeEnvironmentStrings (lpEnv); FreeEnvironmentStrings(lpEnv);
} }
return 0; return 0;
} }
/* the /A does *NOT* have to be followed by a whitespace */ /* The /A does *NOT* have to be followed by a whitespace */
if ( !_tcsnicmp (param, _T("/A"), 2) ) if (!_tcsnicmp(param, _T("/A"), 2))
{ {
BOOL Success; BOOL Success;
StripQuotes(param); StripQuotes(param);
Success = seta_eval ( skip_ws(param+2) ); Success = seta_eval(skip_ws(param + 2));
if (!Success) if (!Success)
{ {
/* might seem random but this is what windows xp does */ /* Might seem random but this is what windows xp does -- This is a message ID */
nErrorLevel = 9165; nErrorLevel = 9165;
} }
return !Success; return !Success;
@ -132,7 +131,7 @@ INT cmd_set (LPTSTR param)
*p++ = _T('\0'); *p++ = _T('\0');
ConOutPrintf(_T("%s"), GetQuotedString(p)); ConOutPrintf(_T("%s"), GetQuotedString(p));
ConInString(value, 1023); ConInString(value, ARRAYSIZE(value));
if (!*value || !SetEnvironmentVariable(param, value)) if (!*value || !SetEnvironmentVariable(param, value))
{ {
@ -144,13 +143,13 @@ INT cmd_set (LPTSTR param)
param = GetQuotedString(param); param = GetQuotedString(param);
p = _tcschr (param, _T('=')); p = _tcschr(param, _T('='));
if (p) if (p)
{ {
/* set or remove environment variable */ /* Set or remove the environment variable */
if (p == param) if (p == param)
{ {
/* handle set =val case */ /* Handle set =val case */
ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT); ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT);
nErrorLevel = 1; nErrorLevel = 1;
return 1; return 1;
@ -165,7 +164,7 @@ INT cmd_set (LPTSTR param)
} }
else else
{ {
/* display all environment variable with the given prefix */ /* Display all the environment variables with the given prefix */
BOOL bFound = FALSE; BOOL bFound = FALSE;
while (_istspace(*param) || *param == _T(',') || *param == _T(';')) while (_istspace(*param) || *param == _T(',') || *param == _T(';'))
@ -195,7 +194,7 @@ INT cmd_set (LPTSTR param)
if (!bFound) if (!bFound)
{ {
ConErrResPrintf (STRING_PATH_ERROR, param); ConErrResPrintf(STRING_PATH_ERROR, param);
nErrorLevel = 1; nErrorLevel = 1;
return 1; return 1;
} }
@ -208,36 +207,38 @@ static INT
ident_len(LPCTSTR p) ident_len(LPCTSTR p)
{ {
LPCTSTR p2 = p; LPCTSTR p2 = p;
if ( __iscsymf(*p) ) if (__iscsymf(*p))
{ {
++p2; ++p2;
while ( __iscsym(*p2) ) while (__iscsym(*p2))
++p2; ++p2;
} }
return (INT)(p2-p); return (INT)(p2-p);
} }
#define PARSE_IDENT(ident,identlen,p) \ #define PARSE_IDENT(ident, identlen, p) \
do { \
identlen = ident_len(p); \ identlen = ident_len(p); \
ident = (LPTSTR)alloca ( ( identlen + 1 ) * sizeof(TCHAR) ); \ ident = (LPTSTR)alloca((identlen + 1) * sizeof(TCHAR)); \
memmove ( ident, p, identlen * sizeof(TCHAR) ); \ memmove(ident, p, identlen * sizeof(TCHAR)); \
ident[identlen] = 0; \ ident[identlen] = 0; \
p += identlen; p += identlen; \
} while (0)
static INT static INT
seta_identval(LPCTSTR ident) seta_identval(LPCTSTR ident)
{ {
LPCTSTR identVal = GetEnvVarOrSpecial ( ident ); LPCTSTR identVal = GetEnvVarOrSpecial(ident);
if ( !identVal ) if (!identVal)
return 0; return 0;
else else
return _tcstol ( identVal, NULL, 0 ); return _tcstol(identVal, NULL, 0);
} }
static BOOL static BOOL
calc(INT* lval, TCHAR op, INT rval) calc(INT* lval, TCHAR op, INT rval)
{ {
switch ( op ) switch (op)
{ {
case '*': case '*':
*lval *= rval; *lval *= rval;
@ -264,49 +265,50 @@ calc(INT* lval, TCHAR op, INT rval)
*lval |= rval; *lval |= rval;
break; break;
default: default:
ConErrResPuts ( STRING_INVALID_OPERAND ); ConErrResPuts(STRING_INVALID_OPERAND);
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
static BOOL static BOOL
seta_stmt (LPCTSTR* p_, INT* result); seta_stmt(LPCTSTR* p_, INT* result);
static BOOL static BOOL
seta_unaryTerm(LPCTSTR* p_, INT* result) seta_unaryTerm(LPCTSTR* p_, INT* result)
{ {
LPCTSTR p = *p_; LPCTSTR p = *p_;
if ( *p == _T('(') )
if (*p == _T('('))
{ {
INT rval; INT rval;
p = skip_ws ( p + 1 ); p = skip_ws(p + 1);
if ( !seta_stmt ( &p, &rval ) ) if (!seta_stmt(&p, &rval))
return FALSE; return FALSE;
if ( *p++ != _T(')') ) if (*p++ != _T(')'))
{ {
ConErrResPuts ( STRING_EXPECTED_CLOSE_PAREN ); ConErrResPuts(STRING_EXPECTED_CLOSE_PAREN);
return FALSE; return FALSE;
} }
*result = rval; *result = rval;
} }
else if ( isdigit(*p) ) else if (isdigit(*p))
{ {
*result = _tcstol ( p, (LPTSTR *)&p, 0 ); *result = _tcstol(p, (LPTSTR*)&p, 0);
} }
else if ( __iscsymf(*p) ) else if (__iscsymf(*p))
{ {
LPTSTR ident; LPTSTR ident;
INT identlen; INT identlen;
PARSE_IDENT(ident,identlen,p); PARSE_IDENT(ident, identlen, p);
*result = seta_identval ( ident ); *result = seta_identval(ident);
} }
else else
{ {
ConErrResPuts ( STRING_EXPECTED_NUMBER_OR_VARIABLE ); ConErrResPuts(STRING_EXPECTED_NUMBER_OR_VARIABLE);
return FALSE; return FALSE;
} }
*p_ = skip_ws ( p ); *p_ = skip_ws(p);
return TRUE; return TRUE;
} }
@ -316,14 +318,15 @@ seta_mulTerm(LPCTSTR* p_, INT* result)
LPCTSTR p = *p_; LPCTSTR p = *p_;
TCHAR op = 0; TCHAR op = 0;
INT rval; INT rval;
if ( _tcschr(_T("!~-"),*p) )
if (_tcschr(_T("!~-"), *p))
{ {
op = *p; op = *p;
p = skip_ws ( p + 1 ); p = skip_ws(p + 1);
} }
if ( !seta_unaryTerm ( &p, &rval ) ) if (!seta_unaryTerm(&p, &rval))
return FALSE; return FALSE;
switch ( op ) switch (op)
{ {
case '!': case '!':
rval = !rval; rval = !rval;
@ -346,19 +349,24 @@ seta_ltorTerm(LPCTSTR* p_, INT* result, LPCTSTR ops, BOOL (*subTerm)(LPCTSTR*,IN
{ {
LPCTSTR p = *p_; LPCTSTR p = *p_;
INT lval; INT lval;
if ( !subTerm ( &p, &lval ) )
/* Evaluate the left-hand side */
if (!subTerm(&p, &lval))
return FALSE; return FALSE;
while ( *p && _tcschr(ops,*p) )
while (*p && _tcschr(ops, *p))
{ {
INT rval; INT rval;
TCHAR op = *p; TCHAR op = *p;
p = skip_ws ( p+1 ); p = skip_ws(p + 1);
if ( !subTerm ( &p, &rval ) ) /* Evaluate the immediate right-hand side */
if (!subTerm(&p, &rval))
return FALSE; return FALSE;
if ( !calc ( &lval, op, rval ) ) /* This becomes the new left-hand side for the next iteration */
if (!calc(&lval, op, rval))
return FALSE; return FALSE;
} }
@ -370,13 +378,13 @@ seta_ltorTerm(LPCTSTR* p_, INT* result, LPCTSTR ops, BOOL (*subTerm)(LPCTSTR*,IN
static BOOL static BOOL
seta_addTerm(LPCTSTR* p_, INT* result) seta_addTerm(LPCTSTR* p_, INT* result)
{ {
return seta_ltorTerm ( p_, result, _T("*/%"), seta_mulTerm ); return seta_ltorTerm(p_, result, _T("*/%"), seta_mulTerm);
} }
static BOOL static BOOL
seta_logShiftTerm(LPCTSTR* p_, INT* result) seta_logShiftTerm(LPCTSTR* p_, INT* result)
{ {
return seta_ltorTerm ( p_, result, _T("+-"), seta_addTerm ); return seta_ltorTerm(p_, result, _T("+-"), seta_addTerm);
} }
static BOOL static BOOL
@ -384,19 +392,25 @@ seta_bitAndTerm(LPCTSTR* p_, INT* result)
{ {
LPCTSTR p = *p_; LPCTSTR p = *p_;
INT lval; INT lval;
if ( !seta_logShiftTerm ( &p, &lval ) )
/* Evaluate the left-hand side */
if (!seta_logShiftTerm(&p, &lval))
return FALSE; return FALSE;
while ( *p && _tcschr(_T("<>"),*p) && p[0] == p[1] )
/* Handle << >> operators */
while (*p && _tcschr(_T("<>"), *p) && p[0] == p[1])
{ {
INT rval; INT rval;
TCHAR op = *p; TCHAR op = *p;
p = skip_ws ( p+2 ); p = skip_ws(p + 2);
if ( !seta_logShiftTerm ( &p, &rval ) ) /* Evaluate the immediate right-hand side */
if (!seta_logShiftTerm(&p, &rval))
return FALSE; return FALSE;
switch ( op ) /* This becomes the new left-hand side for the next iteration */
switch (op)
{ {
case '<': case '<':
{ {
@ -408,11 +422,13 @@ seta_bitAndTerm(LPCTSTR* p_, INT* result)
lval <<= rval; lval <<= rval;
break; break;
} }
case '>': case '>':
lval >>= rval; lval >>= rval;
break; break;
default: default:
ConErrResPuts ( STRING_INVALID_OPERAND ); ConErrResPuts(STRING_INVALID_OPERAND);
return FALSE; return FALSE;
} }
} }
@ -425,19 +441,19 @@ seta_bitAndTerm(LPCTSTR* p_, INT* result)
static BOOL static BOOL
seta_bitExclOrTerm(LPCTSTR* p_, INT* result) seta_bitExclOrTerm(LPCTSTR* p_, INT* result)
{ {
return seta_ltorTerm ( p_, result, _T("&"), seta_bitAndTerm ); return seta_ltorTerm(p_, result, _T("&"), seta_bitAndTerm);
} }
static BOOL static BOOL
seta_bitOrTerm(LPCTSTR* p_, INT* result) seta_bitOrTerm(LPCTSTR* p_, INT* result)
{ {
return seta_ltorTerm ( p_, result, _T("^"), seta_bitExclOrTerm ); return seta_ltorTerm(p_, result, _T("^"), seta_bitExclOrTerm);
} }
static BOOL static BOOL
seta_expr(LPCTSTR* p_, INT* result) seta_expr(LPCTSTR* p_, INT* result)
{ {
return seta_ltorTerm ( p_, result, _T("|"), seta_bitOrTerm ); return seta_ltorTerm(p_, result, _T("|"), seta_bitOrTerm);
} }
static BOOL static BOOL
@ -448,34 +464,40 @@ seta_assignment(LPCTSTR* p_, INT* result)
TCHAR op = 0; TCHAR op = 0;
INT identlen, exprval; INT identlen, exprval;
PARSE_IDENT(ident,identlen,p); PARSE_IDENT(ident, identlen, p);
if ( identlen ) if (identlen)
{ {
p = skip_ws(p); p = skip_ws(p);
if ( *p == _T('=') ) /* Handle = assignment */
op = *p, p = skip_ws(p+1); if (*p == _T('='))
else if ( _tcschr ( _T("*/%+-&^|"), *p ) && p[1] == _T('=') ) op = *p, p = skip_ws(p + 1);
op = *p, p = skip_ws(p+2); /* Handle *= /= %= += -= &= ^= |= assignments */
else if ( _tcschr ( _T("<>"), *p ) && *p == p[1] && p[2] == _T('=') ) else if (_tcschr(_T("*/%+-&^|"), *p) && p[1] == _T('='))
op = *p, p = skip_ws(p+3); op = *p, p = skip_ws(p + 2);
/* Handle <<= >>= assignments */
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 */ /* Allow to chain multiple assignments, such as: a=b=1 */
if ( ident && op ) if (ident && op)
{ {
INT identval; INT identval;
LPTSTR buf; LPTSTR buf;
if ( !seta_assignment ( &p, &exprval ) ) if (!seta_assignment(&p, &exprval))
return FALSE; return FALSE;
identval = seta_identval ( ident ); identval = seta_identval(ident);
switch ( op ) switch (op)
{ {
/* Handle = assignment */
case '=': case '=':
identval = exprval; identval = exprval;
break; break;
/* Handle <<= assignment */
case '<': case '<':
{ {
/* Shift left has to be a positive number, 0-31 otherwise 0 is returned, /* Shift left has to be a positive number, 0-31 otherwise 0 is returned,
@ -486,23 +508,28 @@ seta_assignment(LPCTSTR* p_, INT* result)
identval <<= exprval; identval <<= exprval;
break; break;
} }
/* Handle >>= assignment */
case '>': case '>':
identval >>= exprval; identval >>= exprval;
break; break;
/* Other assignments */
default: default:
if ( !calc ( &identval, op, exprval ) ) if (!calc(&identval, op, exprval))
return FALSE; return FALSE;
} }
buf = (LPTSTR)alloca ( 32 * sizeof(TCHAR) );
_sntprintf ( buf, 32, _T("%i"), identval ); buf = (LPTSTR)alloca(32 * sizeof(TCHAR));
SetEnvironmentVariable ( ident, buf ); // TODO FIXME - check return value _sntprintf(buf, 32, _T("%i"), identval);
SetEnvironmentVariable(ident, buf); // TODO FIXME - check return value
exprval = identval; exprval = identval;
} }
else else
{ {
/* restore p in case we found an ident but not an op */ /* Restore p in case we found an identifier but not an operator */
p = *p_; p = *p_;
if ( !seta_expr ( &p, &exprval ) ) if (!seta_expr(&p, &exprval))
return FALSE; return FALSE;
} }
@ -517,13 +544,15 @@ seta_stmt(LPCTSTR* p_, INT* result)
LPCTSTR p = *p_; LPCTSTR p = *p_;
INT rval; INT rval;
if ( !seta_assignment ( &p, &rval ) ) if (!seta_assignment(&p, &rval))
return FALSE; return FALSE;
while ( *p == _T(',') )
{
p = skip_ws ( p+1 );
if ( !seta_assignment ( &p, &rval ) ) /* Loop over each statement */
while (*p == _T(','))
{
p = skip_ws(p + 1);
if (!seta_assignment(&p, &rval))
return FALSE; return FALSE;
} }
@ -536,15 +565,19 @@ static BOOL
seta_eval(LPCTSTR p) seta_eval(LPCTSTR p)
{ {
INT rval; INT rval;
if ( !*p )
if (!*p)
{ {
ConErrResPuts ( STRING_SYNTAX_COMMAND_INCORRECT ); ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT);
return FALSE; return FALSE;
} }
if ( !seta_stmt ( &p, &rval ) ) if (!seta_stmt(&p, &rval))
return FALSE; return FALSE;
if ( !bc )
ConOutPrintf ( _T("%i"), rval ); /* Echo the result of the evaluation only in interactive (non-batch) mode */
if (!bc)
ConOutPrintf(_T("%i"), rval);
return TRUE; return TRUE;
} }