📄 commandssupport.cpp
字号:
{
PrintMessage(CString("Number expected on right of operator: ")+pszCondition,TRUE,TRUE);
_debugStack.DumpStack(_config.nDebugDepth);
}
return(FALSE);
}
double nRight = atof(strCond.Right(nLen-nIndex));
// Do the comparison.
if (strOperator == "=" || strOperator == "==")
return(nLeft == nRight);
else
if (strOperator == "!=")
return(nLeft != nRight);
else
if (strOperator == ">")
return(nLeft > nRight);
else
if (strOperator == "<")
return(nLeft < nRight);
else
if (strOperator == ">=")
return(nLeft >= nRight);
else
if (strOperator == "<=")
return(nLeft <= nRight);
else
{
if (_config.bDebugMessages)
{
PrintMessage(CString("Invalid operator: ")+pszCondition,TRUE,TRUE);
_debugStack.DumpStack(_config.nDebugDepth);
}
return(FALSE);
}
}
/////////////////////////
// Math Functions
//
// Operators supported: * / % + -
BOOL CalculateMath(const char *pszParam, long &lNum)
{
// Should not have any strings in the math formula.
// Also remove any spaces.
CString strText;
int nLen = strlen(pszParam);
int nIndex = 0;
char ch;
while(nIndex < nLen)
{
ch = *(pszParam+nIndex);
if (isalpha(ch))
{
if (_config.bDebugMessages)
{
PrintMessage(CString("Text in math: ")+pszParam,TRUE,TRUE);
_debugStack.DumpStack(_config.nDebugDepth);
}
return(FALSE);
}
if (ch != ' ')
strText += ch;
nIndex++;
}
nLen = strText.GetLength();
// To make life easy, I want to keep simplifying the string until I'm left with just addition and subtraction
// and I'm able to just walk the string from left to right.
// Start with Parens. Need to pull out portions of the string that are surounded by parens.
if (strText.Find('(') != -1 || strText.Find(')') != -1)
{
// There are parens. Make sure we have matched sets.
nIndex = 0;
int nLeftParen = 0;
int nRightParen = 0;
int nParenIndex = 0;
while(nIndex < nLen) // nLen is still set from above.
{
if (strText.GetAt(nIndex) == '(')
{
nLeftParen++;
nParenIndex = nIndex; // Keep track of innermost paren for later.
}
if (strText.GetAt(nIndex) == ')')
nRightParen++;
nIndex++;
}
// If nLeftParen and nRightParen are not equal, there are a mismatched number
// of parens in the formula.
if (nLeftParen != nRightParen)
{
if (_config.bDebugMessages)
{
PrintMessage(CString("Mismatched number of parens: ")+pszParam,TRUE,TRUE);
_debugStack.DumpStack(_config.nDebugDepth);
}
return(FALSE);
}
CString strMeat;
// nLeftParen is equal to the number of sections to replace.
while(nLeftParen)
{
// Find the matching right paren.
nIndex = nParenIndex+1;
while(nIndex < nLen && strText.GetAt(nIndex) != ')')
nIndex++;
// This if should never get hit unless there are some major problems.
// I already know there are matching parens. This checks to see if
// we hit the end of the buffer without finding it.
if (nIndex >= nLen)
{
if (_config.bDebugMessages)
{
PrintMessage("Math error that should never be hit.",TRUE,TRUE);
_debugStack.DumpStack(_config.nDebugDepth);
}
return(FALSE);
}
// Pull out the meat between the parens. (Parens not included)
strMeat = strText.Mid(nParenIndex+1,nIndex-nParenIndex-1);
if (!strMeat.IsEmpty())
{
// Simplify it. This will evaluate all the * % / and return a resultant string.
if (!EvaluateMultDivMod(strMeat))
return(FALSE);
// We should be left with just a number after the + - function.
if (!EvaluatePlusMinus(strMeat))
return(FALSE);
}
strText = strText.Left(nParenIndex) + strMeat + strText.Right(nLen-nIndex-1);
nLen = strText.GetLength();
nLeftParen--;
// If there is still more to do, find the next inner-most paren.
if (nLeftParen)
{
while(nParenIndex >= 0)
{
if (strText.GetAt(nParenIndex) == '(')
break;
nParenIndex--;
}
// We better have found one or something is really wrong.
if (nParenIndex < 0)
{
if (_config.bDebugMessages)
{
PrintMessage(CString("Can't find matching left paren: ")+pszParam,TRUE,TRUE);
_debugStack.DumpStack(_config.nDebugDepth);
}
return(FALSE);
}
}
}
}
if (!EvaluateMultDivMod(strText))
return(FALSE);
if (!EvaluatePlusMinus(strText))
return(FALSE);
lNum = atol(strText);
return(TRUE);
}
BOOL EvaluateMultDivMod(CString &strFormula)
{
CString strNew;
BOOL bNegative = FALSE;
BOOL bDoMath = FALSE;
char chLastOp = ' ';
long lFirstNum = 0;
long lSecondNum = 0;
long lResult;
CString strNum;
int nLen = strFormula.GetLength();
int nIndex = 0;
char ch;
while(nIndex < nLen)
{
ch = strFormula.GetAt(nIndex);
if (isdigit(ch) || (strNum.IsEmpty() && ch == '-'))
{
strNum += ch;
nIndex++;
continue;
}
if (bDoMath)
{
bDoMath = FALSE;
lSecondNum = atol(strNum);
strNum.Empty();
switch(chLastOp)
{
case '*' :
lResult = lFirstNum * lSecondNum;
break;
case '/' :
if (lSecondNum == 0) // Division by Zero.
{
if (_config.bDebugMessages)
{
PrintMessage(CString("Division by zero: ")+strFormula,TRUE,TRUE);
_debugStack.DumpStack(_config.nDebugDepth);
}
return(FALSE);
}
lResult = lFirstNum / lSecondNum;
break;
case '%' :
if (lSecondNum == 0) // Division by Zero.
{
if (_config.bDebugMessages)
{
PrintMessage(CString("Division by zero: ")+strFormula,TRUE,TRUE);
_debugStack.DumpStack(_config.nDebugDepth);
}
return(FALSE);
}
lResult = lFirstNum % lSecondNum;
break;
}
// If the next operator is * / or % then reset the bDoMath stuff.
if (ch == '*' || ch == '/' || ch == '%')
{
bDoMath = TRUE;
chLastOp = ch;
lFirstNum = lResult;
nIndex++;
continue;
}
// The operator must be + or -
strNum.Format("%ld",lResult);
strNew += strNum;
strNew += ch;
nIndex++;
strNum.Empty();
continue;
}
if (ch == '*' || ch == '/' || ch == '%')
{
bDoMath = TRUE;
chLastOp = ch;
lFirstNum = atol(strNum);
nIndex++;
strNum.Empty();
continue;
}
// Must be + or -.
strNew += strNum;
strNew += ch;
nIndex++;
strNum.Empty();
}
if (bDoMath)
{
lSecondNum = atol(strNum);
switch(chLastOp)
{
case '*' :
lResult = lFirstNum * lSecondNum;
break;
case '/' :
if (lSecondNum == 0) // Division by Zero.
{
if (_config.bDebugMessages)
{
PrintMessage(CString("Division by zero: ")+strFormula,TRUE,TRUE);
_debugStack.DumpStack(_config.nDebugDepth);
}
return(FALSE);
}
lResult = lFirstNum / lSecondNum;
break;
case '%' :
if (lSecondNum == 0) // Division by Zero.
{
if (_config.bDebugMessages)
{
PrintMessage(CString("Division by zero: ")+strFormula,TRUE,TRUE);
_debugStack.DumpStack(_config.nDebugDepth);
}
return(FALSE);
}
lResult = lFirstNum % lSecondNum;
break;
}
strNum.Format("%ld",lResult);
strNew += strNum;
}
else
strNew += strNum;
strFormula = strNew;
return(TRUE);
}
BOOL EvaluatePlusMinus(CString &strFormula)
{
CString strNew;
CString strNum;
strNum.Empty();
long lResult = 0;
char chLastOp = '~';
int nLen = strFormula.GetLength();
int nIndex = 0;
char ch;
while(nIndex < nLen)
{
ch = strFormula.GetAt(nIndex);
if (isdigit(ch) || (strNum.IsEmpty() && ch == '-'))
{
strNum += ch;
nIndex++;
continue;
}
if (chLastOp == '~')
lResult = atol(strNum);
else
switch(chLastOp)
{
case '+' :
lResult += atol(strNum);
break;
case '-' :
lResult -= atol(strNum);
break;
default : // Unknown operator.
if (_config.bDebugMessages)
{
PrintMessage(CString("Unknown operator: ")+strFormula,TRUE,TRUE);
_debugStack.DumpStack(_config.nDebugDepth);
}
return(FALSE);
}
strNum.Empty();
chLastOp = ch;
nIndex++;
}
if (!strNum.IsEmpty())
if (chLastOp == '~')
lResult = atol(strNum);
else
switch(chLastOp)
{
case '+' :
lResult += atol(strNum);
break;
case '-' :
lResult -= atol(strNum);
break;
default : // Unknown operator.
if (_config.bDebugMessages)
{
PrintMessage(CString("Unknown operator: ")+strFormula,TRUE,TRUE);
_debugStack.DumpStack(_config.nDebugDepth);
}
return(FALSE);
}
strFormula.Format("%ld",lResult);
return(TRUE);
}
BOOL PausePrompt()
{
_terminal.Print("Press Ctrl+C to cancel, any other key to continue...");
// sit here until they press a key.
while(!kbhit());
_terminal.Print("\n");
char ch = getch();
if (ch == 3) // Ctrl+C
return(FALSE);
// Eat up any extra characters that may be in the buffer.
while(kbhit())
getch();
return(TRUE);
}
BOOL ShowFile(const char *pszFilename)
{
CStdioFileFixed file;
if (!file.Open(pszFilename,CFile::modeRead))
return(FALSE);
CommandPrintOn();
_terminal.Print("\n");
int nNumLines = 0;
int nMaxLines = _terminal.GetWindowLines()-1;
CString strText;
while(file.ReadString(strText))
{
_terminal.Print(strText+"\n");
if (_config.bPause)
{
nNumLines++;
if (nNumLines == nMaxLines)
if (!PausePrompt())
break;
else
nNumLines = 0;
}
}
file.Close();
CommandPrintOff();
return(TRUE);
}
BOOL ShowHelpFile(const char *pszFilename)
{
CString strFile;
strFile.Format("%s.hlp",pszFilename);
return(ShowFile(strFile));
}
void PrepareForWrite(const char *pszText, CString &strOut)
{
char *ptr = strOut.GetBuffer(strlen(pszText)*2);
while(*pszText)
{
if (*pszText == '@' || *pszText == '$' || *pszText == _config.chEscape)
{
*ptr = _config.chEscape;
ptr++;
}
*ptr = *pszText;
ptr++;
pszText++;
}
*ptr = '\x0';
strOut.ReleaseBuffer(-1);
}
// Takes a number without commas, and puts commas in.
void Commatize(CString &strNum)
{
CString strTemp(strNum);
strNum.Empty();
int nLen = strTemp.GetLength();
int nNumSections = nLen / 3;
int nExtras = nLen % 3;
if (nExtras)
nNumSections++;
int nStartPos = 0;
for (int i=0;i<nNumSections;i++)
{
if (!i && nExtras)
{
strNum = strTemp.Left(nExtras);
nStartPos += nExtras;
}
else
{
if (i)
strNum += ",";
strNum += strTemp.Mid(nStartPos,3);
nStartPos += 3;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -