Files
simgear/simgear/structure/SGExpression.cxx
T
timoore 9861d74221 Fixes for compiling with gcc 4.3
Include standard header files and qualify with std:: where needed.

Add "const" to various char parameters and variables.
2008-04-13 21:11:44 +00:00

640 lines
20 KiB
C++

/* -*-c++-*-
*
* Copyright (C) 2006-2007 Mathias Froehlich
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include "SGExpression.hxx"
#include <string>
#include <sstream>
#include <simgear/props/props.hxx>
template<typename T>
static bool
SGReadValueFromString(const char* str, T& value)
{
if (!str) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
return false;
}
std::stringstream s;
s.str(std::string(str));
s >> value;
if (s.fail()) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
return false;
}
return true;
}
template<>
bool
SGReadValueFromString(const char* str, bool& value)
{
if (!str) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read string content.");
return false;
}
std::stringstream s;
s.str(std::string(str));
s >> value;
if (!s.fail())
return true;
std::string stdstr;
if (!SGReadValueFromString(str, stdstr))
return false;
if (stdstr == "true" || stdstr == "True" || stdstr == "TRUE") {
value = true;
return true;
}
if (stdstr == "false" || stdstr == "False" || stdstr == "FALSE") {
value = true;
return true;
}
return false;
}
template<typename T>
static bool
SGReadValueFromContent(const SGPropertyNode *node, T& value)
{
if (!node)
return false;
return SGReadValueFromString(node->getStringValue(), value);
}
template<typename T>
static SGExpression<T>*
SGReadIExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression);
template<typename T>
static bool
SGReadNaryOperands(SGNaryExpression<T>* nary,
SGPropertyNode *inputRoot, const SGPropertyNode *expression)
{
for (int i = 0; i < expression->nChildren(); ++i) {
SGExpression<T>* inputExpression;
inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(i));
if (!inputExpression)
return false;
nary->addOperand(inputExpression);
}
return true;
}
// template<typename T>
// static SGExpression<T>*
// SGReadBExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
// {
// if (!expression)
// return 0;
// std::string name = expression->getName();
// if (name == "value") {
// T value;
// if (!SGReadValueFromContent(expression, value)) {
// SG_LOG(SG_IO, SG_ALERT, "Cannot read \"value\" expression.");
// return 0;
// }
// return new SGConstExpression<T>(value);
// }
// return 0;
// }
template<typename T>
static SGExpression<T>*
SGReadIExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
{
if (!expression)
return 0;
std::string name = expression->getName();
if (name == "value") {
T value;
if (!SGReadValueFromContent(expression, value)) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"value\" expression.");
return 0;
}
return new SGConstExpression<T>(value);
}
if (name == "property") {
if (!inputRoot) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.\n"
"No inputRoot argument given!");
return 0;
}
if (!expression->getStringValue()) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGPropertyNode* inputNode;
inputNode = inputRoot->getNode(expression->getStringValue(), true);
return new SGPropertyExpression<T>(inputNode);
}
if (name == "abs" || name == "fabs") {
if (expression->nChildren() != 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpression;
inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(0));
if (!inputExpression) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGAbsExpression<T>(inputExpression);
}
if (name == "sqr") {
if (expression->nChildren() != 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpression;
inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(0));
if (!inputExpression) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGSqrExpression<T>(inputExpression);
}
if (name == "clip") {
if (expression->nChildren() != 3) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
const SGPropertyNode* minProperty = expression->getChild("clipMin");
T clipMin;
if (!SGReadValueFromContent(minProperty, clipMin))
clipMin = SGMisc<T>::min(SGLimits<T>::min(), -SGLimits<T>::max());
const SGPropertyNode* maxProperty = expression->getChild("clipMax");
T clipMax;
if (!SGReadValueFromContent(maxProperty, clipMax))
clipMin = SGLimits<T>::max();
SGSharedPtr<SGExpression<T> > inputExpression;
for (int i = 0; !inputExpression && i < expression->nChildren(); ++i)
inputExpression = SGReadIExpression<T>(inputRoot, expression->getChild(i));
if (!inputExpression) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGClipExpression<T>(inputExpression, clipMin, clipMax);
}
if (name == "div") {
if (expression->nChildren() != 2) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
SGReadIExpression<T>(inputRoot, expression->getChild(0)),
SGReadIExpression<T>(inputRoot, expression->getChild(1))
};
if (!inputExpressions[0] || !inputExpressions[1]) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
}
if (name == "mod") {
if (expression->nChildren() != 2) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
SGReadIExpression<T>(inputRoot, expression->getChild(0)),
SGReadIExpression<T>(inputRoot, expression->getChild(1))
};
if (!inputExpressions[0] || !inputExpressions[1]) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
}
if (name == "sum") {
if (expression->nChildren() < 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSumExpression<T>* output = new SGSumExpression<T>;
if (!SGReadNaryOperands(output, inputRoot, expression)) {
delete output;
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return output;
}
if (name == "prod" || name == "product") {
if (expression->nChildren() < 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGProductExpression<T>* output = new SGProductExpression<T>;
if (!SGReadNaryOperands(output, inputRoot, expression)) {
delete output;
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return output;
}
if (name == "min") {
if (expression->nChildren() < 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGMinExpression<T>* output = new SGMinExpression<T>;
if (!SGReadNaryOperands(output, inputRoot, expression)) {
delete output;
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return output;
}
if (name == "max") {
if (expression->nChildren() < 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGMaxExpression<T>* output = new SGMaxExpression<T>;
if (!SGReadNaryOperands(output, inputRoot, expression)) {
delete output;
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return output;
}
return 0;
}
template<typename T>
static SGExpression<T>*
SGReadFExpression(SGPropertyNode *inputRoot, const SGPropertyNode *expression)
{
SGExpression<T>* r = SGReadIExpression<T>(inputRoot, expression);
if (r)
return r;
if (!expression)
return 0;
std::string name = expression->getName();
if (name == "acos") {
if (expression->nChildren() != 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpression;
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
if (!inputExpression) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGACosExpression<T>(inputExpression);
}
if (name == "asin") {
if (expression->nChildren() != 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpression;
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
if (!inputExpression) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGASinExpression<T>(inputExpression);
}
if (name == "atan") {
if (expression->nChildren() != 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpression;
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
if (!inputExpression) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGATanExpression<T>(inputExpression);
}
if (name == "ceil") {
if (expression->nChildren() != 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpression;
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
if (!inputExpression) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGCeilExpression<T>(inputExpression);
}
if (name == "cos") {
if (expression->nChildren() != 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpression;
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
if (!inputExpression) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGCosExpression<T>(inputExpression);
}
if (name == "cosh") {
if (expression->nChildren() != 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpression;
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
if (!inputExpression) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGCoshExpression<T>(inputExpression);
}
if (name == "deg2rad") {
if (expression->nChildren() != 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpression;
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
if (!inputExpression) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGScaleExpression<T>(inputExpression, SGMisc<T>::pi()/180);
}
if (name == "exp") {
if (expression->nChildren() != 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpression;
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
if (!inputExpression) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGExpExpression<T>(inputExpression);
}
if (name == "floor") {
if (expression->nChildren() != 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpression;
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
if (!inputExpression) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGFloorExpression<T>(inputExpression);
}
if (name == "log") {
if (expression->nChildren() != 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpression;
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
if (!inputExpression) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGLogExpression<T>(inputExpression);
}
if (name == "log10") {
if (expression->nChildren() != 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpression;
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
if (!inputExpression) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGLog10Expression<T>(inputExpression);
}
if (name == "rad2deg") {
if (expression->nChildren() != 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpression;
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
if (!inputExpression) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGScaleExpression<T>(inputExpression, 180/SGMisc<T>::pi());
}
if (name == "sin") {
if (expression->nChildren() != 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpression;
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
if (!inputExpression) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGSinExpression<T>(inputExpression);
}
if (name == "sinh") {
if (expression->nChildren() != 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpression;
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
if (!inputExpression) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGSinhExpression<T>(inputExpression);
}
if (name == "sqrt") {
if (expression->nChildren() != 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpression;
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
if (!inputExpression) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGSqrtExpression<T>(inputExpression);
}
if (name == "tan") {
if (expression->nChildren() != 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpression;
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
if (!inputExpression) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGTanExpression<T>(inputExpression);
}
if (name == "tanh") {
if (expression->nChildren() != 1) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpression;
inputExpression = SGReadFExpression<T>(inputRoot, expression->getChild(0));
if (!inputExpression) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGTanhExpression<T>(inputExpression);
}
// if (name == "table") {
// }
// if (name == "step") {
// }
// if (name == "condition") {
// }
if (name == "atan2") {
if (expression->nChildren() != 2) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
SGReadFExpression<T>(inputRoot, expression->getChild(0)),
SGReadFExpression<T>(inputRoot, expression->getChild(1))
};
if (!inputExpressions[0] || !inputExpressions[1]) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGAtan2Expression<T>(inputExpressions[0], inputExpressions[1]);
}
if (name == "div") {
if (expression->nChildren() != 2) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
SGReadFExpression<T>(inputRoot, expression->getChild(0)),
SGReadFExpression<T>(inputRoot, expression->getChild(1))
};
if (!inputExpressions[0] || !inputExpressions[1]) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGDivExpression<T>(inputExpressions[0], inputExpressions[1]);
}
if (name == "mod") {
if (expression->nChildren() != 2) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
SGReadFExpression<T>(inputRoot, expression->getChild(0)),
SGReadFExpression<T>(inputRoot, expression->getChild(1))
};
if (!inputExpressions[0] || !inputExpressions[1]) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGModExpression<T>(inputExpressions[0], inputExpressions[1]);
}
if (name == "pow") {
if (expression->nChildren() != 2) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
SGSharedPtr<SGExpression<T> > inputExpressions[2] = {
SGReadIExpression<T>(inputRoot, expression->getChild(0)),
SGReadIExpression<T>(inputRoot, expression->getChild(1))
};
if (!inputExpressions[0] || !inputExpressions[1]) {
SG_LOG(SG_IO, SG_ALERT, "Cannot read \"" << name << "\" expression.");
return 0;
}
return new SGPowExpression<T>(inputExpressions[0], inputExpressions[1]);
}
return 0;
}
SGExpression<int>*
SGReadIntExpression(SGPropertyNode *inputRoot,
const SGPropertyNode *configNode)
{ return SGReadIExpression<int>(inputRoot, configNode); }
SGExpression<float>*
SGReadFloatExpression(SGPropertyNode *inputRoot,
const SGPropertyNode *configNode)
{ return SGReadFExpression<float>(inputRoot, configNode); }
SGExpression<double>*
SGReadDoubleExpression(SGPropertyNode *inputRoot,
const SGPropertyNode *configNode)
{ return SGReadFExpression<double>(inputRoot, configNode); }
// SGExpression<bool>*
// SGReadBoolExpression(SGPropertyNode *inputRoot,
// const SGPropertyNode *configNode)
// { return SGReadBExpression<bool>(inputRoot, configNode); }