Click here to Skip to main content
15,885,767 members
Articles / Programming Languages / C++

CatchCulator

Rate me:
Please Sign up or sign in to vote.
4.97/5 (71 votes)
18 Oct 2005CPOL7 min read 130K   2K   69  
A tool used to catch and combine values output by different applications.
// Author: Dr. Mircea Puiu
// Created on: October 2005 for CodeProject
//
// ScriptDlg.cpp : implementation file
//

#include "stdafx.h"
#include "CatchCulator.h"
#include "ScriptDlg.h"

#include "CatchCulatorDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CScriptDlg dialog


CScriptDlg::CScriptDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CScriptDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CScriptDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	m_colorBkGnd = RGB(186, 198, 179);
	m_brushBkGnd.CreateSolidBrush(m_colorBkGnd);
	m_strCaption = " Script";
	m_nID = -1;
}


void CScriptDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CScriptDlg)
	DDX_Control(pDX, IDC_EDIT_SCRIPT, m_script);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CScriptDlg, CDialog)
	//{{AFX_MSG_MAP(CScriptDlg)
	ON_WM_CTLCOLOR()
	ON_BN_CLICKED(IDC_BUTTON_UPDATE_SCRIPT, OnButtonUpdateScript)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CScriptDlg message handlers

HBRUSH CScriptDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

	if ( nCtlColor != CTLCOLOR_EDIT)
	{
		hbr = (HBRUSH)m_brushBkGnd.GetSafeHandle();
		pDC->SetBkColor(m_colorBkGnd);
	}
	return hbr;
}

BOOL CScriptDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	SetWindowText(m_strCaption.GetBuffer(0));
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

double CScriptDlg::ComputedValue(char *resultName)
{
	// Look for the <resultName> in m_listToDo and return the result
	double			result = 0.0;
	POSITION		pos;
	Calculation		CL;
	CString			strName = resultName;

	if ( m_listToDo.IsEmpty () ) return result;
	// Cut the blanks at left and right, if any
	strName.TrimLeft();
	strName.TrimRight();
	// Go through the list
	pos = m_listToDo.GetHeadPosition();
	while ( pos )
	{
		CL = m_listToDo.GetNext(pos);
		if ( CL.resultName == strName )
		{
			result = CL.result;
			break;
		}
	}
	return result;
}

POSITION CScriptDlg::FindVariable(char *varName)
{
	// Return the POSITION of [varName] in m_listToDo or NULL if not found
	POSITION		posName = NULL, pos, posCrt;
	Calculation		CL;
	CString			strName = varName;

	if ( m_listToDo.IsEmpty () ) return posName;
	// Cut the blanks at left and right, if any
	strName.TrimLeft();
	strName.TrimRight();
	// Go through the list
	pos = m_listToDo.GetHeadPosition();
	while ( pos )
	{
		posCrt = pos;
		CL = m_listToDo.GetNext(pos);
		if ( CL.resultName == strName )
		{
			posName = posCrt;
			break;
		}
	}
	return posName;
}

void CScriptDlg::OnButtonUpdateScript() 
{
	// TODO: Update the script
	// Supported operations: +, -, *, /
	CCatchCulatorDlg	*pMain = (CCatchCulatorDlg *)AfxGetMainWnd();
	CString				strText, strL, strR, strAux;
	Calculation			CL;
	int					i, nLines, N, posToken, posTokenName1, posTokenName2;
	char				chText[1024], chValue[256];
	bool				bIsZero;
	double				dValue;

	if ( !pMain ) return;
	// Clear the previous calculations list, if any
	if ( !m_listToDo.IsEmpty() ) m_listToDo.RemoveAll();
	// Go throughout the multi-line edit control
	nLines = m_script.GetLineCount();
	for ( i=0; i<nLines; i++ )
	{
		// Get line "i"
		N = m_script.GetLine(i, chText, 1023);
		chText[N] = 0; // make it a null-terminated string
		strText = chText;
		if ( strText.GetLength() < 1 ) continue; // no script in this line
		// Get the operation
		posToken = strText.ReverseFind('*');
		if ( posToken != -1 ) CL.operation = "*";
		else
		{
			posToken = strText.ReverseFind('/');
			if ( posToken != -1 ) CL.operation = "/";
			else
			{
				posToken = strText.ReverseFind('+');
				if ( posToken != -1 ) CL.operation = "+";
				else
				{
					posToken = strText.ReverseFind('-');
					if ( posToken != -1 ) CL.operation = "-";
					else continue; // unrecognized operation
				}
			}
		}
		// Get the name associated with the result
		posTokenName2 = strText.Find(">");
		if ( posTokenName2 == -1 ) continue; // no name
		if ( posTokenName2 > posToken ) continue; // invalid naming
		posTokenName1 = strText.Find("<");
		if ( posTokenName1 == -1 ) continue; // no name
		if ( posTokenName1 > posTokenName2 ) continue; // invalid naming syntax
		CL.resultName = strText.Mid(posTokenName1 + 1, 
									posTokenName2 - posTokenName1 - 1);
		if ( CL.resultName == "" ) continue; // no name
		// Get the operands (left and right with respect to posToken)
		strL = strText.Mid(posTokenName2 + 1, posToken - posTokenName2 - 1);
		strR = strText.Right(strText.GetLength() - posToken - 1);
		if ( (strL == "") && (CL.operation != "+") && (CL.operation != "-") ) 
					continue; // no left operand
		if ( strR == "" ) continue; // no right operand
		strL.TrimLeft();	strL.TrimRight();
		strR.TrimLeft();	strR.TrimRight();
		// Check if strL is a constant value, else
		// look for strL among the names in the catches tree and then
		// among the names within the ToDo list
		strAux = strL;
		strAux.Replace(" ", "");
		bIsZero = false;
		if (strAux == "0" ) bIsZero = true;
		if ( strAux.GetLength() > 255 ) strncpy(chValue, strAux.GetBuffer(0), 255);
		else strcpy(chValue, strAux.GetBuffer(0));
		dValue = 0.0;
		sscanf(chValue, "%lf", &dValue);
		if ( bIsZero && ((int)dValue == 0) )
		{
			// opL is constant 0
			CL.opL = "3-0";
		}
		else if ( dValue != 0 )
		{
			// opL is a (non-zero) constant
			sprintf(chValue, "%lf", dValue);
			CL.opL = "3-";
			CL.opL += chValue;
		}
		else if ( pMain->FindVariable(strL.GetBuffer(0)) )
		{
			// opL is a monitored variable
			CL.opL = "1-";
			CL.opL += strL;
		}
		else
		{
			if ( FindVariable(strL.GetBuffer(0)) )
			{
				CL.opL = "2-";
				CL.opL += strL;
			}
			else
			{
				// Unknown variable, disregard script line
				continue;
			}
		}
		// Check if strR is a constant value, else
		// look for strR among the names in the catches tree and then
		// among the names within the ToDo list
		strAux = strR;
		strAux.Replace(" ", "");
		bIsZero = false;
		if (strAux == "0" ) bIsZero = true;
		if ( strAux.GetLength() > 255 ) strncpy(chValue, strAux.GetBuffer(0), 255);
		else strcpy(chValue, strAux.GetBuffer(0));
		dValue = 0.0;
		sscanf(chValue, "%lf", &dValue);
		if ( bIsZero && ((int)dValue == 0) )
		{
			// opR is constant 0
			CL.opR = "3-0";
		}
		else if ( dValue != 0 )
		{
			// opR is a (non-zero) constant
			sprintf(chValue, "%lf", dValue);
			CL.opR = "3-";
			CL.opR += chValue;
		}
		else if ( pMain->FindVariable(strR.GetBuffer(0)) )
		{
			// opL is a monitored variable
			CL.opR = "1-";
			CL.opR += strR;
		}
		else
		{
			if ( FindVariable(strR.GetBuffer(0)) )
			{
				CL.opR = "2-";
				CL.opR += strR;
			}
			else
			{
				// Unknown variable, disregard script line
				continue;
			}
		}
		// Initialize the result with 0
		CL.result = 0.0;
		// Add CL to m_listToDo
		m_listToDo.AddTail(CL);
	} // next line of script (i)
	// Update the display
	pMain->UpdateDisplay(m_nID);
}

void CScriptDlg::UpdateScript()
{
	OnButtonUpdateScript();
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Europe Europe
More than 30 years of software development experience.
(also playing the SCRUM Master role depending on the project)

Comments and Discussions