+++ /dev/null
-#include "parser.h"
-
-#include <QDebug>
-#include <QRegExp>
-#include <iostream>
-
-#include "command.h"
-#include "treeitem.h"
-
-extern QList <Command*> modelCommands;
-
-Parser::Parser()
-{
- initParser();
-}
-
-void Parser::initParser()
-{
- initAtom();
- current=-1;
-}
-
-void Parser::initAtom()
-{
- atom="";
- com="";
- paramList.clear();
- errLevel=NoError;
- errDescription="";
- errMessage="";
-}
-
-void Parser::parseAtom (QString s)
-{
- initAtom();
- QRegExp re;
- int pos;
-
- // Strip WS at beginning
- while (s.length() > 0 && (
- s.at(0) == '\n' ||
- s.at(0) == '\r' ||
- s.at(0) == ' ') )
- s = s.mid(1);
- if (s.length() == 0)
- return;
-
- // Get command
- re.setPattern ("^(\\w*)");
- pos=re.indexIn (s);
- if (pos>=0)
- com=re.cap(1);
-
- // Get parameters
- paramList.clear();
- QString t;
- int leftParenthesis;
- int rightParenthesis;
- if (!nextParenthesisContents(s, leftParenthesis, rightParenthesis, t)) return;
-
- paramList = findParameters(t);
- atom = s;
-}
-
-QString Parser::getAtom()
-{
- return atom;
-}
-
-QString Parser::getCommand()
-{
- return com;
-}
-
-QStringList Parser::getParameters()
-{
- return paramList;
-}
-
-int Parser::parCount()
-{
- return paramList.count();
-}
-
-QString Parser::errorMessage()
-{
- QString l;
- switch (errLevel)
- {
- case NoError: l="No Error"; break;
- case Warning: l="Warning"; break;
- case Aborted: l="Aborted"; break;
- default: l="";
- }
- return QString ("Error Level: '%1' Command: '%2' Description: '%3'")
- .arg(l).arg(com).arg(errDescription);
-}
-
-QString Parser::errorDescription()
-{
- return errDescription;
-}
-
-ErrorLevel Parser::errorLevel()
-{
- return errLevel;
-}
-
-void Parser::setError(ErrorLevel level, const QString &description)
-{
- errDescription=description;
- errLevel=level;
-}
-
-bool Parser::checkParameters(TreeItem *selti)
-{
- foreach (Command *c, modelCommands)
- {
- if (c->getName() == com)
- {
- // Check type of selection
- if (selti)
- {
- bool ok;
- ok=false;
- TreeItem::Type st=selti->getType();
- Command::SelectionType ct=c->getSelectionType();
- if (ct==Command::TreeItem || ct==Command::BranchOrImage)
- {
- if (st==TreeItem::MapCenter ||
- st==TreeItem::Branch ||
- st==TreeItem::XLink ||
- st==TreeItem::Image )
- ok=true;
- } else if ( ct==Command::BranchOrImage )
- {
- if (st==TreeItem::MapCenter ||
- st==TreeItem::Branch ||
- st==TreeItem::Image )
- ok=true;
- } else if ( ct==Command::Branch || ct==Command::BranchLike)
- {
-
- if (st == TreeItem::MapCenter ||
- st == TreeItem::Branch )
- ok=true;
- } else if ( ct==Command::Image )
- {
- if (st==TreeItem::Image )
- ok=true;
- } else if ( ct==Command::Any)
- {
- ok=true;
- } else if ( ct==Command::XLink)
- {
- if (st==TreeItem::XLink)
- ok=true;
- } else
- qWarning()<<"Parser::checkParameters Unknown selection type";
- if (!ok)
- {
- setError (Aborted, "Selection does not match command");
- return false;
- }
- }
-
- // Check for number of parameters
- int optPars=0;
- for (int i=0; i < c->parCount(); i++ )
- if (c->isParOptional(i) ) optPars++;
- if (paramList.count() < (c->parCount() - optPars) ||
- paramList.count() > c->parCount() )
- {
- QString expected;
- if (optPars>0)
- expected=QString("%1..%2").arg(c->parCount()-optPars).arg(c->parCount() );
- else
- expected=QString().setNum(c->parCount());
- setError (
- Aborted,
- QString("Wrong number of parameters: Expected %1, but found %2").arg(expected).arg(paramList.count()));
- return false;
- }
-
- // Check types of parameters
- bool ok;
- for (int i=0; i < paramList.count(); i++ )
- {
- switch (c->getParType(i) )
- {
- case Command::String:
- parString (ok,i);
- if (!ok)
- {
- // Convert to string implicitly
- paramList[i]='"' + paramList[i] + '"';
- ok=true;
- }
- break;
- case Command::Int:
- parInt (ok,i);
- break;
- case Command::Double:
- parDouble (ok,i);
- break;
- case Command::Color:
- parColor (ok,i);
- break;
- case Command::Bool:
- parBool (ok,i);
- break;
- default: ok=false;
- }
- if (!ok)
- {
- setError (
- Aborted,
- QString("Parameter %1 has wrong type").arg(i));
- return false;
- }
- }
- resetError();
- return true;
- }
- }
- setError (Aborted,"Unknown command");
- return false;
-}
-
-void Parser::resetError ()
-{
- errMessage="";
- errDescription="";
- errLevel=NoError;
-}
-
-bool Parser::checkParCount (const int &expected)
-{
- if (paramList.count()!=expected)
- {
- setError (
- Aborted,
- QString("Wrong number of parameters: Expected %1, but found %2").arg(expected).arg(paramList.count()));
- return false;
- }
- return true;
-}
-
-bool Parser::checkParIsInt(const int &index)
-{
- bool ok;
- if (index > paramList.count())
- {
- setError (
- Aborted,
- QString("Parameter index %1 is outside of parameter list").arg(index));
- return false;
- } else
- {
- paramList[index].toInt (&ok, 10);
- if (!ok)
- {
- setError (
- Aborted,
- QString("Parameter %1 is not an integer").arg(index));
- return false;
- }
- }
- return true;
-}
-
-bool Parser::checkParIsDouble(const int &index)
-{
- bool ok;
- if (index > paramList.count())
- {
- setError (
- Aborted,
- QString("Parameter index %1 is outside of parameter list").arg(index));
- return false;
- } else
- {
- paramList[index].toDouble (&ok);
- if (!ok)
- {
- setError (
- Aborted,
- QString("Parameter %1 is not double").arg(index));
- return false;
- }
- }
- return true;
-}
-
-int Parser::parInt (bool &ok,const uint &index)
-{
- if (checkParIsInt (index))
- return paramList[index].toInt (&ok, 10);
- ok=false;
- return 0;
-}
-
-QString Parser::parString (bool &ok, const int &index)
-{
- // return the string at index, this could be also stored in
- // a variable later
-
- // Try to find out if string boundaries are "" or ''
- QRegExp rx;
- int pos = paramList[index].indexOf("\"");
- int n = paramList[index].indexOf("'");
-
- if ( n < 0 && pos < 0 )
- {
- // Neither " nor ' found
- ok = false;
- return "";
- } else if ( pos >= 0 && n < 0)
- // Found ", but no '
- rx.setPattern("\"(.*)\"");
- else if ( n >= 0 && pos < 0)
- // Found ', but no "
- rx.setPattern("'(.*)'");
- else if ( pos > n )
- // "" is within ''
- rx.setPattern("'(.*)'");
- else
- // '' is within ""
- rx.setPattern("\"(.*)\"");
-
-
-
- QString r;
- pos=rx.indexIn (paramList[index]);
- if (pos>=0)
- {
- r = rx.cap (1);
- ok = true;
- } else
- {
- r = "";
- ok = false;
- }
- return r;
-}
-
-bool Parser::parBool (bool &ok,const int &index)
-{
- // return the bool at index, this could be also stored in
- // a variable later
- QString r;
- ok=true;
- QString p=paramList[index];
- if (p=="true" || p=="1")
- return true;
- else if (p=="false" || p=="0")
- return false;
- ok=false;
- return ok;
-}
-
-QColor Parser::parColor(bool &ok,const int &index)
-{
- // return the QColor at index
- ok = false;
- QString r;
- QColor c;
-
- // testscipts use single quotes, convert them first
- paramList[index].replace ("'", "\"");
- QRegExp re("\"(.*)\"");
- int pos = re.indexIn (paramList[index]);
- if (pos >= 0)
- {
- r = re.cap (1);
- c.setNamedColor(r);
- ok = c.isValid();
- }
- return c;
-}
-
-double Parser::parDouble (bool &ok,const int &index)
-{
- if (checkParIsDouble (index))
- return paramList[index].toDouble (&ok);
- ok=false;
- return 0;
-}
-
-void Parser::setScript(const QString &s)
-{
- script=s;
-}
-
-QString Parser::getScript()
-{
- return script;
-}
-
-void Parser::execute()
-{
- current=0;
-}
-
-bool Parser::next() //FIXME-3 parser does not detect missing closing " or '("foo" ()'
-{
- int start=current;
- if (current<0) execute();
- if (current+1>=script.length()) return false;
-
- bool inQuote=false;
- QChar bnd;
-
- while (true)
- {
- // Check if we are inside a string
- if (script.at(current) == '\"')
- {
- if (inQuote)
- {
- if (script.at(current) == bnd)
- inQuote=false;
- } else
- {
- inQuote = true;
- bnd = '\"';
- }
- } else if (script.at(current) == '\'' )
- {
- if (inQuote)
- {
- if (script.at(current) == bnd)
- inQuote=false;
- } else
- {
- inQuote = true;
- bnd = '\'';
- }
- }
-
- // Check for EOL
- if (script.at(current) == '\n')
- {
- if (current+1 < script.length())
- {
- current++;
- if (script.at(current) == '\r')
- current++;
- }
- }
-
- // Check if we are in a comment
- if (!inQuote && script.at(current)=='#')
- {
- while (script.at(current)!='\n')
- {
- current++;
- if (script.at(current) == '\r')
- current++;
- if (current+1>=script.length())
- return false;
- }
- start=current;
- }
-
- // Check for end of atom
- if (!inQuote && script.at(current)==';')
- {
- parseAtom(script.mid(start,current-start) );
- current++;
- return true;
- }
-
- // Check for end of script
- if (current+1>=script.length() )
- {
- if (inQuote)
- {
- setError (Aborted,"Runaway string");
- return false;
- } else
- {
- atom=script.mid(start);
- return true;
- }
- }
- current++;
- }
-}
-
-QStringList Parser::getCommands()
-{
- QStringList list;
- foreach (Command *c, modelCommands)
- list.append (c->getName() );
- return list;
-}
-
-QStringList Parser::findParameters(const QString &s)
-{
- QStringList ret;
- int left = 0;
- bool inquote = false;
-
- // Try to find out if string boundaries are "" or ''
- QString bnd;
- int pos = s.indexOf("\"");
- int n = s.indexOf("'");
-
- if ( n < 0 && pos < 0 )
- {
- // Neither " nor ' found, ignore later
- bnd = "\"";
- } else if ( pos >= 0 && n < 0)
- // Found ", but no '
- bnd = "\"";
- else if ( n >= 0 && pos < 0)
- // Found ', but no "
- bnd = "'";
- else if ( pos > n )
- // "" is within ''
- bnd = "'";
- else
- // '' is within ""
- bnd = "\"";
-
- pos = 0;
- while (pos < s.length())
- {
- if (s.at(pos) == bnd )
- {
- if (inquote)
- inquote = false;
- else
- inquote = true;
- }
- if (s.at(pos) == ',' && !inquote)
- {
- ret << s.mid(left, pos - left );
- left = pos + 1;
- }
- pos++;
- }
- if (left > 0)
- ret << s.mid(left, pos - left );
- else
- if (!s.isEmpty()) ret << s;
- return ret;
-}
-
-bool Parser::nextParenthesisContents(
- const QString &s,
- int &leftParenthesis,
- int &rightParenthesis,
- QString &contents)
-{
- int pos = 0;
- int leftP = -1;
- int rightP = -1;
- int openParenthesis = 0;
- bool inQuote = false;
- QChar bnd;
- while (pos < s.length())
- {
- // Check if we are inside a string
- if (s.at(current) == '\"')
- {
- if (inQuote)
- {
- if (s.at(current) == bnd)
- inQuote=false;
- } else
- {
- inQuote = true;
- bnd = '\"';
- }
- } else if (s.at(current) == '\'' )
- {
- if (inQuote)
- {
- if (s.at(current) == bnd)
- inQuote=false;
- } else
- {
- inQuote = true;
- bnd = '\'';
- }
- }
-
- if (s.at(pos) == '(' && !inQuote)
- {
- openParenthesis++;
- if (openParenthesis == 1) leftP=pos;
- }
-
- if (s.at(pos) == ')' && !inQuote)
- {
- openParenthesis--;
- if (openParenthesis == 0) rightP=pos;
- }
-
- if (openParenthesis < 0)
- {
- setError(Aborted, "Error, too many closing parenthesis!");
- return false;
- }
-
- pos++;
- }
-
- if (leftP < 0)
- {
- setError(Aborted, "Error: No left parenthesis found");
- return false;
- }
-
- if (rightP < 0)
- {
- setError(Aborted, "Error: No right parenthesis found");
- return false;
- }
-
- contents = s.mid(leftP+1, rightP - leftP - 1);
- pos = leftParenthesis;
- leftParenthesis = leftP;
- rightParenthesis = rightP;
-
- return true;
-}
-