10 extern QList <Command*> modelCommands;
17 void Parser::initParser()
23 void Parser::initAtom()
33 void Parser::parseAtom (QString s)
39 // Strip WS at beginning
40 while (s.length() > 0 && (
49 re.setPattern ("^(\\w*)");
59 if (!nextParenthesisContents(s, leftParenthesis, rightParenthesis, t)) return;
61 paramList = findParameters(t);
65 QString Parser::getAtom()
70 QString Parser::getCommand()
75 QStringList Parser::getParameters()
80 int Parser::parCount()
82 return paramList.count();
85 QString Parser::errorMessage()
90 case NoError: l="No Error"; break;
91 case Warning: l="Warning"; break;
92 case Aborted: l="Aborted"; break;
95 return QString ("Error Level: '%1' Command: '%2' Description: '%3'")
96 .arg(l).arg(com).arg(errDescription);
99 QString Parser::errorDescription()
101 return errDescription;
104 ErrorLevel Parser::errorLevel()
109 void Parser::setError(ErrorLevel level, const QString &description)
111 errDescription=description;
115 bool Parser::checkParameters(TreeItem *selti)
117 foreach (Command *c, modelCommands)
119 if (c->getName() == com)
121 // Check type of selection
126 TreeItem::Type st=selti->getType();
127 Command::SelectionType ct=c->getSelectionType();
128 if (ct==Command::TreeItem || ct==Command::BranchOrImage)
130 if (st==TreeItem::MapCenter ||
131 st==TreeItem::Branch ||
132 st==TreeItem::XLink ||
133 st==TreeItem::Image )
135 } else if ( ct==Command::BranchOrImage )
137 if (st==TreeItem::MapCenter ||
138 st==TreeItem::Branch ||
139 st==TreeItem::Image )
141 } else if ( ct==Command::Branch || ct==Command::BranchLike)
144 if (st == TreeItem::MapCenter ||
145 st == TreeItem::Branch )
147 } else if ( ct==Command::Image )
149 if (st==TreeItem::Image )
151 } else if ( ct==Command::Any)
154 } else if ( ct==Command::XLink)
156 if (st==TreeItem::XLink)
159 qWarning()<<"Parser::checkParameters Unknown selection type";
162 setError (Aborted, "Selection does not match command");
167 // Check for number of parameters
169 for (int i=0; i < c->parCount(); i++ )
170 if (c->isParOptional(i) ) optPars++;
171 if (paramList.count() < (c->parCount() - optPars) ||
172 paramList.count() > c->parCount() )
176 expected=QString("%1..%2").arg(c->parCount()-optPars).arg(c->parCount() );
178 expected=QString().setNum(c->parCount());
181 QString("Wrong number of parameters: Expected %1, but found %2").arg(expected).arg(paramList.count()));
185 // Check types of parameters
187 for (int i=0; i < paramList.count(); i++ )
189 switch (c->getParType(i) )
191 case Command::String:
195 // Convert to string implicitly
196 paramList[i]='"' + paramList[i] + '"';
203 case Command::Double:
218 QString("Parameter %1 has wrong type").arg(i));
226 setError (Aborted,"Unknown command");
230 void Parser::resetError ()
237 bool Parser::checkParCount (const int &expected)
239 if (paramList.count()!=expected)
243 QString("Wrong number of parameters: Expected %1, but found %2").arg(expected).arg(paramList.count()));
249 bool Parser::checkParIsInt(const int &index)
252 if (index > paramList.count())
256 QString("Parameter index %1 is outside of parameter list").arg(index));
260 paramList[index].toInt (&ok, 10);
265 QString("Parameter %1 is not an integer").arg(index));
272 bool Parser::checkParIsDouble(const int &index)
275 if (index > paramList.count())
279 QString("Parameter index %1 is outside of parameter list").arg(index));
283 paramList[index].toDouble (&ok);
288 QString("Parameter %1 is not double").arg(index));
295 int Parser::parInt (bool &ok,const uint &index)
297 if (checkParIsInt (index))
298 return paramList[index].toInt (&ok, 10);
303 QString Parser::parString (bool &ok, const int &index)
305 // return the string at index, this could be also stored in
308 // Try to find out if string boundaries are "" or ''
310 int pos = paramList[index].indexOf("\"");
311 int n = paramList[index].indexOf("'");
313 if ( n < 0 && pos < 0 )
315 // Neither " nor ' found
318 } else if ( pos >= 0 && n < 0)
320 rx.setPattern("\"(.*)\"");
321 else if ( n >= 0 && pos < 0)
323 rx.setPattern("'(.*)'");
326 rx.setPattern("'(.*)'");
329 rx.setPattern("\"(.*)\"");
334 pos=rx.indexIn (paramList[index]);
347 bool Parser::parBool (bool &ok,const int &index)
349 // return the bool at index, this could be also stored in
353 QString p=paramList[index];
354 if (p=="true" || p=="1")
356 else if (p=="false" || p=="0")
362 QColor Parser::parColor(bool &ok,const int &index)
364 // return the QColor at index
369 // testscipts use single quotes, convert them first
370 paramList[index].replace ("'", "\"");
371 QRegExp re("\"(.*)\"");
372 int pos = re.indexIn (paramList[index]);
382 double Parser::parDouble (bool &ok,const int &index)
384 if (checkParIsDouble (index))
385 return paramList[index].toDouble (&ok);
390 void Parser::setScript(const QString &s)
395 QString Parser::getScript()
400 void Parser::execute()
405 bool Parser::next() //FIXME-3 parser does not detect missing closing " or '("foo" ()'
408 if (current<0) execute();
409 if (current+1>=script.length()) return false;
416 // Check if we are inside a string
417 if (script.at(current) == '\"')
421 if (script.at(current) == bnd)
428 } else if (script.at(current) == '\'' )
432 if (script.at(current) == bnd)
442 if (script.at(current) == '\n')
444 if (current+1 < script.length())
447 if (script.at(current) == '\r')
452 // Check if we are in a comment
453 if (!inQuote && script.at(current)=='#')
455 while (script.at(current)!='\n')
458 if (script.at(current) == '\r')
460 if (current+1>=script.length())
466 // Check for end of atom
467 if (!inQuote && script.at(current)==';')
469 parseAtom(script.mid(start,current-start) );
474 // Check for end of script
475 if (current+1>=script.length() )
479 setError (Aborted,"Runaway string");
483 atom=script.mid(start);
491 QStringList Parser::getCommands()
494 foreach (Command *c, modelCommands)
495 list.append (c->getName() );
499 QStringList Parser::findParameters(const QString &s)
503 bool inquote = false;
505 // Try to find out if string boundaries are "" or ''
507 int pos = s.indexOf("\"");
508 int n = s.indexOf("'");
510 if ( n < 0 && pos < 0 )
512 // Neither " nor ' found, ignore later
514 } else if ( pos >= 0 && n < 0)
517 else if ( n >= 0 && pos < 0)
528 while (pos < s.length())
530 if (s.at(pos) == bnd )
537 if (s.at(pos) == ',' && !inquote)
539 ret << s.mid(left, pos - left );
545 ret << s.mid(left, pos - left );
547 if (!s.isEmpty()) ret << s;
551 bool Parser::nextParenthesisContents(
553 int &leftParenthesis,
554 int &rightParenthesis,
560 int openParenthesis = 0;
561 bool inQuote = false;
563 while (pos < s.length())
565 // Check if we are inside a string
566 if (s.at(current) == '\"')
570 if (s.at(current) == bnd)
577 } else if (s.at(current) == '\'' )
581 if (s.at(current) == bnd)
590 if (s.at(pos) == '(' && !inQuote)
593 if (openParenthesis == 1) leftP=pos;
596 if (s.at(pos) == ')' && !inQuote)
599 if (openParenthesis == 0) rightP=pos;
602 if (openParenthesis < 0)
604 setError(Aborted, "Error, too many closing parenthesis!");
613 setError(Aborted, "Error: No left parenthesis found");
619 setError(Aborted, "Error: No right parenthesis found");
623 contents = s.mid(leftP+1, rightP - leftP - 1);
624 pos = leftParenthesis;
625 leftParenthesis = leftP;
626 rightParenthesis = rightP;