Commit 3121c71f authored by David Saxton's avatar David Saxton

Changed internal method of reporting parser errors (now far more reliable).

svn path=/trunk/KDE/kdeedu/kmplot/; revision=562445
parent 0d8e0e8c
......@@ -28,7 +28,7 @@
#include <qradiobutton.h>
#include "settings.h"
#include "xparser.h"
#include "coordsconfigdialog.h"
#include "ui_editcoords.h"
......@@ -41,8 +41,8 @@ class EditCoords : public QWidget, public Ui::EditCoords
{ setupUi(this); }
};
CoordsConfigDialog::CoordsConfigDialog(XParser *p, QWidget *parent)
: KConfigDialog(parent, "coords", Settings::self()), m_parser(p)
CoordsConfigDialog::CoordsConfigDialog(QWidget *parent)
: KConfigDialog(parent, "coords", Settings::self())
{
configAxesDialog = new EditCoords( 0 );
configAxesDialog->layout()->setMargin( 0 );
......@@ -57,12 +57,22 @@ CoordsConfigDialog::~CoordsConfigDialog()
bool CoordsConfigDialog::evalX()
{
double const min = m_parser->eval( configAxesDialog->kcfg_XMin->text() );
if ( m_parser->parserError( true )!=0 )
Parser::Error error;
double const min = XParser::self()->eval( configAxesDialog->kcfg_XMin->text(), & error );
if ( error != Parser::ParseSuccess )
{
XParser::self()->displayErrorDialog( error );
return false;
double const max = m_parser->eval( configAxesDialog->kcfg_XMax->text() );
if ( m_parser->parserError( true )!=0 )
}
double const max = XParser::self()->eval( configAxesDialog->kcfg_XMax->text(), & error );
if ( error != Parser::ParseSuccess )
{
XParser::self()->displayErrorDialog( error );
return false;
}
if ( min >= max )
{
KMessageBox::sorry(this,i18n("The minimum range value must be lower than the maximum range value"));
......@@ -70,14 +80,25 @@ bool CoordsConfigDialog::evalX()
}
return true;
}
bool CoordsConfigDialog::evalY()
{
double const min = m_parser->eval( configAxesDialog->kcfg_YMin->text() );
if ( m_parser->parserError( true )!=0 )
Parser::Error error;
double const min = XParser::self()->eval( configAxesDialog->kcfg_YMin->text(), & error );
if ( error != Parser::ParseSuccess )
{
XParser::self()->displayErrorDialog( error );
return false;
double const max = m_parser->eval( configAxesDialog->kcfg_YMax->text() );
if ( m_parser->parserError( true )!=0 )
}
double const max = XParser::self()->eval( configAxesDialog->kcfg_YMax->text(), & error );
if ( error != Parser::ParseSuccess )
{
XParser::self()->displayErrorDialog( error );
return false;
}
if ( min >= max )
{
KMessageBox::sorry(this,i18n("The minimum range value must be lower than the maximum range value"));
......
......@@ -27,8 +27,6 @@
#include <kconfigdialog.h>
#include "xparser.h"
namespace Ui{
class EditCoords;
}
......@@ -43,7 +41,7 @@ class CoordsConfigDialog : public KConfigDialog
{
Q_OBJECT
public:
CoordsConfigDialog(XParser *p, QWidget *parent = 0);
CoordsConfigDialog(QWidget *parent = 0);
~CoordsConfigDialog();
protected slots:
virtual void slotOk();
......@@ -52,7 +50,6 @@ class CoordsConfigDialog : public KConfigDialog
bool evalX();
bool evalY();
Parser *m_parser;
EditCoords * configAxesDialog;
};
......
......@@ -60,8 +60,9 @@ Value::Value( double value )
bool Value::updateExpression( const QString & expression )
{
double newValue = XParser::self()->eval( expression );
if ( XParser::self()->parserError( false ) )
Parser::Error error;
double newValue = XParser::self()->eval( expression, & error );
if ( error != Parser::ParseSuccess )
return false;
m_value = newValue;
......@@ -389,9 +390,10 @@ bool Equation::setFstr( const QString & fstr, int * error, int * errorPosition )
m_fstr = prevFstr;
updateVariables();
XParser::self()->setParserError( Parser::ZeroOrder );
*error = Parser::ZeroOrder;
*errorPosition = XParser::self()->errorPosition();
/// \todo indicate the position of the error
*errorPosition = 0;
return false;
}
......@@ -402,18 +404,14 @@ bool Equation::setFstr( const QString & fstr, int * error, int * errorPosition )
updateVariables();
/// \todo indicate the position of the invalid argument?
XParser::self()->setParserError( Parser::TooManyArguments );
*error = Parser::TooManyArguments;
*errorPosition = XParser::self()->errorPosition();
*errorPosition = -1;
return false;
}
XParser::self()->initEquation( this );
if ( XParser::self()->parserError( false ) != Parser::ParseSuccess )
XParser::self()->initEquation( this, (Parser::Error*)error, errorPosition );
if ( *error != Parser::ParseSuccess )
{
*error = XParser::self()->parserError( false );
*errorPosition = XParser::self()->errorPosition();
// kDebug() << k_funcinfo << "BAD XParser::self()->errorPosition()="<< *errorPosition<< " error="<<XParser::self()->errorString((Parser::Error)*error)<< endl;
m_fstr = prevFstr;
......
......@@ -159,7 +159,7 @@ bool KConstantEditor::checkValueValid()
{
Parser::Error error;
(double) XParser::self()->eval( valueEdit->text(), & error );
bool valid = (error == Parser::ParseSuccess) & m_constantValidator->isValid( nameEdit->text() );
bool valid = (error == Parser::ParseSuccess) && m_constantValidator->isValid( nameEdit->text() );
valueInvalidLabel->setVisible( !valid );
return valid;
}
......
......@@ -42,6 +42,7 @@
#include "kmplotio.h"
#include "maindlg.h"
#include "settings.h"
#include "xparser.h"
static QString CurrentVersionString( "4" );
......
......@@ -144,8 +144,9 @@ void KParameterEditor::saveCurrentValue()
bool KParameterEditor::checkValueValid()
{
QString valueText = m_mainWidget->value->text();
(double) XParser::self()->eval( valueText );
bool valid = (XParser::self()->parserError( false ) == 0);
Parser::Error error;
(double) XParser::self()->eval( valueText, & error );
bool valid = (error == Parser::ParseSuccess);
m_mainWidget->valueInvalidLabel->setVisible( !valueText.isEmpty() && !valid );
return valid;
}
......@@ -187,8 +188,10 @@ void KParameterEditor::cmdImport_clicked()
line = stream.readLine();
if (line.isEmpty())
continue;
XParser::self()->eval( line );
if ( XParser::self()->parserError(false) == 0)
Parser::Error error;
XParser::self()->eval( line, & error );
if ( error == Parser::ParseSuccess )
{
if ( !checkTwoOfIt(line) )
{
......
......@@ -54,6 +54,7 @@
#include "functioneditor.h"
#include "kprinterdlg.h"
#include "kconstanteditor.h"
#include "xparser.h"
#include "settings.h"
#include "maindlg.h"
......@@ -695,7 +696,7 @@ void MainDlg::editAxes()
// create a config dialog and add a axes page
if ( !coordsDialog)
{
coordsDialog = new CoordsConfigDialog( XParser::self(), m_parent);
coordsDialog = new CoordsConfigDialog(m_parent);
// User edited the configuration - update your local copies of the
// configuration data
connect( coordsDialog, SIGNAL( settingsChanged(const QString &) ), this, SLOT(updateSettings() ) );
......
......@@ -129,13 +129,13 @@ VectorFunction Parser::vectorFunctions[ VectorCount ]=
Parser::Parser()
: m_sanitizer( this )
{
m_errorPosition = -1;
m_evalPos = 0;
m_nextFunctionID = 0;
m_stack = new double [STACKSIZE];
stkptr = m_stack;
m_constants = new Constants;
m_error = 0;
m_ownEquation = 0;
m_currentEquation = 0;
}
......@@ -218,6 +218,14 @@ uint Parser::getNewId()
double Parser::eval( const QString & str, Error * error, int * errorPosition )
{
Error t1;
if ( ! error )
error = & t1;
int t2;
if ( ! errorPosition )
errorPosition = & t2;
if ( !m_ownEquation )
m_ownEquation = new Equation( Equation::Cartesian, 0 );
......@@ -239,7 +247,7 @@ double Parser::fkt(uint const id, int eq, double x )
{
if ( !m_ufkt.contains( id ) || m_ufkt[id]->eq.size() <= eq )
{
m_error = NoSuchFunction;
*m_error = NoSuchFunction;
return 0;
}
......@@ -490,7 +498,7 @@ int Parser::addFunction( const QString & str1, const QString & str2, Function::T
if ( !temp->eq[i]->setFstr( str[i] ) )
{
kDebug() << "could not set fstr to \""<<str[i]<<"\"! error:"<<errorString(m_error)<<"\n";
kDebug() << "could not set fstr to \""<<str[i]<<"\"! error:"<<errorString(*m_error)<<"\n";
delete temp;
return -1;
}
......@@ -498,7 +506,7 @@ int Parser::addFunction( const QString & str1, const QString & str2, Function::T
if ( fnameToID( temp->eq[i]->name() ) != -1 )
{
kDebug() << "function name reused.\n";
m_error = FunctionNameReused;
*m_error = FunctionNameReused;
delete temp;
return -1;
}
......@@ -514,13 +522,24 @@ int Parser::addFunction( const QString & str1, const QString & str2, Function::T
}
void Parser::initEquation( Equation * eq )
void Parser::initEquation( Equation * eq, Error * error, int * errorPosition )
{
Error t1;
if ( ! error )
error = & t1;
int t2;
if ( ! errorPosition )
errorPosition = & t2;
if ( eq->parent() )
eq->parent()->clearFunctionDependencies();
m_error = ParseSuccess;
m_errorPosition = -1;
m_error = error;
*m_error = ParseSuccess;
*errorPosition = -1;
m_currentEquation = eq;
mem = mptr = eq->mem;
m_pmAt = 0;
......@@ -530,11 +549,11 @@ void Parser::initEquation( Equation * eq )
m_evalPos = m_eval.indexOf( '=' ) + 1;
heir1();
if ( !evalRemaining().isEmpty() && m_error == ParseSuccess )
m_error = SyntaxError;
if ( !evalRemaining().isEmpty() && *m_error == ParseSuccess )
*m_error = SyntaxError;
if ( m_error != ParseSuccess )
m_errorPosition = m_sanitizer.realPos( m_evalPos );
if ( *m_error != ParseSuccess )
*errorPosition = m_sanitizer.realPos( m_evalPos );
addToken(ENDE);
}
......@@ -577,7 +596,7 @@ void Parser::heir1()
QChar c;
heir2();
if (m_error!=ParseSuccess)
if (*m_error!=ParseSuccess)
return;
while(1)
......@@ -595,12 +614,12 @@ void Parser::heir1()
case 0xb1:
if ( m_pmAt >= MAX_PM )
{
m_error = TooManyPM;
*m_error = TooManyPM;
return;
}
if ( m_currentEquation == m_ownEquation )
{
m_error = InvalidPM;
*m_error = InvalidPM;
return;
}
// no break
......@@ -610,7 +629,7 @@ void Parser::heir1()
++m_evalPos;
addToken(PUSH);
heir2();
if(m_error!=ParseSuccess)
if(*m_error!=ParseSuccess)
return;
}
switch ( c.unicode() )
......@@ -637,14 +656,14 @@ void Parser::heir2()
if ( match("-") )
{
heir2();
if(m_error!=ParseSuccess)
if(*m_error!=ParseSuccess)
return;
addToken(NEG);
}
else if ( match( QChar(0x221a) ) ) // square root symbol
{
heir2();
if(m_error!=ParseSuccess)
if(*m_error!=ParseSuccess)
return;
addToken(SQRT);
}
......@@ -657,7 +676,7 @@ void Parser::heir3()
{
QChar c;
heir4();
if(m_error!=ParseSuccess)
if(*m_error!=ParseSuccess)
return;
while(1)
{
......@@ -674,7 +693,7 @@ void Parser::heir3()
++m_evalPos;
addToken(PUSH);
heir4();
if(m_error!=ParseSuccess)
if(*m_error!=ParseSuccess)
return ;
}
switch ( c.unicode() )
......@@ -693,13 +712,13 @@ void Parser::heir3()
void Parser::heir4()
{
primary();
if(m_error!=ParseSuccess)
if(*m_error!=ParseSuccess)
return;
while(match("^"))
{
addToken(PUSH);
primary();
if(m_error!=ParseSuccess)
if(*m_error!=ParseSuccess)
return;
addToken(POW);
}
......@@ -722,7 +741,7 @@ bool Parser::tryFunction()
heir1();
if ( !match(")") && !match(",") )
m_error = MissingBracket;
*m_error = MissingBracket;
return true;
}
......@@ -791,14 +810,14 @@ bool Parser::tryUserFunction()
if ( it->eq[i] == m_currentEquation || (m_currentEquation && it->dependsOn( m_currentEquation->parent() )) )
{
m_error = RecursiveFunctionCall;
*m_error = RecursiveFunctionCall;
return true;
}
int argCount = readFunctionArguments();
if ( argCount != it->eq[i]->variables().size() )
{
m_error = IncorrectArgumentCount;
*m_error = IncorrectArgumentCount;
return true;
}
......@@ -880,7 +899,7 @@ int Parser::readFunctionArguments()
m_evalPos--;
}
}
while ( m_error == ParseSuccess && argLeft && !evalRemaining().isEmpty() );
while ( *m_error == ParseSuccess && argLeft && !evalRemaining().isEmpty() );
return argCount;
}
......@@ -902,7 +921,7 @@ bool Parser::match( const QString & lit )
void Parser::addToken( Token token )
{
if ( mptr>=&mem[MEMSIZE-10] )
m_error = MemoryOverflow;
*m_error = MemoryOverflow;
else
*mptr++=token;
}
......@@ -915,7 +934,7 @@ void Parser::addConstant(double x)
double *pd=(double*)mptr;
if(mptr>=&mem[MEMSIZE-10])
m_error = MemoryOverflow;
*m_error = MemoryOverflow;
else
{
*pd++=x;
......@@ -929,7 +948,7 @@ void Parser::adduint(uint x)
uint *p=(uint*)mptr;
if(mptr>=&mem[MEMSIZE-10])
m_error = MemoryOverflow;
*m_error = MemoryOverflow;
else
{
*p++=x;
......@@ -943,7 +962,7 @@ void Parser::addfptr(double(*fadr)(double))
double (**pf)(double)=(double(**)(double))mptr;
if( mptr>=&mem[MEMSIZE-10] )
m_error = MemoryOverflow;
*m_error = MemoryOverflow;
else
{
*pf++=fadr;
......@@ -961,7 +980,7 @@ void Parser::addfptr( double(*fadr)(const Vector & ), int argCount )
double (**pf)(const Vector &) = (double(**)(const Vector &))mptr;
if( mptr>=&mem[MEMSIZE-10] )
m_error = MemoryOverflow;
*m_error = MemoryOverflow;
else
{
*pf++=fadr;
......@@ -975,7 +994,7 @@ void Parser::addfptr( uint id, uint eq_id, uint args )
uint *p=(uint*)mptr;
if(mptr>=&mem[MEMSIZE-10])
m_error=MemoryOverflow;
*m_error=MemoryOverflow;
else
{
*p++=id;
......@@ -1061,15 +1080,11 @@ QString Parser::errorString( Error error )
}
Parser::Error Parser::parserError(bool showMessageBox)
{
if (!showMessageBox)
return m_error;
QString message( errorString(m_error) );
void Parser::displayErrorDialog( Error error )
{
QString message( errorString(error) );
if ( !message.isEmpty() )
KMessageBox::sorry(0, message, "KmPlot");
return m_error;
}
......
......@@ -333,19 +333,9 @@ class Parser : public QObject
*/
static QString errorString( Error error );
/**
* Position where the error occurred.
* Displays an error dialog appropriate to \p error.
*/
int errorPosition() const { return m_errorPosition; }
/**
* If showMessageBox is true, an error message box will appear if an
* error was found.
* \return The current error value.
*/
Error parserError( bool showMessageBox );
/**
* Called by e.g. Equation::setFstr before the parser stage is reached.
*/
void setParserError( Error error ) { m_error = error; }
void displayErrorDialog( Error error );
/**
* \return the number of radians per angle-unit that the user has
* selected (i.e. this will return 1.0 if the user has selected
......@@ -362,7 +352,7 @@ class Parser : public QObject
* Initializes the function for evaluation. Called after the functions
* fstr is set.
*/
void initEquation( Equation * equation );
void initEquation( Equation * equation, Error * error = 0, int * errorPosition = 0 );
uint getNewId(); /// Returns the next ID-number
uint countFunctions(); /// Returns how many functions there are
......@@ -387,10 +377,6 @@ class Parser : public QObject
static ScalarFunction scalarFunctions[ScalarCount];
static VectorFunction vectorFunctions[VectorCount];
Error m_error;
/// Position where the error occurred.
int m_errorPosition;
void heir1();
void heir2();
void heir3();
......@@ -444,6 +430,7 @@ class Parser : public QObject
Constants * m_constants;
ExpressionSanitizer m_sanitizer;
int m_pmAt; ///< When parsing an expression, which plus-minus symbol at
Error * m_error;
private:
friend class XParser;
......
......@@ -66,6 +66,7 @@
#include "parameteranimator.h"
#include "view.h"
#include "viewadaptor.h"
#include "xparser.h"
// other includes
......
......@@ -125,7 +125,6 @@ bool XParser::getext( Function *item, const QString fstr )
str = str.mid( p2, 1000 );
Value value;
if ( !value.updateExpression( tstr ) )
if ( parserError(false) )
{
errflg = true;
break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment