--HG--
branch : feature
This commit is contained in:
dismine 2014-05-01 14:33:40 +03:00
parent 37ecf9fd86
commit 362638066a
41 changed files with 7158 additions and 7036 deletions

View file

@ -61,7 +61,3 @@ qreal VMeasurement::GetValue(const qreal &size, const qreal &height) const
const qreal k_height = ( height - 176.0 ) / 6.0;
return base + k_size * ksize + k_height * kheight;
}

View file

@ -37,23 +37,23 @@
class VMeasurement
{
public:
/**
* @brief VStandardTableRow create empty row
*/
VMeasurement();
/**
* @brief VStandardTableRow create row
* @param base value in base size and growth
* @param ksize increment in sizes
* @param kgrowth increment in growths
* @param description description of increment
*/
VMeasurement(const qreal &base, const qreal &ksize, const qreal &kheight,
const QString &gui_text = QString(), const QString &number = QString(),
const QString &TagName = QString());
VMeasurement(const qreal &base, const QString &gui_text = QString(),
const QString &number = QString(), const QString &TagName = QString());
~VMeasurement(){}
/**
* @brief VStandardTableRow create empty row
*/
VMeasurement();
/**
* @brief VStandardTableRow create row
* @param base value in base size and growth
* @param ksize increment in sizes
* @param kgrowth increment in growths
* @param description description of increment
*/
VMeasurement(const qreal &base, const qreal &ksize, const qreal &kheight,
const QString &gui_text = QString(), const QString &number = QString(),
const QString &TagName = QString());
VMeasurement(const qreal &base, const QString &gui_text = QString(),
const QString &number = QString(), const QString &TagName = QString());
~VMeasurement(){}
/**
* @brief GetBase return value in base size and growth
* @return value

View file

@ -54,7 +54,7 @@ DialogIncrements::DialogIncrements(VContainer *data, VPattern *doc, QWidget *par
m = new VIndividualMeasurements(data);
m->setContent(filePath);
}
catch(VException &e)
catch (VException &e)
{
e.CriticalMessageBox(tr("File error."), this);
emit DialogClosed(QDialog::Rejected);
@ -101,8 +101,8 @@ DialogIncrements::DialogIncrements(VContainer *data, VPattern *doc, QWidget *par
ui->lineEditGivenName->setText(m->GivenName());
ui->lineEditFamilyName->setText(m->FamilyName());
ui->comboBoxSex->addItem(tr("male"),QVariant(m->GenderToStr(VIndividualMeasurements::Male)));
ui->comboBoxSex->addItem(tr("female"),QVariant(m->GenderToStr(VIndividualMeasurements::Female)));
ui->comboBoxSex->addItem(tr("male"), QVariant(m->GenderToStr(VIndividualMeasurements::Male)));
ui->comboBoxSex->addItem(tr("female"), QVariant(m->GenderToStr(VIndividualMeasurements::Female)));
qint32 index = ui->comboBoxSex->findData(m->GenderToStr(m->Sex()));
if (index != -1)
{
@ -473,7 +473,7 @@ void DialogIncrements::OpenTable()
m1 = new VIndividualMeasurements(data);
m1->setContent(filePath);
}
catch(VException &e)
catch (VException &e)
{
e.CriticalMessageBox(tr("File error."), this);
delete m1;
@ -529,7 +529,7 @@ void DialogIncrements::OpenTable()
doc->SetPath(filePath);
emit haveLiteChange();
}
catch(VException &e)
catch (VException &e)
{
e.CriticalMessageBox(tr("File error."), this);
delete m1;

View file

@ -116,7 +116,7 @@ void DialogIndividualMeasurements::DialogAccepted()
iMeasur.close();
}
}
catch(VException &e)
catch (VException &e)
{
e.CriticalMessageBox(tr("File error."), this);
qDebug()<<"File error."<<e.ErrorMessage()<<e.DetailedInformation()<<Q_FUNC_INFO;
@ -214,7 +214,7 @@ void DialogIndividualMeasurements::LoadIndividualTables()
const QString lang = QLocale(m.Language()).nativeLanguageName();
ui->comboBoxLang->addItem(lang, QVariant(fi.absoluteFilePath()));
}
catch(VException &e)
catch (VException &e)
{
qDebug()<<"File error."<<e.ErrorMessage()<<e.DetailedInformation()<<Q_FUNC_INFO;
continue;
@ -249,7 +249,7 @@ void DialogIndividualMeasurements::OpenTable()
{
VDomDocument::ValidateXML("://schema/individual_measurements.xsd", fileName);
}
catch(VException &e)
catch (VException &e)
{
e.CriticalMessageBox(tr("File error."), this);
fileName.clear();

View file

@ -86,7 +86,7 @@ void DialogStandardMeasurements::DialogAccepted()
m.setContent(_tablePath);
qApp->setPatternUnit(m.Unit());
}
catch(VException &e)
catch (VException &e)
{
e.CriticalMessageBox(tr("File error."), this);
qDebug()<<"File error."<<e.ErrorMessage()<<e.DetailedInformation()<<Q_FUNC_INFO;
@ -152,7 +152,7 @@ void DialogStandardMeasurements::LoadStandardTables()
m.setContent(fi.absoluteFilePath());
ui->comboBoxTables->addItem(m.Description(), QVariant(fi.absoluteFilePath()));
}
catch(VException &e)
catch (VException &e)
{
qDebug()<<"File error."<<e.ErrorMessage()<<e.DetailedInformation()<<Q_FUNC_INFO;
continue;

View file

@ -105,8 +105,8 @@ void DialogDetail::DialogAccepted()
emit DialogClosed(QDialog::Accepted);
}
void DialogDetail::NewItem(quint32 id, const Valentina::Tools &typeTool, const NodeDetail::NodeDetails &typeNode, qreal mx,
qreal my)
void DialogDetail::NewItem(quint32 id, const Valentina::Tools &typeTool, const NodeDetail::NodeDetails &typeNode,
qreal mx, qreal my)
{
QString name;
switch (typeTool)

View file

@ -133,7 +133,8 @@ private:
* @param idDetail id detail
* @param index index of edge
*/
void ChoosedDetail(const quint32 &id, const Valentina::Scenes &type, quint32 &idDetail, ptrdiff_t &index);
void ChoosedDetail(const quint32 &id, const Valentina::Scenes &type, quint32 &idDetail,
ptrdiff_t &index);
};
inline quint32 DialogUnionDetails::getD1() const

View file

@ -70,7 +70,8 @@ void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &context, c
{
QByteArray localMsg = msg.toLocal8Bit();
QMessageBox messageBox;
switch (type) {
switch (type)
{
case QtDebugMsg:
fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line,
context.function);

View file

@ -157,8 +157,8 @@ void MainWindow::ActionNewDraw()
pattern->ClearGObjects();
//Create single point
const quint32 id = pattern->AddGObject(new VPointF(qApp->toPixel((10+comboBoxDraws->count()*5)), qApp->toPixel(10), "А", 5,
10));
const quint32 id = pattern->AddGObject(new VPointF(qApp->toPixel((10+comboBoxDraws->count()*5)), qApp->toPixel(10),
"А", 5, 10));
VToolSinglePoint *spoint = new VToolSinglePoint(doc, pattern, id, Valentina::FromGui);
sceneDraw->addItem(spoint);
connect(spoint, &VToolPoint::ChoosedTool, sceneDraw, &VMainGraphicsScene::ChoosedItem);
@ -261,8 +261,8 @@ void MainWindow::ClosedDialogLine(int result)
void MainWindow::ToolAlongLine(bool checked)
{
SetToolButton<DialogAlongLine>(checked, Valentina::AlongLineTool, ":/cursor/alongline_cursor.png", tr("Select point"),
&MainWindow::ClosedDialogAlongLine);
SetToolButton<DialogAlongLine>(checked, Valentina::AlongLineTool, ":/cursor/alongline_cursor.png",
tr("Select point"), &MainWindow::ClosedDialogAlongLine);
}
void MainWindow::ClosedDialogAlongLine(int result)
@ -360,8 +360,9 @@ void MainWindow::ClosedDialogSplinePath(int result)
void MainWindow::ToolCutSplinePath(bool checked)
{
SetToolButton<DialogCutSplinePath>(checked, Valentina::CutSplinePathTool, ":/cursor/splinepath_cut_point_cursor.png",
tr("Select curve path"), &MainWindow::ClosedDialogCutSplinePath);
SetToolButton<DialogCutSplinePath>(checked, Valentina::CutSplinePathTool,
":/cursor/splinepath_cut_point_cursor.png", tr("Select curve path"),
&MainWindow::ClosedDialogCutSplinePath);
}
void MainWindow::ClosedDialogCutSplinePath(int result)
@ -420,8 +421,9 @@ void MainWindow::ClosedDialogTriangle(int result)
void MainWindow::ToolPointOfIntersection(bool checked)
{
SetToolButton<DialogPointOfIntersection>(checked, Valentina::PointOfIntersection, ":/cursor/pointofintersect_cursor.png",
tr("Select point vertically"), &MainWindow::ClosedDialogPointOfIntersection);
SetToolButton<DialogPointOfIntersection>(checked, Valentina::PointOfIntersection,
":/cursor/pointofintersect_cursor.png", tr("Select point vertically"),
&MainWindow::ClosedDialogPointOfIntersection);
}
void MainWindow::ClosedDialogPointOfIntersection(int result)
@ -431,8 +433,8 @@ void MainWindow::ClosedDialogPointOfIntersection(int result)
void MainWindow::ToolUnionDetails(bool checked)
{
SetToolButton<DialogUnionDetails>(checked, Valentina::UnionDetails, ":/cursor/union_cursor.png", tr("Select detail"),
&MainWindow::ClosedDialogUnionDetails);
SetToolButton<DialogUnionDetails>(checked, Valentina::UnionDetails, ":/cursor/union_cursor.png",
tr("Select detail"), &MainWindow::ClosedDialogUnionDetails);
//Must disconnect this signal here.
disconnect(doc, &VPattern::FullUpdateFromFile, dialogTool, &DialogTool::UpdateList);
}
@ -1358,7 +1360,7 @@ void MainWindow::LoadPattern(const QString &fileName)
QString path = doc->MPath();
path = CheckPathToMeasurements(path, qApp->patternType());
if(path.isEmpty())
if (path.isEmpty())
{
Clear();
return;
@ -1394,7 +1396,7 @@ void MainWindow::LoadPattern(const QString &fileName)
}
}
}
catch(VException &e)
catch (VException &e)
{
e.CriticalMessageBox(tr("File error."), this);
Clear();
@ -1440,7 +1442,7 @@ void MainWindow::LoadPattern(const QString &fileName)
Clear();
return;
}
catch(VException &e)
catch (VException &e)
{
e.CriticalMessageBox(tr("Error parsing file."), this);
Clear();
@ -1478,7 +1480,7 @@ QString MainWindow::CheckPathToMeasurements(const QString &path, const Pattern::
QMessageBox::StandardButton res = QMessageBox::question(this, "Loading measurements file", text,
QMessageBox::Yes | QMessageBox::No,
QMessageBox::Yes);
if(res == QMessageBox::No)
if (res == QMessageBox::No)
{
return QString();
}
@ -1495,7 +1497,7 @@ QString MainWindow::CheckPathToMeasurements(const QString &path, const Pattern::
}
QString mPath = QFileDialog::getOpenFileName(this, tr("Open file"), QDir::homePath(), filter);
if(mPath.isEmpty())
if (mPath.isEmpty())
{
return mPath;
}

View file

@ -111,6 +111,6 @@ namespace Pattern
enum Measurement { Standard, Individual };
Q_DECLARE_FLAGS(Measurements, Measurement)
}
Q_DECLARE_OPERATORS_FOR_FLAGS( Pattern::Measurements )
Q_DECLARE_OPERATORS_FOR_FLAGS( Pattern::Measurements )
#endif // OPTIONS_H

View file

@ -222,26 +222,26 @@ void TableWindow::saveScene()
suffix << "svg" << "png" << "pdf" << "eps" << "ps";
switch (suffix.indexOf(fi.suffix()))
{
case 0: //svg
paper->setVisible(false);
SvgFile(name);
paper->setVisible(true);
break;
case 1: //png
PngFile(name);
break;
case 2: //pdf
PdfFile(name);
break;
case 3: //eps
EpsFile(name);
break;
case 4: //ps
PsFile(name);
break;
default:
qDebug() << "Bad file suffix"<<Q_FUNC_INFO;
break;
case 0: //svg
paper->setVisible(false);
SvgFile(name);
paper->setVisible(true);
break;
case 1: //png
PngFile(name);
break;
case 2: //pdf
PdfFile(name);
break;
case 3: //eps
EpsFile(name);
break;
case 4: //ps
PsFile(name);
break;
default:
qDebug() << "Bad file suffix"<<Q_FUNC_INFO;
break;
}
paper->setPen(QPen(Qt::black, qApp->toPixel(qApp->widthMainLine())));
brush->setColor( QColor( Qt::gray ) );

View file

@ -36,7 +36,7 @@ const QString VToolPoint::TagName = QStringLiteral("point");
VToolPoint::VToolPoint(VPattern *doc, VContainer *data, quint32 id, QGraphicsItem *parent):VDrawTool(doc, data, id),
QGraphicsEllipseItem(parent), radius(DefRadius), namePoint(0), lineName(0)
{
switch(qApp->patternUnit())
switch (qApp->patternUnit())
{
case Valentina::Mm:
radius = qApp->toPixel(DefRadius);

View file

@ -31,9 +31,9 @@
const QString VToolTriangle::ToolType = QStringLiteral("triangle");
VToolTriangle::VToolTriangle(VPattern *doc, VContainer *data, const quint32 &id,
const quint32 &axisP1Id, const quint32 &axisP2Id, const quint32 &firstPointId,
const quint32 &secondPointId, const Valentina::Sources &typeCreation, QGraphicsItem *parent)
VToolTriangle::VToolTriangle(VPattern *doc, VContainer *data, const quint32 &id, const quint32 &axisP1Id,
const quint32 &axisP2Id, const quint32 &firstPointId, const quint32 &secondPointId,
const Valentina::Sources &typeCreation, QGraphicsItem *parent)
:VToolPoint(doc, data, id, parent), axisP1Id(axisP1Id), axisP2Id(axisP2Id), firstPointId(firstPointId),
secondPointId(secondPointId)
{

View file

@ -48,8 +48,9 @@ public:
* @param typeCreation way we create this tool.
* @param parent parent object.
*/
VNodeArc(VPattern *doc, VContainer *data, quint32 id, quint32 idArc, const Valentina::Sources &typeCreation,
const quint32 &idTool = 0, QObject *qoParent = nullptr, QGraphicsItem * parent = nullptr);
VNodeArc(VPattern *doc, VContainer *data, quint32 id, quint32 idArc,
const Valentina::Sources &typeCreation, const quint32 &idTool = 0,
QObject *qoParent = nullptr, QGraphicsItem * parent = nullptr);
/**
* @brief Create help create tool.
* @param doc dom document container.

View file

@ -39,18 +39,17 @@ class VNodePoint: public VAbstractNode, public QGraphicsEllipseItem
{
Q_OBJECT
public:
/**
* @brief VNodePoint constructor.
* @param doc dom document container.
* @param data container with variables.
* @param id object id in container.
* @param id object id in containerPoint.
* @param typeCreation way we create this tool.
* @param parent parent object.
*/
VNodePoint(VPattern *doc, VContainer *data, quint32 id, quint32 idPoint,
const Valentina::Sources &typeCreation, const quint32 &idTool = 0, QObject *qoParent = nullptr,
QGraphicsItem * parent = nullptr );
/**
* @brief VNodePoint constructor.
* @param doc dom document container.
* @param data container with variables.
* @param id object id in container.
* @param id object id in containerPoint.
* @param typeCreation way we create this tool.
* @param parent parent object.
*/
VNodePoint(VPattern *doc, VContainer *data, quint32 id, quint32 idPoint, const Valentina::Sources &typeCreation,
const quint32 &idTool = 0, QObject *qoParent = nullptr, QGraphicsItem * parent = nullptr );
/**
* @brief Create help create tool.
* @param doc dom document container.
@ -60,9 +59,8 @@ public:
* @param parse parser file mode.
* @param typeCreation way we create this tool.
*/
static void Create(VPattern *doc, VContainer *data, quint32 id, quint32 idPoint,
const Document::Documents &parse, const Valentina::Sources &typeCreation, const quint32 &idTool = 0,
QObject *parent = nullptr);
static void Create(VPattern *doc, VContainer *data, quint32 id, quint32 idPoint, const Document::Documents &parse,
const Valentina::Sources &typeCreation, const quint32 &idTool = 0, QObject *parent = nullptr);
static const QString TagName;
static const QString ToolType;
/**

View file

@ -39,18 +39,17 @@ class VNodeSpline:public VAbstractNode, public QGraphicsPathItem
{
Q_OBJECT
public:
/**
* @brief VNodeSpline constructor.
* @param doc dom document container.
* @param data container with variables.
* @param id object id in container.
* @param id object id in containerSpline.
* @param typeCreation way we create this tool.
* @param parent parent object.
*/
VNodeSpline(VPattern *doc, VContainer *data, quint32 id, quint32 idSpline,
const Valentina::Sources &typeCreation, const quint32 &idTool = 0, QObject *qoParent = nullptr,
QGraphicsItem * parent = nullptr);
/**
* @brief VNodeSpline constructor.
* @param doc dom document container.
* @param data container with variables.
* @param id object id in container.
* @param id object id in containerSpline.
* @param typeCreation way we create this tool.
* @param parent parent object.
*/
VNodeSpline(VPattern *doc, VContainer *data, quint32 id, quint32 idSpline, const Valentina::Sources &typeCreation,
const quint32 &idTool = 0, QObject *qoParent = nullptr, QGraphicsItem * parent = nullptr);
/**
* @brief Create help create tool.
* @param doc dom document container.

View file

@ -53,8 +53,8 @@ VNodeSplinePath::VNodeSplinePath(VPattern *doc, VContainer *data, quint32 id, qu
}
void VNodeSplinePath::Create(VPattern *doc, VContainer *data, quint32 id, quint32 idSpline,
const Document::Documents &parse, const Valentina::Sources &typeCreation, const quint32 &idTool,
QObject *parent)
const Document::Documents &parse, const Valentina::Sources &typeCreation,
const quint32 &idTool, QObject *parent)
{
VAbstractTool::AddRecord(id, Valentina::NodeSplinePath, doc);
if (parse == Document::FullParse)

View file

@ -60,9 +60,8 @@ public:
* @param parse parser file mode.
* @param typeCreation way we create this tool.
*/
static void Create(VPattern *doc, VContainer *data, quint32 id, quint32 idSpline,
const Document::Documents &parse, const Valentina::Sources &typeCreation, const quint32 &idTool = 0,
QObject *parent = 0);
static void Create(VPattern *doc, VContainer *data, quint32 id, quint32 idSpline, const Document::Documents &parse,
const Valentina::Sources &typeCreation, const quint32 &idTool = 0, QObject *parent = 0);
static const QString TagName;
static const QString ToolType;
/**

View file

@ -481,7 +481,7 @@ void VToolUnionDetails::Create(const quint32 _id, const VDetail &d1, const VDeta
++j;
} while (pointsD2 < d2.RemoveEdge(indexD2).CountNode());
}
} while(i < d1.RemoveEdge(indexD1).CountNode());
} while (i < d1.RemoveEdge(indexD1).CountNode());
newDetail.setName("Detail");
VToolDetail::Create(0, newDetail, scene, doc, data, parse, Valentina::FromTool);

View file

@ -174,7 +174,7 @@ QString VApplication::translationsPath() const
void VApplication::InitLineWidth()
{
switch(_patternUnit)
switch (_patternUnit)
{
case Valentina::Mm:
_widthMainLine = DefWidth;

View file

@ -293,7 +293,8 @@ void VDomDocument::ValidateXML(const QString &schema, const QString &fileName)
pattern.close();
fileSchema.close();
VException e(messageHandler.statusMessage());
e.AddMoreInformation(tr("Validation error in line %1 column %2").arg(messageHandler.line()).arg(messageHandler.column()));
e.AddMoreInformation(tr("Validation error in line %1 column %2").arg(messageHandler.line())
.arg(messageHandler.column()));
throw e;
}
pattern.close();
@ -347,7 +348,7 @@ Valentina::Units VDomDocument::StrToUnits(const QString &unit)
QString VDomDocument::UnitsToStr(const Valentina::Units &unit)
{
QString result;
switch(unit)
switch (unit)
{
case Valentina::Mm:
result = "mm";

View file

@ -42,21 +42,21 @@
/**
* @brief The VDomDocument class represents a Valentina document (.val file).
*
* A Valentina document describes the construction of a sewing pattern. The
*
* A Valentina document describes the construction of a sewing pattern. The
* information is stored in XML format. By parsing a VDomDocument, the contained
* pattern is rendered to a Valentina graphics scene (VMainGraphicsScene).
*
* A sewing pattern consists of zero or more increments and one
* A sewing pattern consists of zero or more increments and one
* or more pattern pieces.
*
* An increment is an auxiliary variable that is calculated from regular measurement
* variables (that belong to the standard measurements table). Increments are used to
* create a graduation schema for the sewing pattern.
*
* A pattern piece contains
* A pattern piece contains
* 1) auxiliary pattern construction elements (calculation),
* 2) pattern construction elements (modeling), and
* 2) pattern construction elements (modeling), and
* 3) special markers, e.g. seam allowances (details).
* Of these, 2) and 3) are visible in the final pattern (draw mode 'Modeling'),
* 1) is only displayed when editing (draw mode 'Calculation') the pattern.

View file

@ -460,7 +460,7 @@ Valentina::Units VPattern::MUnit() const
QStringList units;
units << "mm" << "cm" << "inch";
QString unit = GetParametrString(element, AttrUnit);
switch(units.indexOf(unit))
switch (units.indexOf(unit))
{
case 0:// mm
return Valentina::Mm;
@ -491,7 +491,7 @@ Pattern::Measurements VPattern::MType() const
QString type = GetParametrString(element, AttrType);
QStringList types;
types << "standard" << "individual";
switch(types.indexOf(type))
switch (types.indexOf(type))
{
case 0:// standard
return Pattern::Standard;
@ -1049,7 +1049,8 @@ void VPattern::ParsePointElement(VMainGraphicsScene *scene, const QDomElement &d
const QString formula = GetParametrString(domElement, VAbstractTool::AttrLength, "0");
const quint32 splineId = GetParametrUInt(domElement, VToolCutSpline::AttrSpline, "0");
VToolCutSpline::Create(id, name, formula, splineId, mx, my, scene, this, data, parse, Valentina::FromFile);
VToolCutSpline::Create(id, name, formula, splineId, mx, my, scene, this, data, parse,
Valentina::FromFile);
}
catch (const VExceptionBadId &e)
{

View file

@ -70,7 +70,7 @@ void VStandardMeasurements::Measurements()
}
else
{
for(qint32 i = 0; i < nodeList.size(); ++i)
for (qint32 i = 0; i < nodeList.size(); ++i)
{
const QDomNode domNode = nodeList.at(i);
if (domNode.isNull() == false && domNode.isElement())

View file

@ -39,78 +39,78 @@ namespace qmu
// Trigonometric function
qreal QmuParser::Sinh(qreal v)
{
return sinh(v);
return sinh(v);
}
qreal QmuParser::Cosh(qreal v)
{
return cosh(v);
return cosh(v);
}
qreal QmuParser::Tanh(qreal v)
{
return tanh(v);
return tanh(v);
}
qreal QmuParser::ASinh(qreal v)
{
return log(v + qSqrt(v * v + 1));
return log(v + qSqrt(v * v + 1));
}
qreal QmuParser::ACosh(qreal v)
{
return log(v + qSqrt(v * v - 1));
return log(v + qSqrt(v * v - 1));
}
qreal QmuParser::ATanh(qreal v)
{
return (0.5 * log((1 + v) / (1 - v)));
return (0.5 * log((1 + v) / (1 - v)));
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
// Logarithm functions
// Logarithm base 2
qreal QmuParser::Log2(qreal v)
{
#ifdef MUP_MATH_EXCEPTIONS
if (v<=0)
{
throw QmuParserError(ecDOMAIN_ERROR, "Log2");
}
if (v<=0)
{
throw QmuParserError(ecDOMAIN_ERROR, "Log2");
}
#endif
return log(v)/log(2.0);
return log(v)/log(2.0);
}
// Logarithm base 10
qreal QmuParser::Log10(qreal v)
{
#ifdef MUP_MATH_EXCEPTIONS
if (v<=0)
{
throw QmuParserError(ecDOMAIN_ERROR, "Log10");
}
if (v<=0)
{
throw QmuParserError(ecDOMAIN_ERROR, "Log10");
}
#endif
return log10(v);
return log10(v);
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
// misc
qreal QmuParser::Abs(qreal v)
{
return qAbs(v);
return qAbs(v);
}
qreal QmuParser::Rint(qreal v)
{
return qFloor(v + 0.5);
return qFloor(v + 0.5);
}
qreal QmuParser::Sign(qreal v)
{
return ((v<0) ? -1 : (v>0) ? 1 : 0);
return ((v<0) ? -1 : (v>0) ? 1 : 0);
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Callback for the unary minus operator.
* @param v The value to negate
@ -118,10 +118,10 @@ qreal QmuParser::Sign(qreal v)
*/
qreal QmuParser::UnaryMinus(qreal v)
{
return -v;
return -v;
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Callback for adding multiple values.
* @param [in] a_afArg Vector with the function arguments
@ -129,16 +129,19 @@ qreal QmuParser::UnaryMinus(qreal v)
*/
qreal QmuParser::Sum(const qreal *a_afArg, int a_iArgc)
{
if (!a_iArgc)
{
throw exception_type("too few arguments for function sum.");
}
qreal fRes=0;
for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
return fRes;
if (a_iArgc == false)
{
throw exception_type("too few arguments for function sum.");
}
qreal fRes=0;
for (int i=0; i<a_iArgc; ++i)
{
fRes += a_afArg[i];
}
return fRes;
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Callback for averaging multiple values.
* @param [in] a_afArg Vector with the function arguments
@ -146,16 +149,19 @@ qreal QmuParser::Sum(const qreal *a_afArg, int a_iArgc)
*/
qreal QmuParser::Avg(const qreal *a_afArg, int a_iArgc)
{
if (!a_iArgc)
{
throw exception_type("too few arguments for function sum.");
}
qreal fRes=0;
for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
return fRes/static_cast<qreal>(a_iArgc);
if (a_iArgc == false)
{
throw exception_type("too few arguments for function sum.");
}
qreal fRes=0;
for (int i=0; i<a_iArgc; ++i)
{
fRes += a_afArg[i];
}
return fRes/static_cast<qreal>(a_iArgc);
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Callback for determining the minimum value out of a vector.
* @param [in] a_afArg Vector with the function arguments
@ -163,19 +169,19 @@ qreal QmuParser::Avg(const qreal *a_afArg, int a_iArgc)
*/
qreal QmuParser::Min(const qreal *a_afArg, int a_iArgc)
{
if (!a_iArgc)
{
throw exception_type("too few arguments for function min.");
}
qreal fRes=a_afArg[0];
for (int i=0; i<a_iArgc; ++i)
{
fRes = qMin(fRes, a_afArg[i]);
}
return fRes;
if (a_iArgc == false)
{
throw exception_type("too few arguments for function min.");
}
qreal fRes=a_afArg[0];
for (int i=0; i<a_iArgc; ++i)
{
fRes = qMin(fRes, a_afArg[i]);
}
return fRes;
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Callback for determining the maximum value out of a vector.
* @param [in] a_afArg Vector with the function arguments
@ -183,19 +189,19 @@ qreal QmuParser::Min(const qreal *a_afArg, int a_iArgc)
*/
qreal QmuParser::Max(const qreal *a_afArg, int a_iArgc)
{
if (!a_iArgc)
{
throw exception_type("too few arguments for function min.");
}
qreal fRes=a_afArg[0];
for (int i=0; i<a_iArgc; ++i)
{
fRes = qMax(fRes, a_afArg[i]);
}
return fRes;
if (a_iArgc == false)
{
throw exception_type("too few arguments for function min.");
}
qreal fRes=a_afArg[0];
for (int i=0; i<a_iArgc; ++i)
{
fRes = qMax(fRes, a_afArg[i]);
}
return fRes;
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Default value recognition callback.
* @param [in] a_szExpr Pointer to the expression
@ -205,30 +211,30 @@ qreal QmuParser::Max(const qreal *a_afArg, int a_iArgc)
*/
int QmuParser::IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal)
{
qreal fVal(0);
qreal fVal(0);
#if defined(_UNICODE)
std::wstring a_szExprStd = a_szExpr.toStdWString();
#else
std::string a_szExprStd = a_szExpr.toStdString();
#endif
stringstream_type stream(a_szExprStd);
stream.seekg(0); // todo: check if this really is necessary
stream.imbue(QmuParser::s_locale);
stream >> fVal;
stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading
#if defined(_UNICODE)
std::wstring a_szExprStd = a_szExpr.toStdWString();
#else
std::string a_szExprStd = a_szExpr.toStdString();
#endif
stringstream_type stream(a_szExprStd);
stream.seekg(0); // todo: check if this really is necessary
stream.imbue(QmuParser::s_locale);
stream >> fVal;
stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading
if (iEnd==static_cast<stringstream_type::pos_type>(-1))
{
return 0;
}
if (iEnd==static_cast<stringstream_type::pos_type>(-1))
{
return 0;
}
*a_iPos += static_cast<int>(iEnd);
*a_fVal = fVal;
return 1;
*a_iPos += static_cast<int>(iEnd);
*a_fVal = fVal;
return 1;
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Constructor.
*
@ -236,15 +242,15 @@ int QmuParser::IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal)
*/
QmuParser::QmuParser():QmuParserBase()
{
AddValIdent(IsVal);
AddValIdent(IsVal);
InitCharSets();
InitFun();
InitConst();
InitOprt();
InitCharSets();
InitFun();
InitConst();
InitOprt();
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Define the character sets.
* @sa DefineNameChars, DefineOprtChars, DefineInfixOprtChars
@ -254,53 +260,53 @@ QmuParser::QmuParser():QmuParserBase()
*/
void QmuParser::InitCharSets()
{
DefineNameChars( "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" );
DefineOprtChars( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_{}" );
DefineInfixOprtChars( "/+-*^?<>=#!$%&|~'_" );
DefineNameChars( "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" );
DefineOprtChars( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_{}" );
DefineInfixOprtChars( "/+-*^?<>=#!$%&|~'_" );
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Initialize the default functions.
*/
void QmuParser::InitFun()
{
// trigonometric functions
DefineFun("sin", qSin);
DefineFun("cos", qCos);
DefineFun("tan", qTan);
// arcus functions
DefineFun("asin", qAsin);
DefineFun("acos", qAcos);
DefineFun("atan", qAtan);
DefineFun("atan2", qAtan2);
// hyperbolic functions
DefineFun("sinh", Sinh);
DefineFun("cosh", Cosh);
DefineFun("tanh", Tanh);
// arcus hyperbolic functions
DefineFun("asinh", ASinh);
DefineFun("acosh", ACosh);
DefineFun("atanh", ATanh);
// Logarithm functions
DefineFun("log2", Log2);
DefineFun("log10", Log10);
DefineFun("log", Log10);
DefineFun("ln", qLn);
// misc
DefineFun("exp", qExp);
DefineFun("sqrt", qSqrt);
DefineFun("sign", Sign);
DefineFun("rint", Rint);
DefineFun("abs", Abs);
// Functions with variable number of arguments
DefineFun("sum", Sum);
DefineFun("avg", Avg);
DefineFun("min", Min);
DefineFun("max", Max);
// trigonometric functions
DefineFun("sin", qSin);
DefineFun("cos", qCos);
DefineFun("tan", qTan);
// arcus functions
DefineFun("asin", qAsin);
DefineFun("acos", qAcos);
DefineFun("atan", qAtan);
DefineFun("atan2", qAtan2);
// hyperbolic functions
DefineFun("sinh", Sinh);
DefineFun("cosh", Cosh);
DefineFun("tanh", Tanh);
// arcus hyperbolic functions
DefineFun("asinh", ASinh);
DefineFun("acosh", ACosh);
DefineFun("atanh", ATanh);
// Logarithm functions
DefineFun("log2", Log2);
DefineFun("log10", Log10);
DefineFun("log", Log10);
DefineFun("ln", qLn);
// misc
DefineFun("exp", qExp);
DefineFun("sqrt", qSqrt);
DefineFun("sign", Sign);
DefineFun("rint", Rint);
DefineFun("abs", Abs);
// Functions with variable number of arguments
DefineFun("sum", Sum);
DefineFun("avg", Avg);
DefineFun("min", Min);
DefineFun("max", Max);
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Initialize constants.
*
@ -309,11 +315,11 @@ void QmuParser::InitFun()
*/
void QmuParser::InitConst()
{
DefineConst("_pi", (qreal)M_PI);
DefineConst("_e", (qreal)M_E);
DefineConst("_pi", (qreal)M_PI);
DefineConst("_e", (qreal)M_E);
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Initialize operators.
*
@ -321,38 +327,38 @@ void QmuParser::InitConst()
*/
void QmuParser::InitOprt()
{
DefineInfixOprt("-", UnaryMinus);
DefineInfixOprt("-", UnaryMinus);
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
void QmuParser::OnDetectVar(const QString &pExpr, int &nStart, int &nEnd)
{
Q_UNUSED(pExpr);
Q_UNUSED(nStart);
Q_UNUSED(nEnd);
// this is just sample code to illustrate modifying variable names on the fly.
// I'm not sure anyone really needs such a feature...
/*
Q_UNUSED(pExpr);
Q_UNUSED(nStart);
Q_UNUSED(nEnd);
// this is just sample code to illustrate modifying variable names on the fly.
// I'm not sure anyone really needs such a feature...
/*
string sVar(pExpr->begin()+nStart, pExpr->begin()+nEnd);
string sRepl = std::string("_") + sVar + "_";
string sVar(pExpr->begin()+nStart, pExpr->begin()+nEnd);
string sRepl = std::string("_") + sVar + "_";
int nOrigVarEnd = nEnd;
cout << "variable detected!\n";
cout << " Expr: " << *pExpr << "\n";
cout << " Start: " << nStart << "\n";
cout << " End: " << nEnd << "\n";
cout << " Var: \"" << sVar << "\"\n";
cout << " Repl: \"" << sRepl << "\"\n";
nEnd = nStart + sRepl.length();
cout << " End: " << nEnd << "\n";
pExpr->replace(pExpr->begin()+nStart, pExpr->begin()+nOrigVarEnd, sRepl);
cout << " New expr: " << *pExpr << "\n";
*/
int nOrigVarEnd = nEnd;
cout << "variable detected!\n";
cout << " Expr: " << *pExpr << "\n";
cout << " Start: " << nStart << "\n";
cout << " End: " << nEnd << "\n";
cout << " Var: \"" << sVar << "\"\n";
cout << " Repl: \"" << sRepl << "\"\n";
nEnd = nStart + sRepl.length();
cout << " End: " << nEnd << "\n";
pExpr->replace(pExpr->begin()+nStart, pExpr->begin()+nOrigVarEnd, sRepl);
cout << " New expr: " << *pExpr << "\n";
*/
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Numerically differentiate with regard to a variable.
* @param [in] a_Var Pointer to the differentiation variable.
@ -368,25 +374,25 @@ void QmuParser::OnDetectVar(const QString &pExpr, int &nStart, int &nEnd)
*/
qreal QmuParser::Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon) const
{
qreal fRes(0),
fBuf(*a_Var),
f[4] = {0,0,0,0},
fEpsilon(a_fEpsilon);
qreal fRes(0),
fBuf(*a_Var),
f[4] = {0, 0, 0, 0},
fEpsilon(a_fEpsilon);
// Backwards compatible calculation of epsilon inc case the user doesnt provide
// his own epsilon
if (qFuzzyCompare(fEpsilon + 1, 1 + 0))
{
fEpsilon = (qFuzzyCompare(a_fPos + 1, 1 + 0)) ? static_cast<qreal>(1e-10) : static_cast<qreal>(1e-7) * a_fPos;
}
// Backwards compatible calculation of epsilon inc case the user doesnt provide
// his own epsilon
if (qFuzzyCompare(fEpsilon + 1, 1 + 0))
{
fEpsilon = (qFuzzyCompare(a_fPos + 1, 1 + 0)) ? static_cast<qreal>(1e-10) : static_cast<qreal>(1e-7) * a_fPos;
}
*a_Var = a_fPos+2 * fEpsilon; f[0] = Eval();
*a_Var = a_fPos+1 * fEpsilon; f[1] = Eval();
*a_Var = a_fPos-1 * fEpsilon; f[2] = Eval();
*a_Var = a_fPos-2 * fEpsilon; f[3] = Eval();
*a_Var = fBuf; // restore variable
*a_Var = a_fPos+2 * fEpsilon; f[0] = Eval();
*a_Var = a_fPos+1 * fEpsilon; f[1] = Eval();
*a_Var = a_fPos-1 * fEpsilon; f[2] = Eval();
*a_Var = a_fPos-2 * fEpsilon; f[3] = Eval();
*a_Var = fBuf; // restore variable
fRes = (-f[0] + 8*f[1] - 8*f[2] + f[3]) / (12*fEpsilon);
return fRes;
fRes = (-f[0] + 8*f[1] - 8*f[2] + f[3]) / (12*fEpsilon);
return fRes;
}
} // namespace qmu

View file

@ -51,7 +51,7 @@ namespace qmu
virtual void InitFun();
virtual void InitConst();
virtual void InitOprt();
virtual void OnDetectVar(const QString &pExpr, int &nStart, int &nEnd);
virtual void OnDetectVar(const QString &pExpr, int &nStart, int &nEnd);
qreal Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon = 0) const;
protected:
static int IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal);

File diff suppressed because it is too large Load diff

View file

@ -1,262 +1,261 @@
/***************************************************************************************************
**
** Original work Copyright (C) 2013 Ingo Berg
** Modified work Copyright 2014 Roman Telezhynskyi <dismine(at)gmail.com>
**
** Permission is hereby granted, free of charge, to any person obtaining a copy of this
** software and associated documentation files (the "Software"), to deal in the Software
** without restriction, including without limitation the rights to use, copy, modify,
** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in all copies or
** substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
******************************************************************************************************/
#ifndef QMUQPARSERBASE_H
#define QMUQPARSERBASE_H
#include <QStack>
#include <QString>
#include <QStringList>
#include "qmuparserdef.h"
#include "qmuparsertokenreader.h"
#include "qmuparserbytecode.h"
#include "qmuparsererror.h"
namespace qmu
{
/**
* @file
* @brief This file contains the class definition of the qmuparser engine.
*/
/**
* @brief Mathematical expressions parser (base parser engine).
* @author (C) 2013 Ingo Berg
*
* This is the implementation of a bytecode based mathematical expressions parser.
* The formula will be parsed from string and converted into a bytecode.
* Future calculations will be done with the bytecode instead the formula string
* resulting in a significant performance increase.
* Complementary to a set of internally implemented functions the parser is able to handle
* user defined functions and variables.
*/
class QmuParserBase
{
friend class QmuParserTokenReader;
public:
/**
* @brief Type of the error class.
*
* Included for backwards compatibility.
*/
typedef QmuParserError exception_type;
QmuParserBase();
QmuParserBase(const QmuParserBase &a_Parser);
QmuParserBase& operator=(const QmuParserBase &a_Parser);
virtual ~QmuParserBase();
static void EnableDebugDump(bool bDumpCmd, bool bDumpStack);
qreal Eval() const;
qreal* Eval(int &nStackSize) const;
void Eval(qreal *results, int nBulkSize);
int GetNumResults() const;
void SetExpr(const QString &a_sExpr);
void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL);
void SetDecSep(char_type cDecSep);
void SetThousandsSep(char_type cThousandsSep = 0);
void ResetLocale();
void EnableOptimizer(bool a_bIsOn=true);
void EnableBuiltInOprt(bool a_bIsOn=true);
bool HasBuiltInOprt() const;
void AddValIdent(identfun_type a_pCallback);
void DefineOprt(const QString &a_strName, fun_type2 a_pFun, unsigned a_iPri=0,
EOprtAssociativity a_eAssociativity = oaLEFT, bool a_bAllowOpt = false);
void DefineConst(const QString &a_sName, qreal a_fVal);
void DefineStrConst(const QString &a_sName, const QString &a_strVal);
void DefineVar(const QString &a_sName, qreal *a_fVar);
void DefinePostfixOprt(const QString &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true);
void DefineInfixOprt(const QString &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX,
bool a_bAllowOpt=true);
// Clear user defined variables, constants or functions
void ClearVar();
void ClearFun();
void ClearConst();
void ClearInfixOprt();
void ClearPostfixOprt();
void ClearOprt();
void RemoveVar(const QString &a_strVarName);
const varmap_type& GetUsedVar() const;
const varmap_type& GetVar() const;
const valmap_type& GetConst() const;
const QString& GetExpr() const;
const funmap_type& GetFunDef() const;
QString GetVersion(EParserVersionInfo eInfo = pviFULL) const;
const QStringList& GetOprtDef() const;
void DefineNameChars(const QString &a_szCharset);
void DefineOprtChars(const QString &a_szCharset);
void DefineInfixOprtChars(const QString &a_szCharset);
const QString& ValidNameChars() const;
const QString& ValidOprtChars() const;
const QString& ValidInfixOprtChars() const;
void SetArgSep(char_type cArgSep);
QChar GetArgSep() const;
void Error(EErrorCodes a_iErrc, int a_iPos = -1, const QString &a_strTok = QString() ) const;
/**
* @fn void qmu::QmuParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun,
* bool a_bAllowOpt = true)
* @brief Define a parser function without arguments.
* @param a_strName Name of the function
* @param a_pFun Pointer to the callback function
* @param a_bAllowOpt A flag indicating this function may be optimized
*/
template<typename T>
void DefineFun(const QString &a_strName, T a_pFun, bool a_bAllowOpt = true)
{
AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() );
}
protected:
static const QStringList c_DefaultOprt;
static std::locale s_locale; ///< The locale used by the parser
static bool g_DbgDumpCmdCode;
static bool g_DbgDumpStack;
void Init();
virtual void InitCharSets() = 0;
virtual void InitFun() = 0;
virtual void InitConst() = 0;
virtual void InitOprt() = 0;
virtual void OnDetectVar(const QString &pExpr, int &nStart, int &nEnd);
/**
* @brief A facet class used to change decimal and thousands separator.
*/
template<class TChar>
class change_dec_sep : public std::numpunct<TChar>
{
public:
explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3)
:std::numpunct<TChar>(), m_nGroup(nGroup), m_cDecPoint(cDecSep), m_cThousandsSep(cThousandsSep)
{}
protected:
virtual char_type do_decimal_point() const
{
return m_cDecPoint;
}
virtual char_type do_thousands_sep() const
{
return m_cThousandsSep;
}
virtual std::string do_grouping() const
{
return std::string(1, m_nGroup);
}
private:
int m_nGroup;
char_type m_cDecPoint;
char_type m_cThousandsSep;
};
private:
/**
* @brief Typedef for the parse functions.
*
* The parse function do the actual work. The parser exchanges
* the function pointer to the parser function depending on
* which state it is in. (i.e. bytecode parser vs. string parser)
*/
typedef qreal (QmuParserBase::*ParseFunction)() const;
/**
* @brief Type used for storing an array of values.
*/
typedef QVector<qreal> valbuf_type;
/**
* @brief Type for a vector of strings.
*/
typedef QVector<QString> stringbuf_type;
/**
* @brief Typedef for the token reader.
*/
typedef QmuParserTokenReader token_reader_type;
/**
* @brief Type used for parser tokens.
*/
typedef QmuParserToken<qreal, QString> token_type;
/**
* @brief Maximum number of threads spawned by OpenMP when using the bulk mode.
*/
static const int s_MaxNumOpenMPThreads = 4;
/**
* @brief Pointer to the parser function.
*
* Eval() calls the function whose address is stored there.
*/
mutable ParseFunction m_pParseFormula;
mutable QmuParserByteCode m_vRPN; ///< The Bytecode class.
mutable stringbuf_type m_vStringBuf; ///< String buffer, used for storing string function arguments
stringbuf_type m_vStringVarBuf;
std::unique_ptr<token_reader_type> m_pTokenReader; ///< Managed pointer to the token reader object.
funmap_type m_FunDef; ///< Map of function names and pointers.
funmap_type m_PostOprtDef; ///< Postfix operator callbacks
funmap_type m_InfixOprtDef; ///< unary infix operator.
funmap_type m_OprtDef; ///< Binary operator callbacks
valmap_type m_ConstDef; ///< user constants.
strmap_type m_StrVarDef; ///< user defined string constants
varmap_type m_VarDef; ///< user defind variables.
bool m_bBuiltInOp; ///< Flag that can be used for switching built in operators on and off
QString m_sNameChars; ///< Charset for names
QString m_sOprtChars; ///< Charset for postfix/ binary operator tokens
QString m_sInfixOprtChars; ///< Charset for infix operator tokens
mutable int m_nIfElseCounter; ///< Internal counter for keeping track of nested if-then-else clauses
// items merely used for caching state information
mutable valbuf_type m_vStackBuffer; ///< This is merely a buffer used for the stack in the cmd parsing routine
mutable int m_nFinalResultIdx;
void Assign(const QmuParserBase &a_Parser);
void InitTokenReader();
void ReInit() const;
void AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback,
funmap_type &a_Storage, const QString &a_szCharSet );
void ApplyRemainingOprt(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal) const;
void ApplyBinOprt(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal) const;
void ApplyIfElse(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal) const;
void ApplyFunc(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal, int iArgCount) const;
token_type ApplyStrFunc(const token_type &a_FunTok, const QVector<token_type> &a_vArg) const;
int GetOprtPrecedence(const token_type &a_Tok) const;
EOprtAssociativity GetOprtAssociativity(const token_type &a_Tok) const;
void CreateRPN() const;
qreal ParseString() const;
qreal ParseCmdCode() const;
qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const;
void CheckName(const QString &a_strName, const QString &a_CharSet) const;
void CheckOprt(const QString &a_sName, const QmuParserCallback &a_Callback,
const QString &a_szCharSet) const;
void StackDump(const QStack<token_type > &a_stVal, const QStack<token_type > &a_stOprt) const;
};
} // namespace qmu
#endif
/***************************************************************************************************
**
** Original work Copyright (C) 2013 Ingo Berg
** Modified work Copyright 2014 Roman Telezhynskyi <dismine(at)gmail.com>
**
** Permission is hereby granted, free of charge, to any person obtaining a copy of this
** software and associated documentation files (the "Software"), to deal in the Software
** without restriction, including without limitation the rights to use, copy, modify,
** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in all copies or
** substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
******************************************************************************************************/
#ifndef QMUQPARSERBASE_H
#define QMUQPARSERBASE_H
#include <QStack>
#include <QString>
#include <QStringList>
#include "qmuparserdef.h"
#include "qmuparsertokenreader.h"
#include "qmuparserbytecode.h"
#include "qmuparsererror.h"
namespace qmu
{
/**
* @file
* @brief This file contains the class definition of the qmuparser engine.
*/
/**
* @brief Mathematical expressions parser (base parser engine).
* @author (C) 2013 Ingo Berg
*
* This is the implementation of a bytecode based mathematical expressions parser.
* The formula will be parsed from string and converted into a bytecode.
* Future calculations will be done with the bytecode instead the formula string
* resulting in a significant performance increase.
* Complementary to a set of internally implemented functions the parser is able to handle
* user defined functions and variables.
*/
class QmuParserBase
{
friend class QmuParserTokenReader;
public:
/**
* @brief Type of the error class.
*
* Included for backwards compatibility.
*/
typedef QmuParserError exception_type;
QmuParserBase();
QmuParserBase(const QmuParserBase &a_Parser);
QmuParserBase& operator=(const QmuParserBase &a_Parser);
virtual ~QmuParserBase();
static void EnableDebugDump(bool bDumpCmd, bool bDumpStack);
qreal Eval() const;
qreal* Eval(int &nStackSize) const;
void Eval(qreal *results, int nBulkSize);
int GetNumResults() const;
void SetExpr(const QString &a_sExpr);
void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL);
void SetDecSep(char_type cDecSep);
void SetThousandsSep(char_type cThousandsSep = 0);
void ResetLocale();
void EnableOptimizer(bool a_bIsOn=true);
void EnableBuiltInOprt(bool a_bIsOn=true);
bool HasBuiltInOprt() const;
void AddValIdent(identfun_type a_pCallback);
void DefineOprt(const QString &a_strName, fun_type2 a_pFun, unsigned a_iPri=0,
EOprtAssociativity a_eAssociativity = oaLEFT, bool a_bAllowOpt = false);
void DefineConst(const QString &a_sName, qreal a_fVal);
void DefineStrConst(const QString &a_sName, const QString &a_strVal);
void DefineVar(const QString &a_sName, qreal *a_fVar);
void DefinePostfixOprt(const QString &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true);
void DefineInfixOprt(const QString &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX,
bool a_bAllowOpt=true);
// Clear user defined variables, constants or functions
void ClearVar();
void ClearFun();
void ClearConst();
void ClearInfixOprt();
void ClearPostfixOprt();
void ClearOprt();
void RemoveVar(const QString &a_strVarName);
const varmap_type& GetUsedVar() const;
const varmap_type& GetVar() const;
const valmap_type& GetConst() const;
const QString& GetExpr() const;
const funmap_type& GetFunDef() const;
QString GetVersion(EParserVersionInfo eInfo = pviFULL) const;
const QStringList& GetOprtDef() const;
void DefineNameChars(const QString &a_szCharset);
void DefineOprtChars(const QString &a_szCharset);
void DefineInfixOprtChars(const QString &a_szCharset);
const QString& ValidNameChars() const;
const QString& ValidOprtChars() const;
const QString& ValidInfixOprtChars() const;
void SetArgSep(char_type cArgSep);
QChar GetArgSep() const;
void Error(EErrorCodes a_iErrc, int a_iPos = -1, const QString &a_strTok = QString() ) const;
/**
* @fn void qmu::QmuParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun,
* bool a_bAllowOpt = true)
* @brief Define a parser function without arguments.
* @param a_strName Name of the function
* @param a_pFun Pointer to the callback function
* @param a_bAllowOpt A flag indicating this function may be optimized
*/
template<typename T>
void DefineFun(const QString &a_strName, T a_pFun, bool a_bAllowOpt = true)
{
AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() );
}
protected:
static const QStringList c_DefaultOprt;
static std::locale s_locale; ///< The locale used by the parser
static bool g_DbgDumpCmdCode;
static bool g_DbgDumpStack;
void Init();
virtual void InitCharSets() = 0;
virtual void InitFun() = 0;
virtual void InitConst() = 0;
virtual void InitOprt() = 0;
virtual void OnDetectVar(const QString &pExpr, int &nStart, int &nEnd);
/**
* @brief A facet class used to change decimal and thousands separator.
*/
template<class TChar>
class change_dec_sep : public std::numpunct<TChar>
{
public:
explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3)
:std::numpunct<TChar>(), m_nGroup(nGroup), m_cDecPoint(cDecSep), m_cThousandsSep(cThousandsSep)
{}
protected:
virtual char_type do_decimal_point() const
{
return m_cDecPoint;
}
virtual char_type do_thousands_sep() const
{
return m_cThousandsSep;
}
virtual std::string do_grouping() const
{
return std::string(1, m_nGroup);
}
private:
int m_nGroup;
char_type m_cDecPoint;
char_type m_cThousandsSep;
};
private:
/**
* @brief Typedef for the parse functions.
*
* The parse function do the actual work. The parser exchanges
* the function pointer to the parser function depending on
* which state it is in. (i.e. bytecode parser vs. string parser)
*/
typedef qreal (QmuParserBase::*ParseFunction)() const;
/**
* @brief Type used for storing an array of values.
*/
typedef QVector<qreal> valbuf_type;
/**
* @brief Type for a vector of strings.
*/
typedef QVector<QString> stringbuf_type;
/**
* @brief Typedef for the token reader.
*/
typedef QmuParserTokenReader token_reader_type;
/**
* @brief Type used for parser tokens.
*/
typedef QmuParserToken<qreal, QString> token_type;
/**
* @brief Maximum number of threads spawned by OpenMP when using the bulk mode.
*/
static const int s_MaxNumOpenMPThreads = 4;
/**
* @brief Pointer to the parser function.
*
* Eval() calls the function whose address is stored there.
*/
mutable ParseFunction m_pParseFormula;
mutable QmuParserByteCode m_vRPN; ///< The Bytecode class.
mutable stringbuf_type m_vStringBuf; ///< String buffer, used for storing string function arguments
stringbuf_type m_vStringVarBuf;
std::unique_ptr<token_reader_type> m_pTokenReader; ///< Managed pointer to the token reader object.
funmap_type m_FunDef; ///< Map of function names and pointers.
funmap_type m_PostOprtDef; ///< Postfix operator callbacks
funmap_type m_InfixOprtDef; ///< unary infix operator.
funmap_type m_OprtDef; ///< Binary operator callbacks
valmap_type m_ConstDef; ///< user constants.
strmap_type m_StrVarDef; ///< user defined string constants
varmap_type m_VarDef; ///< user defind variables.
bool m_bBuiltInOp; ///< Flag that can be used for switching built in operators on and off
QString m_sNameChars; ///< Charset for names
QString m_sOprtChars; ///< Charset for postfix/ binary operator tokens
QString m_sInfixOprtChars; ///< Charset for infix operator tokens
mutable int m_nIfElseCounter; ///< Internal counter for keeping track of nested if-then-else clauses
// items merely used for caching state information
mutable valbuf_type m_vStackBuffer; ///< This is merely a buffer used for the stack in the cmd parsing routine
mutable int m_nFinalResultIdx;
void Assign(const QmuParserBase &a_Parser);
void InitTokenReader();
void ReInit() const;
void AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback,
funmap_type &a_Storage, const QString &a_szCharSet );
void ApplyRemainingOprt(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal) const;
void ApplyBinOprt(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal) const;
void ApplyIfElse(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal) const;
void ApplyFunc(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal, int iArgCount) const;
token_type ApplyStrFunc(const token_type &a_FunTok, const QVector<token_type> &a_vArg) const;
int GetOprtPrecedence(const token_type &a_Tok) const;
EOprtAssociativity GetOprtAssociativity(const token_type &a_Tok) const;
void CreateRPN() const;
qreal ParseString() const;
qreal ParseCmdCode() const;
qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const;
void CheckName(const QString &a_strName, const QString &a_CharSet) const;
void CheckOprt(const QString &a_sName, const QmuParserCallback &a_Callback,
const QString &a_szCharSet) const;
void StackDump(const QStack<token_type > &a_stVal, const QStack<token_type > &a_stOprt) const;
};
} // namespace qmu
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,126 +1,124 @@
/***************************************************************************************************
**
** Original work Copyright (C) 2013 Ingo Berg
** Modified work Copyright 2014 Roman Telezhynskyi <dismine(at)gmail.com>
**
** Permission is hereby granted, free of charge, to any person obtaining a copy of this
** software and associated documentation files (the "Software"), to deal in the Software
** without restriction, including without limitation the rights to use, copy, modify,
** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in all copies or
** substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
******************************************************************************************************/
#ifndef QMUPARSERBYTECODE_H
#define QMUPARSERBYTECODE_H
#include "qmuparserdef.h"
#include "qmuparsererror.h"
#include "qmuparsertoken.h"
/**
* @file
* @brief Definition of the parser bytecode class.
*/
namespace qmu
{
struct SToken
{
ECmdCode Cmd;
int StackPos;
union
{
struct //SValData
{
qreal *ptr;
qreal data;
qreal data2;
} Val;
struct //SFunData
{
// Note: generic_fun_type is merely a placeholder. The real type could be
// anything between gun_type1 and fun_type9. I can't use a void
// pointer due to constraints in the ANSI standard which allows
// data pointers and function pointers to differ in size.
generic_fun_type ptr;
int argc;
int idx;
} Fun;
struct //SOprtData
{
qreal *ptr;
int offset;
} Oprt;
};
};
/**
* @brief Bytecode implementation of the Math Parser.
*
* The bytecode contains the formula converted to revers polish notation stored in a continious
* memory area. Associated with this data are operator codes, variable pointers, constant
* values and function pointers. Those are necessary in order to calculate the result.
* All those data items will be casted to the underlying datatype of the bytecode.
*
* @author (C) 2004-2013 Ingo Berg
*/
class QmuParserByteCode
{
private:
/** @brief Token type for internal use only. */
typedef QmuParserToken<qreal, string_type> token_type;
/** @brief Token vector for storing the RPN. */
typedef QVector<SToken> rpn_type;
/** @brief Position in the Calculation array. */
unsigned m_iStackPos;
/** @brief Maximum size needed for the stack. */
std::size_t m_iMaxStackSize;
/** @brief The actual rpn storage. */
rpn_type m_vRPN;
bool m_bEnableOptimizer;
void ConstantFolding(ECmdCode a_Oprt);
public:
QmuParserByteCode();
QmuParserByteCode(const QmuParserByteCode &a_ByteCode);
QmuParserByteCode& operator=(const QmuParserByteCode &a_ByteCode);
void Assign(const QmuParserByteCode &a_ByteCode);
void AddVar(qreal *a_pVar);
void AddVal(qreal a_fVal);
void AddOp(ECmdCode a_Oprt);
void AddIfElse(ECmdCode a_Oprt);
void AddAssignOp(qreal *a_pVar);
void AddFun(generic_fun_type a_pFun, int a_iArgc);
void AddBulkFun(generic_fun_type a_pFun, int a_iArgc);
void AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx);
void EnableOptimizer(bool bStat);
void Finalize();
void clear();
std::size_t GetMaxStackSize() const;
std::size_t GetSize() const;
const SToken* GetBase() const;
void AsciiDump();
};
} // namespace qmu
#endif
/***************************************************************************************************
**
** Original work Copyright (C) 2013 Ingo Berg
** Modified work Copyright 2014 Roman Telezhynskyi <dismine(at)gmail.com>
**
** Permission is hereby granted, free of charge, to any person obtaining a copy of this
** software and associated documentation files (the "Software"), to deal in the Software
** without restriction, including without limitation the rights to use, copy, modify,
** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in all copies or
** substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
******************************************************************************************************/
#ifndef QMUPARSERBYTECODE_H
#define QMUPARSERBYTECODE_H
#include "qmuparserdef.h"
#include "qmuparsererror.h"
#include "qmuparsertoken.h"
/**
* @file
* @brief Definition of the parser bytecode class.
*/
namespace qmu
{
struct SToken
{
ECmdCode Cmd;
int StackPos;
union //
{
struct //SValData
{
qreal *ptr;
qreal data;
qreal data2;
} Val;
struct //SFunData
{
// Note: generic_fun_type is merely a placeholder. The real type could be
// anything between gun_type1 and fun_type9. I can't use a void
// pointer due to constraints in the ANSI standard which allows
// data pointers and function pointers to differ in size.
generic_fun_type ptr;
int argc;
int idx;
} Fun;
struct //SOprtData
{
qreal *ptr;
int offset;
} Oprt;
};
};
/**
* @brief Bytecode implementation of the Math Parser.
*
* The bytecode contains the formula converted to revers polish notation stored in a continious
* memory area. Associated with this data are operator codes, variable pointers, constant
* values and function pointers. Those are necessary in order to calculate the result.
* All those data items will be casted to the underlying datatype of the bytecode.
*
* @author (C) 2004-2013 Ingo Berg
*/
class QmuParserByteCode
{
private:
/** @brief Token type for internal use only. */
typedef QmuParserToken<qreal, string_type> token_type;
/** @brief Token vector for storing the RPN. */
typedef QVector<SToken> rpn_type;
/** @brief Position in the Calculation array. */
unsigned m_iStackPos;
/** @brief Maximum size needed for the stack. */
std::size_t m_iMaxStackSize;
/** @brief The actual rpn storage. */
rpn_type m_vRPN;
bool m_bEnableOptimizer;
void ConstantFolding(ECmdCode a_Oprt);
public:
QmuParserByteCode();
QmuParserByteCode(const QmuParserByteCode &a_ByteCode);
QmuParserByteCode& operator=(const QmuParserByteCode &a_ByteCode);
void Assign(const QmuParserByteCode &a_ByteCode);
void AddVar(qreal *a_pVar);
void AddVal(qreal a_fVal);
void AddOp(ECmdCode a_Oprt);
void AddIfElse(ECmdCode a_Oprt);
void AddAssignOp(qreal *a_pVar);
void AddFun(generic_fun_type a_pFun, int a_iArgc);
void AddBulkFun(generic_fun_type a_pFun, int a_iArgc);
void AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx);
void EnableOptimizer(bool bStat);
void Finalize();
void clear();
std::size_t GetMaxStackSize() const;
std::size_t GetSize() const;
const SToken* GetBase() const;
void AsciiDump();
};
} // namespace qmu
#endif

View file

@ -29,27 +29,27 @@
namespace qmu
{
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
//Supressing specific warnings on gcc/g++ http://www.mr-edd.co.uk/blog/supressing_gcc_warnings
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( fun_type0 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec, ECmdCode a_iCode )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 1 ), m_iPri ( a_iPrec ), m_eOprtAsct ( oaNONE ),
m_iCode ( a_iCode ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 1 ), m_iPri ( a_iPrec ), m_eOprtAsct ( oaNONE ),
m_iCode ( a_iCode ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Constructor for constructing funcstion callbacks taking two arguments.
* @throw nothrow
@ -58,11 +58,11 @@ QmuParserCallback::QmuParserCallback ( fun_type1 a_pFun, bool a_bAllowOpti, int
__extension__
#endif
QmuParserCallback::QmuParserCallback ( fun_type2 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Constructor for constructing binary operator callbacks.
* @param a_pFun Pointer to a static function taking two arguments
@ -75,104 +75,104 @@ QmuParserCallback::QmuParserCallback ( fun_type2 a_pFun, bool a_bAllowOpti )
__extension__
#endif
QmuParserCallback::QmuParserCallback ( fun_type2 a_pFun, bool a_bAllowOpti, int a_iPrec,
EOprtAssociativity a_eOprtAsct )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( a_iPrec ), m_eOprtAsct ( a_eOprtAsct ),
m_iCode ( cmOPRT_BIN ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
EOprtAssociativity a_eOprtAsct )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( a_iPrec ), m_eOprtAsct ( a_eOprtAsct ),
m_iCode ( cmOPRT_BIN ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( fun_type3 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( fun_type4 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( fun_type5 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( fun_type6 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( fun_type7 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( fun_type8 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( fun_type9 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( fun_type10 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( bulkfun_type0 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( bulkfun_type1 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Constructor for constructing funcstion callbacks taking two arguments.
* @throw nothrow
@ -181,156 +181,156 @@ QmuParserCallback::QmuParserCallback ( bulkfun_type1 a_pFun, bool a_bAllowOpti )
__extension__
#endif
QmuParserCallback::QmuParserCallback ( bulkfun_type2 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( bulkfun_type3 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( bulkfun_type4 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( bulkfun_type5 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( bulkfun_type6 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( bulkfun_type7 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( bulkfun_type8 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( bulkfun_type9 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( bulkfun_type10 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( multfun_type a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( -1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( -1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( strfun_type1 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( strfun_type2 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
#ifdef __GNUC__
__extension__
#endif
QmuParserCallback::QmuParserCallback ( strfun_type3 a_pFun, bool a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti )
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Default constructor.
* @throw nothrow
*/
QmuParserCallback::QmuParserCallback()
: m_pFun ( 0 ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmUNKNOWN ), m_iType ( tpVOID ),
m_bAllowOpti ( 0 )
: m_pFun ( 0 ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmUNKNOWN ), m_iType ( tpVOID ),
m_bAllowOpti ( 0 )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Copy constructor.
* @throw nothrow
*/
QmuParserCallback::QmuParserCallback ( const QmuParserCallback &ref )
: m_pFun ( ref.m_pFun ), m_iArgc ( ref.m_iArgc ), m_iPri ( ref.m_iPri ), m_eOprtAsct ( ref.m_eOprtAsct ),
m_iCode ( ref.m_iCode ), m_iType ( ref.m_iType ), m_bAllowOpti ( ref.m_bAllowOpti )
: m_pFun ( ref.m_pFun ), m_iArgc ( ref.m_iArgc ), m_iPri ( ref.m_iPri ), m_eOprtAsct ( ref.m_eOprtAsct ),
m_iCode ( ref.m_iCode ), m_iType ( ref.m_iType ), m_bAllowOpti ( ref.m_bAllowOpti )
{
m_pFun = ref.m_pFun;
m_iArgc = ref.m_iArgc;
m_bAllowOpti = ref.m_bAllowOpti;
m_iCode = ref.m_iCode;
m_iType = ref.m_iType;
m_iPri = ref.m_iPri;
m_eOprtAsct = ref.m_eOprtAsct;
m_pFun = ref.m_pFun;
m_iArgc = ref.m_iArgc;
m_bAllowOpti = ref.m_bAllowOpti;
m_iCode = ref.m_iCode;
m_iType = ref.m_iType;
m_iPri = ref.m_iPri;
m_eOprtAsct = ref.m_eOprtAsct;
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Clone this instance and return a pointer to the new instance.
*/
QmuParserCallback* QmuParserCallback::Clone() const
{
return new QmuParserCallback ( *this );
return new QmuParserCallback ( *this );
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Return tru if the function is conservative.
*
@ -339,10 +339,10 @@ QmuParserCallback* QmuParserCallback::Clone() const
*/
bool QmuParserCallback::IsOptimizable() const
{
return m_bAllowOpti;
return m_bAllowOpti;
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Get the callback address for the parser function.
*
@ -353,25 +353,25 @@ bool QmuParserCallback::IsOptimizable() const
*/
void* QmuParserCallback::GetAddr() const
{
return m_pFun;
return m_pFun;
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Return the callback code.
*/
ECmdCode QmuParserCallback::GetCode() const
{
return m_iCode;
return m_iCode;
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
ETypeCode QmuParserCallback::GetType() const
{
return m_iType;
return m_iType;
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Return the operator precedence.
* @throw nothrown
@ -380,10 +380,10 @@ ETypeCode QmuParserCallback::GetType() const
*/
int QmuParserCallback::GetPri() const
{
return m_iPri;
return m_iPri;
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Return the operators associativity.
* @throw nothrown
@ -392,15 +392,15 @@ int QmuParserCallback::GetPri() const
*/
EOprtAssociativity QmuParserCallback::GetAssociativity() const
{
return m_eOprtAsct;
return m_eOprtAsct;
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Returns the number of function Arguments.
*/
int QmuParserCallback::GetArgc() const
{
return m_iArgc;
return m_iArgc;
}
} // namespace qmu

View file

@ -1,115 +1,114 @@
/***************************************************************************************************
**
** Original work Copyright (C) 2013 Ingo Berg
** Modified work Copyright 2014 Roman Telezhynskyi <dismine(at)gmail.com>
**
** Permission is hereby granted, free of charge, to any person obtaining a copy of this
** software and associated documentation files (the "Software"), to deal in the Software
** without restriction, including without limitation the rights to use, copy, modify,
** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in all copies or
** substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
******************************************************************************************************/
#ifndef QMUPARSERCALLBACK_H
#define QMUPARSERCALLBACK_H
#include "qmuparserdef.h"
/**
* @file
* @brief Definition of the parser callback class.
*/
namespace qmu
{
/**
* @brief Encapsulation of prototypes for a numerical parser function.
*
* Encapsulates the prototyp for numerical parser functions. The class stores the number of arguments for parser
* functions as well as additional flags indication the function is non optimizeable. The pointer to the callback
* function pointer is stored as void* and needs to be casted according to the argument count. Negative argument counts
* indicate a parser function with a variable number of arguments.
*
* @author (C) 2004-2011 Ingo Berg
*/
class QmuParserCallback
{
public:
QmuParserCallback(fun_type0 a_pFun, bool a_bAllowOpti);
QmuParserCallback(fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec = -1, ECmdCode a_iCode=cmFUNC);
QmuParserCallback(fun_type2 a_pFun, bool a_bAllowOpti, int a_iPrec, EOprtAssociativity a_eAssociativity);
QmuParserCallback(fun_type2 a_pFun, bool a_bAllowOpti);
QmuParserCallback(fun_type3 a_pFun, bool a_bAllowOpti);
QmuParserCallback(fun_type4 a_pFun, bool a_bAllowOpti);
QmuParserCallback(fun_type5 a_pFun, bool a_bAllowOpti);
QmuParserCallback(fun_type6 a_pFun, bool a_bAllowOpti);
QmuParserCallback(fun_type7 a_pFun, bool a_bAllowOpti);
QmuParserCallback(fun_type8 a_pFun, bool a_bAllowOpti);
QmuParserCallback(fun_type9 a_pFun, bool a_bAllowOpti);
QmuParserCallback(fun_type10 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type0 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type1 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type2 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type3 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type4 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type5 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type6 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type7 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type8 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type9 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type10 a_pFun, bool a_bAllowOpti);
QmuParserCallback(multfun_type a_pFun, bool a_bAllowOpti);
QmuParserCallback(strfun_type1 a_pFun, bool a_bAllowOpti);
QmuParserCallback(strfun_type2 a_pFun, bool a_bAllowOpti);
QmuParserCallback(strfun_type3 a_pFun, bool a_bAllowOpti);
QmuParserCallback();
QmuParserCallback(const QmuParserCallback &a_Fun);
QmuParserCallback* Clone() const;
bool IsOptimizable() const;
void* GetAddr() const;
ECmdCode GetCode() const;
ETypeCode GetType() const;
int GetPri() const;
EOprtAssociativity GetAssociativity() const;
int GetArgc() const;
private:
void *m_pFun; ///< Pointer to the callback function, casted to void
/**
* @brief Number of numeric function arguments
*
* This number is negative for functions with variable number of arguments. in this cases
* they represent the actual number of arguments found.
*/
int m_iArgc;
int m_iPri; ///< Valid only for binary and infix operators; Operator precedence.
EOprtAssociativity m_eOprtAsct; ///< Operator associativity; Valid only for binary operators
ECmdCode m_iCode;
ETypeCode m_iType;
bool m_bAllowOpti; ///< Flag indication optimizeability
};
//----------------------------------------------------------------------------------------------------------------------
/**
* @brief Container for Callback objects.
*/
typedef std::map<QString, QmuParserCallback> funmap_type;
} // namespace qmu
#endif
/***************************************************************************************************
**
** Original work Copyright (C) 2013 Ingo Berg
** Modified work Copyright 2014 Roman Telezhynskyi <dismine(at)gmail.com>
**
** Permission is hereby granted, free of charge, to any person obtaining a copy of this
** software and associated documentation files (the "Software"), to deal in the Software
** without restriction, including without limitation the rights to use, copy, modify,
** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in all copies or
** substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
******************************************************************************************************/
#ifndef QMUPARSERCALLBACK_H
#define QMUPARSERCALLBACK_H
#include "qmuparserdef.h"
/**
* @file
* @brief Definition of the parser callback class.
*/
namespace qmu
{
/**
* @brief Encapsulation of prototypes for a numerical parser function.
*
* Encapsulates the prototyp for numerical parser functions. The class stores the number of arguments for parser
* functions as well as additional flags indication the function is non optimizeable. The pointer to the callback
* function pointer is stored as void* and needs to be casted according to the argument count. Negative argument counts
* indicate a parser function with a variable number of arguments.
*
* @author (C) 2004-2011 Ingo Berg
*/
class QmuParserCallback
{
public:
QmuParserCallback(fun_type0 a_pFun, bool a_bAllowOpti);
QmuParserCallback(fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec = -1, ECmdCode a_iCode=cmFUNC);
QmuParserCallback(fun_type2 a_pFun, bool a_bAllowOpti, int a_iPrec, EOprtAssociativity a_eAssociativity);
QmuParserCallback(fun_type2 a_pFun, bool a_bAllowOpti);
QmuParserCallback(fun_type3 a_pFun, bool a_bAllowOpti);
QmuParserCallback(fun_type4 a_pFun, bool a_bAllowOpti);
QmuParserCallback(fun_type5 a_pFun, bool a_bAllowOpti);
QmuParserCallback(fun_type6 a_pFun, bool a_bAllowOpti);
QmuParserCallback(fun_type7 a_pFun, bool a_bAllowOpti);
QmuParserCallback(fun_type8 a_pFun, bool a_bAllowOpti);
QmuParserCallback(fun_type9 a_pFun, bool a_bAllowOpti);
QmuParserCallback(fun_type10 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type0 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type1 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type2 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type3 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type4 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type5 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type6 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type7 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type8 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type9 a_pFun, bool a_bAllowOpti);
QmuParserCallback(bulkfun_type10 a_pFun, bool a_bAllowOpti);
QmuParserCallback(multfun_type a_pFun, bool a_bAllowOpti);
QmuParserCallback(strfun_type1 a_pFun, bool a_bAllowOpti);
QmuParserCallback(strfun_type2 a_pFun, bool a_bAllowOpti);
QmuParserCallback(strfun_type3 a_pFun, bool a_bAllowOpti);
QmuParserCallback();
QmuParserCallback(const QmuParserCallback &a_Fun);
QmuParserCallback* Clone() const;
bool IsOptimizable() const;
void* GetAddr() const;
ECmdCode GetCode() const;
ETypeCode GetType() const;
int GetPri() const;
EOprtAssociativity GetAssociativity() const;
int GetArgc() const;
private:
void *m_pFun; ///< Pointer to the callback function, casted to void
/**
* @brief Number of numeric function arguments
*
* This number is negative for functions with variable number of arguments. in this cases
* they represent the actual number of arguments found.
*/
int m_iArgc;
int m_iPri; ///< Valid only for binary and infix operators; Operator precedence.
EOprtAssociativity m_eOprtAsct; ///< Operator associativity; Valid only for binary operators
ECmdCode m_iCode;
ETypeCode m_iType;
bool m_bAllowOpti; ///< Flag indication optimizeability
};
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Container for Callback objects.
*/
typedef std::map<QString, QmuParserCallback> funmap_type;
} // namespace qmu
#endif

View file

@ -47,11 +47,11 @@
//#define QMUP_USE_OPENMP
#if defined(_UNICODE)
/** @brief Definition of the basic parser string type. */
#define QMUP_STRING_TYPE std::wstring
/** @brief Definition of the basic parser string type. */
#define QMUP_STRING_TYPE std::wstring
#else
/** @brief Definition of the basic parser string type. */
#define QMUP_STRING_TYPE std::string
/** @brief Definition of the basic parser string type. */
#define QMUP_STRING_TYPE std::string
#endif
namespace qmu
@ -272,4 +272,3 @@ typedef qreal* ( *facfun_type ) ( const QString &, void* );
} // end of namespace
#endif

View file

@ -28,116 +28,116 @@ namespace qmu
{
const QmuParserErrorMsg QmuParserErrorMsg::m_Instance;
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
const QmuParserErrorMsg& QmuParserErrorMsg::Instance()
{
return m_Instance;
return m_Instance;
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
QString QmuParserErrorMsg::operator[] ( unsigned a_iIdx ) const
{
return ( a_iIdx < static_cast<unsigned>( m_vErrMsg.size() ) ) ? m_vErrMsg[a_iIdx] : QString();
return ( a_iIdx < static_cast<unsigned>( m_vErrMsg.size() ) ) ? m_vErrMsg[a_iIdx] : QString();
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
QmuParserErrorMsg::~QmuParserErrorMsg()
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
QmuParserErrorMsg::QmuParserErrorMsg()
: m_vErrMsg ( 0 )
: m_vErrMsg ( 0 )
{
m_vErrMsg.resize ( ecCOUNT );
m_vErrMsg.resize ( ecCOUNT );
m_vErrMsg[ecUNASSIGNABLE_TOKEN] = "Unexpected token \"$TOK$\" found at position $POS$.";
m_vErrMsg[ecINTERNAL_ERROR] = "Internal error";
m_vErrMsg[ecINVALID_NAME] = "Invalid function-, variable- or constant name: \"$TOK$\".";
m_vErrMsg[ecINVALID_BINOP_IDENT] = "Invalid binary operator identifier: \"$TOK$\".";
m_vErrMsg[ecINVALID_INFIX_IDENT] = "Invalid infix operator identifier: \"$TOK$\".";
m_vErrMsg[ecINVALID_POSTFIX_IDENT] = "Invalid postfix operator identifier: \"$TOK$\".";
m_vErrMsg[ecINVALID_FUN_PTR] = "Invalid pointer to callback function.";
m_vErrMsg[ecEMPTY_EXPRESSION] = "Expression is empty.";
m_vErrMsg[ecINVALID_VAR_PTR] = "Invalid pointer to variable.";
m_vErrMsg[ecUNEXPECTED_OPERATOR] = "Unexpected operator \"$TOK$\" found at position $POS$";
m_vErrMsg[ecUNEXPECTED_EOF] = "Unexpected end of expression at position $POS$";
m_vErrMsg[ecUNEXPECTED_ARG_SEP] = "Unexpected argument separator at position $POS$";
m_vErrMsg[ecUNEXPECTED_PARENS] = "Unexpected parenthesis \"$TOK$\" at position $POS$";
m_vErrMsg[ecUNEXPECTED_FUN] = "Unexpected function \"$TOK$\" at position $POS$";
m_vErrMsg[ecUNEXPECTED_VAL] = "Unexpected value \"$TOK$\" found at position $POS$";
m_vErrMsg[ecUNEXPECTED_VAR] = "Unexpected variable \"$TOK$\" found at position $POS$";
m_vErrMsg[ecUNEXPECTED_ARG] = "Function arguments used without a function (position: $POS$)";
m_vErrMsg[ecMISSING_PARENS] = "Missing parenthesis";
m_vErrMsg[ecTOO_MANY_PARAMS] = "Too many parameters for function \"$TOK$\" at expression position $POS$";
m_vErrMsg[ecTOO_FEW_PARAMS] = "Too few parameters for function \"$TOK$\" at expression position $POS$";
m_vErrMsg[ecDIV_BY_ZERO] = "Divide by zero";
m_vErrMsg[ecDOMAIN_ERROR] = "Domain error";
m_vErrMsg[ecNAME_CONFLICT] = "Name conflict";
m_vErrMsg[ecOPT_PRI] = "Invalid value for operator priority (must be greater or equal to zero).";
m_vErrMsg[ecBUILTIN_OVERLOAD] = "user defined binary operator \"$TOK$\" conflicts with a built in operator.";
m_vErrMsg[ecUNEXPECTED_STR] = "Unexpected string token found at position $POS$.";
m_vErrMsg[ecUNTERMINATED_STRING] = "Unterminated string starting at position $POS$.";
m_vErrMsg[ecSTRING_EXPECTED] = "String function called with a non string type of argument.";
m_vErrMsg[ecVAL_EXPECTED] = "String value used where a numerical argument is expected.";
m_vErrMsg[ecOPRT_TYPE_CONFLICT] = "No suitable overload for operator \"$TOK$\" at position $POS$.";
m_vErrMsg[ecSTR_RESULT] = "Function result is a string.";
m_vErrMsg[ecGENERIC] = "Parser error.";
m_vErrMsg[ecLOCALE] = "Decimal separator is identic to function argument separator.";
m_vErrMsg[ecUNEXPECTED_CONDITIONAL] = "The \"$TOK$\" operator must be preceeded by a closing bracket.";
m_vErrMsg[ecMISSING_ELSE_CLAUSE] = "If-then-else operator is missing an else clause";
m_vErrMsg[ecMISPLACED_COLON] = "Misplaced colon at position $POS$";
m_vErrMsg[ecUNASSIGNABLE_TOKEN] = "Unexpected token \"$TOK$\" found at position $POS$.";
m_vErrMsg[ecINTERNAL_ERROR] = "Internal error";
m_vErrMsg[ecINVALID_NAME] = "Invalid function-, variable- or constant name: \"$TOK$\".";
m_vErrMsg[ecINVALID_BINOP_IDENT] = "Invalid binary operator identifier: \"$TOK$\".";
m_vErrMsg[ecINVALID_INFIX_IDENT] = "Invalid infix operator identifier: \"$TOK$\".";
m_vErrMsg[ecINVALID_POSTFIX_IDENT] = "Invalid postfix operator identifier: \"$TOK$\".";
m_vErrMsg[ecINVALID_FUN_PTR] = "Invalid pointer to callback function.";
m_vErrMsg[ecEMPTY_EXPRESSION] = "Expression is empty.";
m_vErrMsg[ecINVALID_VAR_PTR] = "Invalid pointer to variable.";
m_vErrMsg[ecUNEXPECTED_OPERATOR] = "Unexpected operator \"$TOK$\" found at position $POS$";
m_vErrMsg[ecUNEXPECTED_EOF] = "Unexpected end of expression at position $POS$";
m_vErrMsg[ecUNEXPECTED_ARG_SEP] = "Unexpected argument separator at position $POS$";
m_vErrMsg[ecUNEXPECTED_PARENS] = "Unexpected parenthesis \"$TOK$\" at position $POS$";
m_vErrMsg[ecUNEXPECTED_FUN] = "Unexpected function \"$TOK$\" at position $POS$";
m_vErrMsg[ecUNEXPECTED_VAL] = "Unexpected value \"$TOK$\" found at position $POS$";
m_vErrMsg[ecUNEXPECTED_VAR] = "Unexpected variable \"$TOK$\" found at position $POS$";
m_vErrMsg[ecUNEXPECTED_ARG] = "Function arguments used without a function (position: $POS$)";
m_vErrMsg[ecMISSING_PARENS] = "Missing parenthesis";
m_vErrMsg[ecTOO_MANY_PARAMS] = "Too many parameters for function \"$TOK$\" at expression position $POS$";
m_vErrMsg[ecTOO_FEW_PARAMS] = "Too few parameters for function \"$TOK$\" at expression position $POS$";
m_vErrMsg[ecDIV_BY_ZERO] = "Divide by zero";
m_vErrMsg[ecDOMAIN_ERROR] = "Domain error";
m_vErrMsg[ecNAME_CONFLICT] = "Name conflict";
m_vErrMsg[ecOPT_PRI] = "Invalid value for operator priority (must be greater or equal to zero).";
m_vErrMsg[ecBUILTIN_OVERLOAD] = "user defined binary operator \"$TOK$\" conflicts with a built in operator.";
m_vErrMsg[ecUNEXPECTED_STR] = "Unexpected string token found at position $POS$.";
m_vErrMsg[ecUNTERMINATED_STRING] = "Unterminated string starting at position $POS$.";
m_vErrMsg[ecSTRING_EXPECTED] = "String function called with a non string type of argument.";
m_vErrMsg[ecVAL_EXPECTED] = "String value used where a numerical argument is expected.";
m_vErrMsg[ecOPRT_TYPE_CONFLICT] = "No suitable overload for operator \"$TOK$\" at position $POS$.";
m_vErrMsg[ecSTR_RESULT] = "Function result is a string.";
m_vErrMsg[ecGENERIC] = "Parser error.";
m_vErrMsg[ecLOCALE] = "Decimal separator is identic to function argument separator.";
m_vErrMsg[ecUNEXPECTED_CONDITIONAL] = "The \"$TOK$\" operator must be preceeded by a closing bracket.";
m_vErrMsg[ecMISSING_ELSE_CLAUSE] = "If-then-else operator is missing an else clause";
m_vErrMsg[ecMISPLACED_COLON] = "Misplaced colon at position $POS$";
#if defined(_DEBUG)
for ( int i = 0; i < ecCOUNT; ++i )
{
if ( !m_vErrMsg[i].length() )
{
assert ( false );
}
}
for ( int i = 0; i < ecCOUNT; ++i )
{
if ( m_vErrMsg[i].length() == false)
{
assert ( false );
}
}
#endif
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
//
// QParserError class
//
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Default constructor.
*/
QmuParserError::QmuParserError()
: m_strMsg(), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ),
m_ErrMsg ( QmuParserErrorMsg::Instance() )
: m_strMsg(), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ),
m_ErrMsg ( QmuParserErrorMsg::Instance() )
{
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief This Constructor is used for internal exceptions only.
*
* It does not contain any information but the error code.
*/
QmuParserError::QmuParserError ( EErrorCodes a_iErrc )
: m_strMsg(), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( a_iErrc ),
m_ErrMsg ( QmuParserErrorMsg::Instance() )
: m_strMsg(), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( a_iErrc ),
m_ErrMsg ( QmuParserErrorMsg::Instance() )
{
m_strMsg = m_ErrMsg[m_iErrc];
ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) );
ReplaceSubString ( m_strMsg, "$TOK$", m_strTok );
m_strMsg = m_ErrMsg[m_iErrc];
ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) );
ReplaceSubString ( m_strMsg, "$TOK$", m_strTok );
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Construct an error from a message text.
*/
QmuParserError::QmuParserError ( const QString &sMsg )
: m_strMsg(sMsg), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ),
m_ErrMsg ( QmuParserErrorMsg::Instance() )
: m_strMsg(sMsg), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ),
m_ErrMsg ( QmuParserErrorMsg::Instance() )
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Construct an error object.
* @param [in] a_iErrc the error code.
@ -149,15 +149,15 @@ QmuParserError::QmuParserError ( EErrorCodes iErrc,
const QString &sTok,
const QString &sExpr,
int iPos )
: m_strMsg(), m_strFormula ( sExpr ), m_strTok ( sTok ), m_iPos ( iPos ), m_iErrc ( iErrc ),
m_ErrMsg ( QmuParserErrorMsg::Instance() )
: m_strMsg(), m_strFormula ( sExpr ), m_strTok ( sTok ), m_iPos ( iPos ), m_iErrc ( iErrc ),
m_ErrMsg ( QmuParserErrorMsg::Instance() )
{
m_strMsg = m_ErrMsg[m_iErrc];
ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) );
ReplaceSubString ( m_strMsg, "$TOK$", m_strTok );
m_strMsg = m_ErrMsg[m_iErrc];
ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) );
ReplaceSubString ( m_strMsg, "$TOK$", m_strTok );
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Construct an error object.
* @param [in] iErrc the error code.
@ -165,58 +165,58 @@ QmuParserError::QmuParserError ( EErrorCodes iErrc,
* @param [in] sTok The token string related to this error.
*/
QmuParserError::QmuParserError ( EErrorCodes iErrc, int iPos, const QString &sTok )
: m_strMsg(), m_strFormula(), m_strTok ( sTok ), m_iPos ( iPos ), m_iErrc ( iErrc ),
m_ErrMsg ( QmuParserErrorMsg::Instance() )
: m_strMsg(), m_strFormula(), m_strTok ( sTok ), m_iPos ( iPos ), m_iErrc ( iErrc ),
m_ErrMsg ( QmuParserErrorMsg::Instance() )
{
m_strMsg = m_ErrMsg[m_iErrc];
ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) );
ReplaceSubString ( m_strMsg, "$TOK$", m_strTok );
m_strMsg = m_ErrMsg[m_iErrc];
ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) );
ReplaceSubString ( m_strMsg, "$TOK$", m_strTok );
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/** @brief Construct an error object.
* @param [in] szMsg The error message text.
* @param [in] iPos the position related to the error.
* @param [in] sTok The token string related to this error.
*/
QmuParserError::QmuParserError ( const QString &szMsg, int iPos, const QString &sTok )
: m_strMsg ( szMsg ), m_strFormula(), m_strTok ( sTok ), m_iPos ( iPos ), m_iErrc ( ecGENERIC ),
m_ErrMsg ( QmuParserErrorMsg::Instance() )
: m_strMsg ( szMsg ), m_strFormula(), m_strTok ( sTok ), m_iPos ( iPos ), m_iErrc ( ecGENERIC ),
m_ErrMsg ( QmuParserErrorMsg::Instance() )
{
ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) );
ReplaceSubString ( m_strMsg, "$TOK$", m_strTok );
ReplaceSubString ( m_strMsg, "$POS$", QString().setNum ( m_iPos ) );
ReplaceSubString ( m_strMsg, "$TOK$", m_strTok );
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/** @brief Copy constructor. */
QmuParserError::QmuParserError ( const QmuParserError &a_Obj )
: m_strMsg ( a_Obj.m_strMsg ), m_strFormula ( a_Obj.m_strFormula ), m_strTok ( a_Obj.m_strTok ),
m_iPos ( a_Obj.m_iPos ), m_iErrc ( a_Obj.m_iErrc ), m_ErrMsg ( QmuParserErrorMsg::Instance() )
: m_strMsg ( a_Obj.m_strMsg ), m_strFormula ( a_Obj.m_strFormula ), m_strTok ( a_Obj.m_strTok ),
m_iPos ( a_Obj.m_iPos ), m_iErrc ( a_Obj.m_iErrc ), m_ErrMsg ( QmuParserErrorMsg::Instance() )
{
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/** @brief Assignment operator. */
QmuParserError& QmuParserError::operator= ( const QmuParserError &a_Obj )
{
if ( this == &a_Obj )
{
return *this;
}
if ( this == &a_Obj )
{
return *this;
}
m_strMsg = a_Obj.m_strMsg;
m_strFormula = a_Obj.m_strFormula;
m_strTok = a_Obj.m_strTok;
m_iPos = a_Obj.m_iPos;
m_iErrc = a_Obj.m_iErrc;
return *this;
m_strMsg = a_Obj.m_strMsg;
m_strFormula = a_Obj.m_strFormula;
m_strTok = a_Obj.m_strTok;
m_iPos = a_Obj.m_iPos;
m_iErrc = a_Obj.m_iErrc;
return *this;
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
QmuParserError::~QmuParserError()
{}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Replace all ocuurences of a substring with another string.
* @param strFind The string that shall be replaced.
@ -224,65 +224,67 @@ QmuParserError::~QmuParserError()
*/
void QmuParserError::ReplaceSubString ( QString &strSource, const QString &strFind, const QString &strReplaceWith )
{
QString strResult;
int iPos ( 0 ), iNext ( 0 );
QString strResult;
int iPos ( 0 ), iNext ( 0 );
for ( ;; )
{
iNext = strSource.indexOf ( strFind, iPos );
strResult.append ( strSource.mid ( iPos, iNext - iPos ) );
for ( ;; )
{
iNext = strSource.indexOf ( strFind, iPos );
strResult.append ( strSource.mid ( iPos, iNext - iPos ) );
if ( iNext == -1 )
break;
if ( iNext == -1 )
{
break;
}
strResult.append ( strReplaceWith );
iPos = iNext + strFind.length();
}
strResult.append ( strReplaceWith );
iPos = iNext + strFind.length();
}
strSource.swap ( strResult );
strSource.swap ( strResult );
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Reset the erro object.
*/
void QmuParserError::Reset()
{
m_strMsg.clear();
m_strFormula.clear();
m_strTok.clear();
m_iPos = -1;
m_iErrc = ecUNDEFINED;
m_strMsg.clear();
m_strFormula.clear();
m_strTok.clear();
m_iPos = -1;
m_iErrc = ecUNDEFINED;
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Set the expression related to this error.
*/
void QmuParserError::SetFormula ( const QString &a_strFormula )
{
m_strFormula = a_strFormula;
m_strFormula = a_strFormula;
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief gets the expression related tp this error.
*/
const QString& QmuParserError::GetExpr() const
{
return m_strFormula;
return m_strFormula;
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Returns the message string for this error.
*/
const QString& QmuParserError::GetMsg() const
{
return m_strMsg;
return m_strMsg;
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Return the formula position related to the error.
*
@ -290,24 +292,24 @@ const QString& QmuParserError::GetMsg() const
*/
std::size_t QmuParserError::GetPos() const
{
return m_iPos;
return m_iPos;
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Return string related with this token (if available).
*/
const QString& QmuParserError::GetToken() const
{
return m_strTok;
return m_strTok;
}
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Return the error code.
*/
EErrorCodes QmuParserError::GetCode() const
{
return m_iErrc;
return m_iErrc;
}
} // namespace qmu

View file

@ -97,18 +97,18 @@ enum EErrorCodes
class QmuParserErrorMsg
{
public:
typedef QmuParserErrorMsg self_type;
typedef QmuParserErrorMsg self_type;
QmuParserErrorMsg();
~QmuParserErrorMsg();
QmuParserErrorMsg();
~QmuParserErrorMsg();
static const QmuParserErrorMsg& Instance();
QString operator[] ( unsigned a_iIdx ) const;
static const QmuParserErrorMsg& Instance();
QString operator[] ( unsigned a_iIdx ) const;
private:
Q_DISABLE_COPY(QmuParserErrorMsg)
QVector<QString> m_vErrMsg; ///< A vector with the predefined error messages
static const self_type m_Instance; ///< The instance pointer
Q_DISABLE_COPY(QmuParserErrorMsg)
QVector<QString> m_vErrMsg; ///< A vector with the predefined error messages
static const self_type m_Instance; ///< The instance pointer
};
//---------------------------------------------------------------------------
@ -121,38 +121,37 @@ class QmuParserError
{
public:
QmuParserError();
explicit QmuParserError ( EErrorCodes a_iErrc );
explicit QmuParserError ( const QString &sMsg );
QmuParserError ( EErrorCodes a_iErrc, const QString &sTok, const QString &sFormula = QString(), int a_iPos = -1 );
QmuParserError ( EErrorCodes a_iErrc, int a_iPos, const QString &sTok );
QmuParserError ( const QString &a_szMsg, int a_iPos, const QString &sTok = QString() );
QmuParserError ( const QmuParserError &a_Obj );
QmuParserError& operator= ( const QmuParserError &a_Obj );
~QmuParserError();
QmuParserError();
explicit QmuParserError ( EErrorCodes a_iErrc );
explicit QmuParserError ( const QString &sMsg );
QmuParserError ( EErrorCodes a_iErrc, const QString &sTok, const QString &sFormula = QString(), int a_iPos = -1 );
QmuParserError ( EErrorCodes a_iErrc, int a_iPos, const QString &sTok );
QmuParserError ( const QString &a_szMsg, int a_iPos, const QString &sTok = QString() );
QmuParserError ( const QmuParserError &a_Obj );
QmuParserError& operator= ( const QmuParserError &a_Obj );
~QmuParserError();
void SetFormula ( const QString &a_strFormula );
const QString& GetExpr() const;
const QString& GetMsg() const;
std::size_t GetPos() const;
const QString& GetToken() const;
EErrorCodes GetCode() const;
void SetFormula ( const QString &a_strFormula );
const QString& GetExpr() const;
const QString& GetMsg() const;
std::size_t GetPos() const;
const QString& GetToken() const;
EErrorCodes GetCode() const;
private:
QString m_strMsg; ///< The message string
QString m_strFormula; ///< Formula string
QString m_strTok; ///< Token related with the error
int m_iPos; ///< Formula position related to the error
EErrorCodes m_iErrc; ///< Error code
const QmuParserErrorMsg &m_ErrMsg;
/**
* @brief Replace all ocuurences of a substring with another string.
*/
void ReplaceSubString ( QString &strSource, const QString &strFind, const QString &strReplaceWith );
void Reset();
QString m_strMsg; ///< The message string
QString m_strFormula; ///< Formula string
QString m_strTok; ///< Token related with the error
int m_iPos; ///< Formula position related to the error
EErrorCodes m_iErrc; ///< Error code
const QmuParserErrorMsg &m_ErrMsg;
/**
* @brief Replace all ocuurences of a substring with another string.
*/
void ReplaceSubString ( QString &strSource, const QString &strFind, const QString &strReplaceWith );
void Reset();
};
} // namespace qmu
#endif

View file

@ -1,59 +1,57 @@
/***************************************************************************************************
**
** Original work Copyright (C) 2013 Ingo Berg
** Modified work Copyright 2014 Roman Telezhynskyi <dismine(at)gmail.com>
**
** Permission is hereby granted, free of charge, to any person obtaining a copy of this
** software and associated documentation files (the "Software"), to deal in the Software
** without restriction, including without limitation the rights to use, copy, modify,
** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in all copies or
** substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
******************************************************************************************************/
#ifndef QMUPARSERFIXES_H
#define QMUPARSERFIXES_H
/** @file
@brief This file contains compatibility fixes for some platforms.
*/
//
// Compatibility fixes
//
//---------------------------------------------------------------------------
//
// Intel Compiler
//
//---------------------------------------------------------------------------
#ifdef __INTEL_COMPILER
// remark #981: operands are evaluated in unspecified order
// disabled -> completely pointless if the functions do not have side effects
//
#pragma warning(disable:981)
// remark #383: value copied to temporary, reference to temporary used
#pragma warning(disable:383)
// remark #1572: floating-point equality and inequality comparisons are unreliable
// disabled -> everyone knows it, the parser passes this problem
// deliberately to the user
#pragma warning(disable:1572)
#endif
#endif // include guard
/***************************************************************************************************
**
** Original work Copyright (C) 2013 Ingo Berg
** Modified work Copyright 2014 Roman Telezhynskyi <dismine(at)gmail.com>
**
** Permission is hereby granted, free of charge, to any person obtaining a copy of this
** software and associated documentation files (the "Software"), to deal in the Software
** without restriction, including without limitation the rights to use, copy, modify,
** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in all copies or
** substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
******************************************************************************************************/
#ifndef QMUPARSERFIXES_H
#define QMUPARSERFIXES_H
/** @file
@brief This file contains compatibility fixes for some platforms.
*/
//
// Compatibility fixes
//
//---------------------------------------------------------------------------
//
// Intel Compiler
//
//---------------------------------------------------------------------------
#ifdef __INTEL_COMPILER
// remark #981: operands are evaluated in unspecified order
// disabled -> completely pointless if the functions do not have side effects
//
#pragma warning(disable:981)
// remark #383: value copied to temporary, reference to temporary used
#pragma warning(disable:383)
// remark #1572: floating-point equality and inequality comparisons are unreliable
// disabled -> everyone knows it, the parser passes this problem
// deliberately to the user
#pragma warning(disable:1572)
#endif
#endif // include guard

File diff suppressed because it is too large Load diff

View file

@ -41,7 +41,7 @@ namespace qmu
*/
namespace Test
{
//----------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief Test cases for unit testing.
*
@ -50,253 +50,251 @@ namespace Test
class QmuParserTester // final
{
public:
typedef int ( QmuParserTester::*testfun_type ) ();
typedef int ( QmuParserTester::*testfun_type ) ();
QmuParserTester();
void Run();
QmuParserTester();
void Run();
private:
QVector<testfun_type> m_vTestFun;
static int c_iCount;
QVector<testfun_type> m_vTestFun;
static int c_iCount;
void AddTest ( testfun_type a_pFun );
void AddTest ( testfun_type a_pFun );
// Test Double Parser
int EqnTest ( const QString &a_str, double a_fRes, bool a_fPass );
int EqnTestWithVarChange ( const QString &a_str, double a_fRes1, double a_fVar1, double a_fRes2, double a_fVar2 );
int ThrowTest ( const QString &a_str, int a_iErrc, bool a_bFail = true );
// Test Double Parser
int EqnTest ( const QString &a_str, double a_fRes, bool a_fPass );
int EqnTestWithVarChange ( const QString &a_str, double a_fRes1, double a_fVar1, double a_fRes2, double a_fVar2 );
int ThrowTest ( const QString &a_str, int a_iErrc, bool a_bFail = true );
// Multiarg callbacks
static qreal f1of1 ( qreal v )
{
return v;
}
// Multiarg callbacks
static qreal f1of1 ( qreal v )
{
return v;
}
static qreal f1of2 ( qreal v, qreal )
{
return v;
}
static qreal f1of2 ( qreal v, qreal )
{
return v;
}
static qreal f2of2 ( qreal , qreal v )
{
return v;
}
static qreal f2of2 ( qreal, qreal v )
{
return v;
}
static qreal f1of3 ( qreal v, qreal , qreal )
{
return v;
}
static qreal f1of3 ( qreal v, qreal, qreal )
{
return v;
}
static qreal f2of3 ( qreal , qreal v, qreal )
{
return v;
}
static qreal f2of3 ( qreal, qreal v, qreal )
{
return v;
}
static qreal f3of3 ( qreal , qreal , qreal v )
{
return v;
}
static qreal f3of3 ( qreal, qreal, qreal v )
{
return v;
}
static qreal f1of4 ( qreal v, qreal, qreal , qreal )
{
return v;
}
static qreal f1of4 ( qreal v, qreal, qreal, qreal )
{
return v;
}
static qreal f2of4 ( qreal , qreal v, qreal , qreal )
{
return v;
}
static qreal f2of4 ( qreal, qreal v, qreal, qreal )
{
return v;
}
static qreal f3of4 ( qreal , qreal, qreal v, qreal )
{
return v;
}
static qreal f3of4 ( qreal, qreal, qreal v, qreal )
{
return v;
}
static qreal f4of4 ( qreal , qreal, qreal , qreal v )
{
return v;
}
static qreal f4of4 ( qreal, qreal, qreal, qreal v )
{
return v;
}
static qreal f1of5 ( qreal v, qreal, qreal , qreal , qreal )
{
return v;
}
static qreal f1of5 ( qreal v, qreal, qreal, qreal, qreal )
{
return v;
}
static qreal f2of5 ( qreal , qreal v, qreal , qreal , qreal )
{
return v;
}
static qreal f2of5 ( qreal, qreal v, qreal, qreal, qreal )
{
return v;
}
static qreal f3of5 ( qreal , qreal, qreal v, qreal , qreal )
{
return v;
}
static qreal f3of5 ( qreal, qreal, qreal v, qreal, qreal )
{
return v;
}
static qreal f4of5 ( qreal , qreal, qreal , qreal v, qreal )
{
return v;
}
static qreal f4of5 ( qreal, qreal, qreal, qreal v, qreal )
{
return v;
}
static qreal f5of5 ( qreal , qreal, qreal , qreal , qreal v )
{
return v;
}
static qreal f5of5 ( qreal, qreal, qreal, qreal, qreal v )
{
return v;
}
static qreal Min ( qreal a_fVal1, qreal a_fVal2 )
{
return ( a_fVal1 < a_fVal2 ) ? a_fVal1 : a_fVal2;
}
static qreal Min ( qreal a_fVal1, qreal a_fVal2 )
{
return ( a_fVal1 < a_fVal2 ) ? a_fVal1 : a_fVal2;
}
static qreal Max ( qreal a_fVal1, qreal a_fVal2 )
{
return ( a_fVal1 > a_fVal2 ) ? a_fVal1 : a_fVal2;
}
static qreal Max ( qreal a_fVal1, qreal a_fVal2 )
{
return ( a_fVal1 > a_fVal2 ) ? a_fVal1 : a_fVal2;
}
static qreal plus2 ( qreal v1 )
{
return v1 + 2;
}
static qreal plus2 ( qreal v1 )
{
return v1 + 2;
}
static qreal times3 ( qreal v1 )
{
return v1 * 3;
}
static qreal times3 ( qreal v1 )
{
return v1 * 3;
}
static qreal sqr ( qreal v1 )
{
return v1 * v1;
}
static qreal sqr ( qreal v1 )
{
return v1 * v1;
}
static qreal sign ( qreal v )
{
return -v;
}
static qreal sign ( qreal v )
{
return -v;
}
static qreal add ( qreal v1, qreal v2 )
{
return v1 + v2;
}
static qreal add ( qreal v1, qreal v2 )
{
return v1 + v2;
}
static qreal land ( qreal v1, qreal v2 )
{
return static_cast<int>( v1 ) & static_cast<int>( v2 );
}
static qreal land ( qreal v1, qreal v2 )
{
return static_cast<int>( v1 ) & static_cast<int>( v2 );
}
static qreal FirstArg ( const qreal* a_afArg, int a_iArgc )
{
if ( !a_iArgc )
{
throw qmu::QmuParser::exception_type ( "too few arguments for function FirstArg." );
}
static qreal FirstArg ( const qreal* a_afArg, int a_iArgc )
{
if ( a_iArgc == false)
{
throw qmu::QmuParser::exception_type ( "too few arguments for function FirstArg." );
}
return a_afArg[0];
}
return a_afArg[0];
}
static qreal LastArg ( const qreal* a_afArg, int a_iArgc )
{
if ( !a_iArgc )
{
throw qmu::QmuParser::exception_type ( "too few arguments for function LastArg." );
}
static qreal LastArg ( const qreal* a_afArg, int a_iArgc )
{
if ( a_iArgc == false)
{
throw qmu::QmuParser::exception_type ( "too few arguments for function LastArg." );
}
return a_afArg[a_iArgc - 1];
}
return a_afArg[a_iArgc - 1];
}
static qreal Sum ( const qreal* a_afArg, int a_iArgc )
{
if ( !a_iArgc )
{
throw qmu::QmuParser::exception_type ( "too few arguments for function sum." );
}
static qreal Sum ( const qreal* a_afArg, int a_iArgc )
{
if ( a_iArgc == false)
{
throw qmu::QmuParser::exception_type ( "too few arguments for function sum." );
}
qreal fRes = 0;
for ( int i = 0; i < a_iArgc; ++i )
{
fRes += a_afArg[i];
}
return fRes;
}
qreal fRes = 0;
for ( int i = 0; i < a_iArgc; ++i )
{
fRes += a_afArg[i];
}
return fRes;
}
static qreal Rnd ( qreal v )
{
return static_cast<qreal>( ( 1 + ( v * qrand() / ( RAND_MAX + 1.0 ) ) ) );
}
static qreal Rnd ( qreal v )
{
return static_cast<qreal>( ( 1 + ( v * qrand() / ( RAND_MAX + 1.0 ) ) ) );
}
static qreal RndWithString ( const char_type* )
{
return static_cast<qreal>( ( 1 + ( 1000.0f * static_cast<qreal>(qrand()) / ( RAND_MAX + 1.0 ) ) ) );
}
static qreal RndWithString ( const char_type* )
{
return static_cast<qreal>( ( 1 + ( 1000.0f * static_cast<qreal>(qrand()) / ( RAND_MAX + 1.0 ) ) ) );
}
static qreal Ping()
{
return 10;
}
static qreal Ping()
{
return 10;
}
static qreal ValueOf ( const QString & )
{
return 123;
}
static qreal ValueOf ( const QString & )
{
return 123;
}
static qreal StrFun1 ( const QString & v1 )
{
int val = v1.toInt();
return static_cast<qreal>(val);
}
static qreal StrFun1 ( const QString & v1 )
{
int val = v1.toInt();
return static_cast<qreal>(val);
}
static qreal StrFun2 ( const QString & v1, qreal v2 )
{
int val = v1.toInt();
return static_cast<qreal>( val + v2 );
}
static qreal StrFun2 ( const QString & v1, qreal v2 )
{
int val = v1.toInt();
return static_cast<qreal>( val + v2 );
}
static qreal StrFun3 ( const QString & v1, qreal v2, qreal v3 )
{
int val = v1.toInt();
return val + v2 + v3;
}
static qreal StrFun3 ( const QString & v1, qreal v2, qreal v3 )
{
int val = v1.toInt();
return val + v2 + v3;
}
static qreal StrToFloat ( const QString & a_szMsg )
{
qreal val = a_szMsg.toDouble();
return val;
}
static qreal StrToFloat ( const QString & a_szMsg )
{
qreal val = a_szMsg.toDouble();
return val;
}
// postfix operator callback
static qreal Mega ( qreal a_fVal )
{
return a_fVal * static_cast<qreal>( 1e6 );
}
// postfix operator callback
static qreal Mega ( qreal a_fVal )
{
return a_fVal * static_cast<qreal>( 1e6 );
}
static qreal Micro ( qreal a_fVal )
{
return a_fVal * static_cast<qreal>( 1e-6 );
}
static qreal Micro ( qreal a_fVal )
{
return a_fVal * static_cast<qreal>( 1e-6 );
}
static qreal Milli ( qreal a_fVal )
{
return a_fVal / static_cast<qreal>( 1e3 );
}
static qreal Milli ( qreal a_fVal )
{
return a_fVal / static_cast<qreal>( 1e3 );
}
// Custom value recognition
static int IsHexVal ( const QString &a_szExpr, int *a_iPos, qreal *a_fVal );
// Custom value recognition
static int IsHexVal ( const QString &a_szExpr, int *a_iPos, qreal *a_fVal );
int TestNames();
int TestSyntax();
int TestMultiArg();
int TestPostFix();
int TestExpression();
int TestInfixOprt();
int TestBinOprt();
int TestVarConst();
int TestInterface();
int TestException();
int TestStrArg();
int TestIfThenElse();
int TestNames();
int TestSyntax();
int TestMultiArg();
int TestPostFix();
int TestExpression();
int TestInfixOprt();
int TestBinOprt();
int TestVarConst();
int TestInterface();
int TestException();
int TestStrArg();
int TestIfThenElse();
void Abort() const;
void Abort() const;
};
} // namespace Test
} // namespace qmu
#endif

View file

@ -50,7 +50,7 @@ namespace qmu
* <li>functions with a string as argument</li>
* <li>prefix operators</li>
* <li>infix operators</li>
* <li>binary operator</li>
* <li>binary operator</li>
* </ul>
*
* @author (C) 2004-2013 Ingo Berg
@ -59,458 +59,470 @@ template<typename TBase, typename TString>
class QmuParserToken
{
public:
//---------------------------------------------------------------------------
/**
* @brief Constructor (default).
*
* Sets token to an neutral state of type cmUNKNOWN.
* @throw nothrow
* @sa ECmdCode
*/
QmuParserToken()
: m_iCode ( cmUNKNOWN ), m_iType ( tpVOID ), m_pTok ( 0 ), m_iIdx ( -1 ), m_strTok(), m_strVal(), m_fVal(),
m_pCallback()
{}
//---------------------------------------------------------------------------
/**
* @brief Constructor (default).
*
* Sets token to an neutral state of type cmUNKNOWN.
* @throw nothrow
* @sa ECmdCode
*/
QmuParserToken()
: m_iCode ( cmUNKNOWN ), m_iType ( tpVOID ), m_pTok ( 0 ), m_iIdx ( -1 ), m_strTok(), m_strVal(), m_fVal(),
m_pCallback()
{}
//------------------------------------------------------------------------------
/**
* @brief Create token from another one.
*
* Implemented by calling Assign(...)
* @throw nothrow
* @post m_iType==cmUNKNOWN
* @sa #Assign
*/
QmuParserToken ( const QmuParserToken &a_Tok )
: m_iCode ( a_Tok.m_iCode ), m_iType ( a_Tok.m_iType ), m_pTok ( a_Tok.m_pTok ), m_iIdx ( a_Tok.m_iIdx ),
m_strTok( a_Tok.m_strTok ), m_strVal(a_Tok.m_strVal), m_fVal(a_Tok.m_fVal), m_pCallback()
{
Assign ( a_Tok );
}
//------------------------------------------------------------------------------
/**
* @brief Create token from another one.
*
* Implemented by calling Assign(...)
* @throw nothrow
* @post m_iType==cmUNKNOWN
* @sa #Assign
*/
QmuParserToken ( const QmuParserToken &a_Tok )
: m_iCode ( a_Tok.m_iCode ), m_iType ( a_Tok.m_iType ), m_pTok ( a_Tok.m_pTok ), m_iIdx ( a_Tok.m_iIdx ),
m_strTok( a_Tok.m_strTok ), m_strVal(a_Tok.m_strVal), m_fVal(a_Tok.m_fVal), m_pCallback()
{
Assign ( a_Tok );
}
//------------------------------------------------------------------------------
/**
* @brief Assignement operator.
*
* Copy token state from another token and return this.
* Implemented by calling Assign(...).
* @throw nothrow
*/
QmuParserToken& operator= ( const QmuParserToken &a_Tok )
{
Assign ( a_Tok );
return *this;
}
//------------------------------------------------------------------------------
/**
* @brief Assignement operator.
*
* Copy token state from another token and return this.
* Implemented by calling Assign(...).
* @throw nothrow
*/
QmuParserToken& operator= ( const QmuParserToken &a_Tok )
{
Assign ( a_Tok );
return *this;
}
//------------------------------------------------------------------------------
/**
* @brief Copy token information from argument.
*
* @throw nothrow
*/
void Assign ( const QmuParserToken &a_Tok )
{
m_iCode = a_Tok.m_iCode;
m_pTok = a_Tok.m_pTok;
m_strTok = a_Tok.m_strTok;
m_iIdx = a_Tok.m_iIdx;
m_strVal = a_Tok.m_strVal;
m_iType = a_Tok.m_iType;
m_fVal = a_Tok.m_fVal;
// create new callback object if a_Tok has one
m_pCallback.reset ( a_Tok.m_pCallback.get() ? a_Tok.m_pCallback->Clone() : 0 );
}
//------------------------------------------------------------------------------
/**
* @brief Copy token information from argument.
*
* @throw nothrow
*/
void Assign ( const QmuParserToken &a_Tok )
{
m_iCode = a_Tok.m_iCode;
m_pTok = a_Tok.m_pTok;
m_strTok = a_Tok.m_strTok;
m_iIdx = a_Tok.m_iIdx;
m_strVal = a_Tok.m_strVal;
m_iType = a_Tok.m_iType;
m_fVal = a_Tok.m_fVal;
// create new callback object if a_Tok has one
m_pCallback.reset ( a_Tok.m_pCallback.get() ? a_Tok.m_pCallback->Clone() : 0 );
}
//------------------------------------------------------------------------------
/**
* @brief Assign a token type.
*
* Token may not be of type value, variable or function. Those have seperate set functions.
*
* @pre [assert] a_iType!=cmVAR
* @pre [assert] a_iType!=cmVAL
* @pre [assert] a_iType!=cmFUNC
* @post m_fVal = 0
* @post m_pTok = 0
*/
QmuParserToken& Set ( ECmdCode a_iType, const TString &a_strTok = TString() )
{
// The following types cant be set this way, they have special Set functions
assert ( a_iType != cmVAR );
assert ( a_iType != cmVAL );
assert ( a_iType != cmFUNC );
//------------------------------------------------------------------------------
/**
* @brief Assign a token type.
*
* Token may not be of type value, variable or function. Those have seperate set functions.
*
* @pre [assert] a_iType!=cmVAR
* @pre [assert] a_iType!=cmVAL
* @pre [assert] a_iType!=cmFUNC
* @post m_fVal = 0
* @post m_pTok = 0
*/
QmuParserToken& Set ( ECmdCode a_iType, const TString &a_strTok = TString() )
{
// The following types cant be set this way, they have special Set functions
assert ( a_iType != cmVAR );
assert ( a_iType != cmVAL );
assert ( a_iType != cmFUNC );
m_iCode = a_iType;
m_iType = tpVOID;
m_pTok = 0;
m_strTok = a_strTok;
m_iIdx = -1;
m_iCode = a_iType;
m_iType = tpVOID;
m_pTok = 0;
m_strTok = a_strTok;
m_iIdx = -1;
return *this;
}
return *this;
}
//------------------------------------------------------------------------------
/**
* @brief Set Callback type.
*/
QmuParserToken& Set ( const QmuParserCallback &a_pCallback, const TString &a_sTok )
{
assert ( a_pCallback.GetAddr() );
//------------------------------------------------------------------------------
/**
* @brief Set Callback type.
*/
QmuParserToken& Set ( const QmuParserCallback &a_pCallback, const TString &a_sTok )
{
assert ( a_pCallback.GetAddr() );
m_iCode = a_pCallback.GetCode();
m_iType = tpVOID;
m_strTok = a_sTok;
m_pCallback.reset ( new QmuParserCallback ( a_pCallback ) );
m_iCode = a_pCallback.GetCode();
m_iType = tpVOID;
m_strTok = a_sTok;
m_pCallback.reset ( new QmuParserCallback ( a_pCallback ) );
m_pTok = 0;
m_iIdx = -1;
m_pTok = 0;
m_iIdx = -1;
return *this;
}
return *this;
}
//------------------------------------------------------------------------------
/**
* @brief Make this token a value token.
*
* Member variables not necessary for value tokens will be invalidated.
* @throw nothrow
*/
QmuParserToken& SetVal ( TBase a_fVal, const TString &a_strTok = TString() )
{
m_iCode = cmVAL;
m_iType = tpDBL;
m_fVal = a_fVal;
m_strTok = a_strTok;
m_iIdx = -1;
//------------------------------------------------------------------------------
/**
* @brief Make this token a value token.
*
* Member variables not necessary for value tokens will be invalidated.
* @throw nothrow
*/
QmuParserToken& SetVal ( TBase a_fVal, const TString &a_strTok = TString() )
{
m_iCode = cmVAL;
m_iType = tpDBL;
m_fVal = a_fVal;
m_strTok = a_strTok;
m_iIdx = -1;
m_pTok = 0;
m_pCallback.reset ( 0 );
m_pTok = 0;
m_pCallback.reset ( 0 );
return *this;
}
return *this;
}
//------------------------------------------------------------------------------
/**
* @brief make this token a variable token.
*
* Member variables not necessary for variable tokens will be invalidated.
* @throw nothrow
*/
QmuParserToken& SetVar ( TBase *a_pVar, const TString &a_strTok )
{
m_iCode = cmVAR;
m_iType = tpDBL;
m_strTok = a_strTok;
m_iIdx = -1;
m_pTok = reinterpret_cast<void*> ( a_pVar );
m_pCallback.reset ( 0 );
return *this;
}
//------------------------------------------------------------------------------
/**
* @brief make this token a variable token.
*
* Member variables not necessary for variable tokens will be invalidated.
* @throw nothrow
*/
QmuParserToken& SetVar ( TBase *a_pVar, const TString &a_strTok )
{
m_iCode = cmVAR;
m_iType = tpDBL;
m_strTok = a_strTok;
m_iIdx = -1;
m_pTok = reinterpret_cast<void*> ( a_pVar );
m_pCallback.reset ( 0 );
return *this;
}
//------------------------------------------------------------------------------
/**
* @brief Make this token a variable token.
*
* Member variables not necessary for variable tokens will be invalidated.
* @throw nothrow
*/
QmuParserToken& SetString ( const TString &a_strTok, std::size_t a_iSize )
{
m_iCode = cmSTRING;
m_iType = tpSTR;
m_strTok = a_strTok;
m_iIdx = static_cast<int> ( a_iSize );
//------------------------------------------------------------------------------
/**
* @brief Make this token a variable token.
*
* Member variables not necessary for variable tokens will be invalidated.
* @throw nothrow
*/
QmuParserToken& SetString ( const TString &a_strTok, std::size_t a_iSize )
{
m_iCode = cmSTRING;
m_iType = tpSTR;
m_strTok = a_strTok;
m_iIdx = static_cast<int> ( a_iSize );
m_pTok = 0;
m_pCallback.reset ( 0 );
return *this;
}
m_pTok = 0;
m_pCallback.reset ( 0 );
return *this;
}
//------------------------------------------------------------------------------
/**
* @brief Set an index associated with the token related data.
*
* In cmSTRFUNC - This is the index to a string table in the main parser.
* @param a_iIdx The index the string function result will take in the bytecode parser.
* @throw exception_type if #a_iIdx<0 or #m_iType!=cmSTRING
*/
void SetIdx ( int a_iIdx )
{
if ( m_iCode != cmSTRING || a_iIdx < 0 )
throw QmuParserError ( ecINTERNAL_ERROR );
//------------------------------------------------------------------------------
/**
* @brief Set an index associated with the token related data.
*
* In cmSTRFUNC - This is the index to a string table in the main parser.
* @param a_iIdx The index the string function result will take in the bytecode parser.
* @throw exception_type if #a_iIdx<0 or #m_iType!=cmSTRING
*/
void SetIdx ( int a_iIdx )
{
if ( m_iCode != cmSTRING || a_iIdx < 0 )
{
throw QmuParserError ( ecINTERNAL_ERROR );
}
m_iIdx = a_iIdx;
}
m_iIdx = a_iIdx;
}
//------------------------------------------------------------------------------
/**
* @brief Return Index associated with the token related data.
*
* In cmSTRFUNC - This is the index to a string table in the main parser.
*
* @throw exception_type if #m_iIdx<0 or #m_iType!=cmSTRING
* @return The index the result will take in the Bytecode calculatin array (#m_iIdx).
*/
int GetIdx() const
{
if ( m_iIdx < 0 || m_iCode != cmSTRING )
throw QmuParserError ( ecINTERNAL_ERROR );
//------------------------------------------------------------------------------
/**
* @brief Return Index associated with the token related data.
*
* In cmSTRFUNC - This is the index to a string table in the main parser.
*
* @throw exception_type if #m_iIdx<0 or #m_iType!=cmSTRING
* @return The index the result will take in the Bytecode calculatin array (#m_iIdx).
*/
int GetIdx() const
{
if ( m_iIdx < 0 || m_iCode != cmSTRING )
{
throw QmuParserError ( ecINTERNAL_ERROR );
}
return m_iIdx;
}
return m_iIdx;
}
//------------------------------------------------------------------------------
/**
* @brief Return the token type.
*
* @return #m_iType
* @throw nothrow
*/
ECmdCode GetCode() const
{
if ( m_pCallback.get() )
{
return m_pCallback->GetCode();
}
else
{
return m_iCode;
}
}
//------------------------------------------------------------------------------
/**
* @brief Return the token type.
*
* @return #m_iType
* @throw nothrow
*/
ECmdCode GetCode() const
{
if ( m_pCallback.get() )
{
return m_pCallback->GetCode();
}
else
{
return m_iCode;
}
}
//------------------------------------------------------------------------------
ETypeCode GetType() const
{
if ( m_pCallback.get() )
{
return m_pCallback->GetType();
}
else
{
return m_iType;
}
}
//------------------------------------------------------------------------------
ETypeCode GetType() const
{
if ( m_pCallback.get() )
{
return m_pCallback->GetType();
}
else
{
return m_iType;
}
}
//------------------------------------------------------------------------------
int GetPri() const
{
if ( !m_pCallback.get() )
throw QmuParserError ( ecINTERNAL_ERROR );
//------------------------------------------------------------------------------
int GetPri() const
{
if ( m_pCallback.get() == false)
{
throw QmuParserError ( ecINTERNAL_ERROR );
}
if ( m_pCallback->GetCode() != cmOPRT_BIN && m_pCallback->GetCode() != cmOPRT_INFIX )
throw QmuParserError ( ecINTERNAL_ERROR );
if ( m_pCallback->GetCode() != cmOPRT_BIN && m_pCallback->GetCode() != cmOPRT_INFIX )
{
throw QmuParserError ( ecINTERNAL_ERROR );
}
return m_pCallback->GetPri();
}
return m_pCallback->GetPri();
}
//------------------------------------------------------------------------------
EOprtAssociativity GetAssociativity() const
{
if ( m_pCallback.get() == NULL || m_pCallback->GetCode() != cmOPRT_BIN )
throw QmuParserError ( ecINTERNAL_ERROR );
//------------------------------------------------------------------------------
EOprtAssociativity GetAssociativity() const
{
if ( m_pCallback.get() == NULL || m_pCallback->GetCode() != cmOPRT_BIN )
{
throw QmuParserError ( ecINTERNAL_ERROR );
}
return m_pCallback->GetAssociativity();
}
return m_pCallback->GetAssociativity();
}
//------------------------------------------------------------------------------
/**
* @brief Return the address of the callback function assoziated with function and operator tokens.
*
* @return The pointer stored in #m_pTok.
* @throw exception_type if token type is non of:
* <ul>
* <li>cmFUNC</li>
* <li>cmSTRFUNC</li>
* <li>cmPOSTOP</li>
* <li>cmINFIXOP</li>
* <li>cmOPRT_BIN</li>
* </ul>
* @sa ECmdCode
*/
generic_fun_type GetFuncAddr() const
{
return ( m_pCallback.get() ) ? reinterpret_cast<generic_fun_type> ( m_pCallback->GetAddr() ) :
reinterpret_cast<generic_fun_type> (0);
}
//------------------------------------------------------------------------------
/**
* @brief Return the address of the callback function assoziated with function and operator tokens.
*
* @return The pointer stored in #m_pTok.
* @throw exception_type if token type is non of:
* <ul>
* <li>cmFUNC</li>
* <li>cmSTRFUNC</li>
* <li>cmPOSTOP</li>
* <li>cmINFIXOP</li>
* <li>cmOPRT_BIN</li>
* </ul>
* @sa ECmdCode
*/
generic_fun_type GetFuncAddr() const
{
return ( m_pCallback.get() ) ? reinterpret_cast<generic_fun_type> ( m_pCallback->GetAddr() ) :
reinterpret_cast<generic_fun_type> (0);
}
//------------------------------------------------------------------------------
/**
* @brief Get value of the token.
*
* Only applicable to variable and value tokens.
* @throw exception_type if token is no value/variable token.
*/
TBase GetVal() const
{
switch ( m_iCode )
{
case cmVAL:
return m_fVal;
case cmVAR:
return * ( reinterpret_cast<TBase*>(m_pTok) );
case cmLE:
Q_UNREACHABLE();
break;
case cmGE:
Q_UNREACHABLE();
break;
case cmNEQ:
Q_UNREACHABLE();
break;
case cmEQ:
Q_UNREACHABLE();
break;
case cmLT:
Q_UNREACHABLE();
break;
case cmGT:
Q_UNREACHABLE();
break;
case cmADD:
Q_UNREACHABLE();
break;
case cmSUB:
Q_UNREACHABLE();
break;
case cmMUL:
Q_UNREACHABLE();
break;
case cmDIV:
Q_UNREACHABLE();
break;
case cmPOW:
Q_UNREACHABLE();
break;
case cmLAND:
Q_UNREACHABLE();
break;
case cmLOR:
Q_UNREACHABLE();
break;
case cmASSIGN:
Q_UNREACHABLE();
break;
case cmBO:
Q_UNREACHABLE();
break;
case cmBC:
Q_UNREACHABLE();
break;
case cmIF:
Q_UNREACHABLE();
break;
case cmELSE:
Q_UNREACHABLE();
break;
case cmENDIF:
Q_UNREACHABLE();
break;
case cmARG_SEP:
Q_UNREACHABLE();
break;
case cmVARPOW2:
Q_UNREACHABLE();
break;
case cmVARPOW3:
Q_UNREACHABLE();
break;
case cmVARPOW4:
Q_UNREACHABLE();
break;
case cmVARMUL:
Q_UNREACHABLE();
break;
case cmPOW2:
Q_UNREACHABLE();
break;
case cmFUNC:
Q_UNREACHABLE();
break;
case cmFUNC_STR:
Q_UNREACHABLE();
break;
case cmFUNC_BULK:
Q_UNREACHABLE();
break;
case cmSTRING:
Q_UNREACHABLE();
break;
case cmOPRT_BIN:
Q_UNREACHABLE();
break;
case cmOPRT_POSTFIX:
Q_UNREACHABLE();
break;
case cmOPRT_INFIX:
Q_UNREACHABLE();
break;
case cmEND:
Q_UNREACHABLE();
break;
case cmUNKNOWN:
Q_UNREACHABLE();
break;
default:
throw QmuParserError ( ecVAL_EXPECTED );
}
}
//------------------------------------------------------------------------------
/**
* @brief Get value of the token.
*
* Only applicable to variable and value tokens.
* @throw exception_type if token is no value/variable token.
*/
TBase GetVal() const
{
switch ( m_iCode )
{
case cmVAL:
return m_fVal;
case cmVAR:
return * ( reinterpret_cast<TBase*>(m_pTok) );
case cmLE:
Q_UNREACHABLE();
break;
case cmGE:
Q_UNREACHABLE();
break;
case cmNEQ:
Q_UNREACHABLE();
break;
case cmEQ:
Q_UNREACHABLE();
break;
case cmLT:
Q_UNREACHABLE();
break;
case cmGT:
Q_UNREACHABLE();
break;
case cmADD:
Q_UNREACHABLE();
break;
case cmSUB:
Q_UNREACHABLE();
break;
case cmMUL:
Q_UNREACHABLE();
break;
case cmDIV:
Q_UNREACHABLE();
break;
case cmPOW:
Q_UNREACHABLE();
break;
case cmLAND:
Q_UNREACHABLE();
break;
case cmLOR:
Q_UNREACHABLE();
break;
case cmASSIGN:
Q_UNREACHABLE();
break;
case cmBO:
Q_UNREACHABLE();
break;
case cmBC:
Q_UNREACHABLE();
break;
case cmIF:
Q_UNREACHABLE();
break;
case cmELSE:
Q_UNREACHABLE();
break;
case cmENDIF:
Q_UNREACHABLE();
break;
case cmARG_SEP:
Q_UNREACHABLE();
break;
case cmVARPOW2:
Q_UNREACHABLE();
break;
case cmVARPOW3:
Q_UNREACHABLE();
break;
case cmVARPOW4:
Q_UNREACHABLE();
break;
case cmVARMUL:
Q_UNREACHABLE();
break;
case cmPOW2:
Q_UNREACHABLE();
break;
case cmFUNC:
Q_UNREACHABLE();
break;
case cmFUNC_STR:
Q_UNREACHABLE();
break;
case cmFUNC_BULK:
Q_UNREACHABLE();
break;
case cmSTRING:
Q_UNREACHABLE();
break;
case cmOPRT_BIN:
Q_UNREACHABLE();
break;
case cmOPRT_POSTFIX:
Q_UNREACHABLE();
break;
case cmOPRT_INFIX:
Q_UNREACHABLE();
break;
case cmEND:
Q_UNREACHABLE();
break;
case cmUNKNOWN:
Q_UNREACHABLE();
break;
default:
throw QmuParserError ( ecVAL_EXPECTED );
}
}
//------------------------------------------------------------------------------
/**
* @brief Get address of a variable token.
*
* Valid only if m_iType==CmdVar.
* @throw exception_type if token is no variable token.
*/
TBase* GetVar() const
{
if ( m_iCode != cmVAR )
{
throw QmuParserError ( ecINTERNAL_ERROR );
}
//------------------------------------------------------------------------------
/**
* @brief Get address of a variable token.
*
* Valid only if m_iType==CmdVar.
* @throw exception_type if token is no variable token.
*/
TBase* GetVar() const
{
if ( m_iCode != cmVAR )
{
throw QmuParserError ( ecINTERNAL_ERROR );
}
return reinterpret_cast<TBase*>( m_pTok );
}
return reinterpret_cast<TBase*>( m_pTok );
}
//------------------------------------------------------------------------------
/**
* @brief Return the number of function arguments.
*
* Valid only if m_iType==CmdFUNC.
*/
int GetArgCount() const
{
assert ( m_pCallback.get() );
//------------------------------------------------------------------------------
/**
* @brief Return the number of function arguments.
*
* Valid only if m_iType==CmdFUNC.
*/
int GetArgCount() const
{
assert ( m_pCallback.get() );
if ( !m_pCallback->GetAddr() )
throw QmuParserError ( ecINTERNAL_ERROR );
if ( m_pCallback->GetAddr() == false)
{
throw QmuParserError ( ecINTERNAL_ERROR );
}
return m_pCallback->GetArgc();
}
return m_pCallback->GetArgc();
}
//------------------------------------------------------------------------------
/**
* @brief Return the token identifier.
*
* If #m_iType is cmSTRING the token identifier is the value of the string argument
* for a string function.
* @return #m_strTok
* @throw nothrow
* @sa m_strTok
*/
const TString& GetAsString() const
{
return m_strTok;
}
//------------------------------------------------------------------------------
/**
* @brief Return the token identifier.
*
* If #m_iType is cmSTRING the token identifier is the value of the string argument
* for a string function.
* @return #m_strTok
* @throw nothrow
* @sa m_strTok
*/
const TString& GetAsString() const
{
return m_strTok;
}
private:
ECmdCode m_iCode; ///< Type of the token; The token type is a constant of type #ECmdCode.
ETypeCode m_iType;
void *m_pTok; ///< Stores Token pointer; not applicable for all tokens
int m_iIdx; ///< An otional index to an external buffer storing the token data
TString m_strTok; ///< Token string
TString m_strVal; ///< Value for string variables
qreal m_fVal; ///< the value
std::unique_ptr<QmuParserCallback> m_pCallback;
ECmdCode m_iCode; ///< Type of the token; The token type is a constant of type #ECmdCode.
ETypeCode m_iType;
void *m_pTok; ///< Stores Token pointer; not applicable for all tokens
int m_iIdx; ///< An otional index to an external buffer storing the token data
TString m_strTok; ///< Token string
TString m_strVal; ///< Value for string variables
qreal m_fVal; ///< the value
std::unique_ptr<QmuParserCallback> m_pCallback;
};
} // namespace qmu

File diff suppressed because it is too large Load diff

View file

@ -1,156 +1,154 @@
/***************************************************************************************************
**
** Original work Copyright (C) 2013 Ingo Berg
** Modified work Copyright 2014 Roman Telezhynskyi <dismine(at)gmail.com>
**
** Permission is hereby granted, free of charge, to any person obtaining a copy of this
** software and associated documentation files (the "Software"), to deal in the Software
** without restriction, including without limitation the rights to use, copy, modify,
** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in all copies or
** substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
******************************************************************************************************/
#ifndef QMUPARSERTOKENREADER_H
#define QMUPARSERTOKENREADER_H
#include <cassert>
#include <cstdio>
#include <cstring>
#include <list>
#include <map>
#include <memory>
#include <stack>
#include <string>
#include "qmuparserdef.h"
#include "qmuparsertoken.h"
/** @file
@brief This file contains the parser token reader definition.
*/
namespace qmu
{
// Forward declaration
class QmuParserBase;
/** @brief Token reader for the ParserBase class.
*/
class QmuParserTokenReader
{
private:
typedef QmuParserToken<qreal, QString> token_type;
public:
QmuParserTokenReader(QmuParserBase *a_pParent);
QmuParserTokenReader* Clone(QmuParserBase *a_pParent) const;
void AddValIdent(identfun_type a_pCallback);
void SetVarCreator(facfun_type a_pFactory, void *pUserData);
void SetFormula(const QString &a_strFormula);
void SetArgSep(char_type cArgSep);
int GetPos() const;
const QString &GetExpr() const;
varmap_type& GetUsedVar();
QChar GetArgSep() const;
void IgnoreUndefVar(bool bIgnore);
void ReInit();
token_type ReadNextToken();
private:
/** @brief Syntax codes.
The syntax codes control the syntax check done during the first time parsing of
the expression string. They are flags that indicate which tokens are allowed next
if certain tokens are identified.
*/
enum ESynCodes
{
noBO = 1 << 0, ///< to avoid i.e. "cos(7)("
noBC = 1 << 1, ///< to avoid i.e. "sin)" or "()"
noVAL = 1 << 2, ///< to avoid i.e. "tan 2" or "sin(8)3.14"
noVAR = 1 << 3, ///< to avoid i.e. "sin a" or "sin(8)a"
noARG_SEP = 1 << 4, ///< to avoid i.e. ",," or "+," ...
noFUN = 1 << 5, ///< to avoid i.e. "sqrt cos" or "(1)sin"
noOPT = 1 << 6, ///< to avoid i.e. "(+)"
noPOSTOP = 1 << 7, ///< to avoid i.e. "(5!!)" "sin!"
noINFIXOP = 1 << 8, ///< to avoid i.e. "++4" "!!4"
noEND = 1 << 9, ///< to avoid unexpected end of formula
noSTR = 1 << 10, ///< to block numeric arguments on string functions
noASSIGN = 1 << 11, ///< to block assignement to constant i.e. "4=7"
noIF = 1 << 12,
noELSE = 1 << 13,
sfSTART_OF_LINE = noOPT | noBC | noPOSTOP | noASSIGN | noIF | noELSE | noARG_SEP,
noANY = ~0 ///< All of he above flags set
};
QmuParserTokenReader(const QmuParserTokenReader &a_Reader);
QmuParserTokenReader& operator=(const QmuParserTokenReader &a_Reader);
void Assign(const QmuParserTokenReader &a_Reader);
void SetParent(QmuParserBase *a_pParent);
int ExtractToken(const QString &a_szCharSet, QString &a_strTok, int a_iPos) const;
int ExtractOperatorToken(QString &a_sTok, int a_iPos) const;
bool IsBuiltIn(token_type &a_Tok);
bool IsArgSep(token_type &a_Tok);
bool IsEOF(token_type &a_Tok);
bool IsInfixOpTok(token_type &a_Tok);
bool IsFunTok(token_type &a_Tok);
bool IsPostOpTok(token_type &a_Tok);
bool IsOprt(token_type &a_Tok);
bool IsValTok(token_type &a_Tok);
bool IsVarTok(token_type &a_Tok);
bool IsStrVarTok(token_type &a_Tok);
bool IsUndefVarTok(token_type &a_Tok);
bool IsString(token_type &a_Tok);
void Error(EErrorCodes a_iErrc,
int a_iPos = -1,
const QString &a_sTok = QString() ) const;
token_type& SaveBeforeReturn(const token_type &tok);
QmuParserBase *m_pParser;
QString m_strFormula;
int m_iPos;
int m_iSynFlags;
bool m_bIgnoreUndefVar;
const funmap_type *m_pFunDef;
const funmap_type *m_pPostOprtDef;
const funmap_type *m_pInfixOprtDef;
const funmap_type *m_pOprtDef;
const valmap_type *m_pConstDef;
const strmap_type *m_pStrVarDef;
varmap_type *m_pVarDef; ///< The only non const pointer to parser internals
facfun_type m_pFactory;
void *m_pFactoryData;
std::list<identfun_type> m_vIdentFun; ///< Value token identification function
varmap_type m_UsedVar;
qreal m_fZero; ///< Dummy value of zero, referenced by undefined variables
int m_iBrackets;
token_type m_lastTok;
QChar m_cArgSep; ///< The character used for separating function arguments
};
} // namespace qmu
#endif
/***************************************************************************************************
**
** Original work Copyright (C) 2013 Ingo Berg
** Modified work Copyright 2014 Roman Telezhynskyi <dismine(at)gmail.com>
**
** Permission is hereby granted, free of charge, to any person obtaining a copy of this
** software and associated documentation files (the "Software"), to deal in the Software
** without restriction, including without limitation the rights to use, copy, modify,
** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in all copies or
** substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
******************************************************************************************************/
#ifndef QMUPARSERTOKENREADER_H
#define QMUPARSERTOKENREADER_H
#include <cassert>
#include <cstdio>
#include <cstring>
#include <list>
#include <map>
#include <memory>
#include <stack>
#include <string>
#include "qmuparserdef.h"
#include "qmuparsertoken.h"
/** @file
@brief This file contains the parser token reader definition.
*/
namespace qmu
{
// Forward declaration
class QmuParserBase;
/** @brief Token reader for the ParserBase class.
*/
class QmuParserTokenReader
{
private:
typedef QmuParserToken<qreal, QString> token_type;
public:
QmuParserTokenReader(QmuParserBase *a_pParent);
QmuParserTokenReader* Clone(QmuParserBase *a_pParent) const;
void AddValIdent(identfun_type a_pCallback);
void SetVarCreator(facfun_type a_pFactory, void *pUserData);
void SetFormula(const QString &a_strFormula);
void SetArgSep(char_type cArgSep);
int GetPos() const;
const QString &GetExpr() const;
varmap_type& GetUsedVar();
QChar GetArgSep() const;
void IgnoreUndefVar(bool bIgnore);
void ReInit();
token_type ReadNextToken();
private:
/**
* @brief Syntax codes.
*
* The syntax codes control the syntax check done during the first time parsing of
* the expression string. They are flags that indicate which tokens are allowed next
* if certain tokens are identified.
*/
enum ESynCodes
{
noBO = 1 << 0, ///< to avoid i.e. "cos(7)("
noBC = 1 << 1, ///< to avoid i.e. "sin)" or "()"
noVAL = 1 << 2, ///< to avoid i.e. "tan 2" or "sin(8)3.14"
noVAR = 1 << 3, ///< to avoid i.e. "sin a" or "sin(8)a"
noARG_SEP = 1 << 4, ///< to avoid i.e. ",," or "+," ...
noFUN = 1 << 5, ///< to avoid i.e. "sqrt cos" or "(1)sin"
noOPT = 1 << 6, ///< to avoid i.e. "(+)"
noPOSTOP = 1 << 7, ///< to avoid i.e. "(5!!)" "sin!"
noINFIXOP = 1 << 8, ///< to avoid i.e. "++4" "!!4"
noEND = 1 << 9, ///< to avoid unexpected end of formula
noSTR = 1 << 10, ///< to block numeric arguments on string functions
noASSIGN = 1 << 11, ///< to block assignement to constant i.e. "4=7"
noIF = 1 << 12,
noELSE = 1 << 13,
sfSTART_OF_LINE = noOPT | noBC | noPOSTOP | noASSIGN | noIF | noELSE | noARG_SEP,
noANY = ~0 ///< All of he above flags set
};
QmuParserTokenReader(const QmuParserTokenReader &a_Reader);
QmuParserTokenReader& operator=(const QmuParserTokenReader &a_Reader);
void Assign(const QmuParserTokenReader &a_Reader);
void SetParent(QmuParserBase *a_pParent);
int ExtractToken(const QString &a_szCharSet, QString &a_strTok, int a_iPos) const;
int ExtractOperatorToken(QString &a_sTok, int a_iPos) const;
bool IsBuiltIn(token_type &a_Tok);
bool IsArgSep(token_type &a_Tok);
bool IsEOF(token_type &a_Tok);
bool IsInfixOpTok(token_type &a_Tok);
bool IsFunTok(token_type &a_Tok);
bool IsPostOpTok(token_type &a_Tok);
bool IsOprt(token_type &a_Tok);
bool IsValTok(token_type &a_Tok);
bool IsVarTok(token_type &a_Tok);
bool IsStrVarTok(token_type &a_Tok);
bool IsUndefVarTok(token_type &a_Tok);
bool IsString(token_type &a_Tok);
void Error(EErrorCodes a_iErrc,
int a_iPos = -1,
const QString &a_sTok = QString() ) const;
token_type& SaveBeforeReturn(const token_type &tok);
QmuParserBase *m_pParser;
QString m_strFormula;
int m_iPos;
int m_iSynFlags;
bool m_bIgnoreUndefVar;
const funmap_type *m_pFunDef;
const funmap_type *m_pPostOprtDef;
const funmap_type *m_pInfixOprtDef;
const funmap_type *m_pOprtDef;
const valmap_type *m_pConstDef;
const strmap_type *m_pStrVarDef;
varmap_type *m_pVarDef; ///< The only non const pointer to parser internals
facfun_type m_pFactory;
void *m_pFactoryData;
std::list<identfun_type> m_vIdentFun; ///< Value token identification function
varmap_type m_UsedVar;
qreal m_fZero; ///< Dummy value of zero, referenced by undefined variables
int m_iBrackets;
token_type m_lastTok;
QChar m_cArgSep; ///< The character used for separating function arguments
};
} // namespace qmu
#endif