1 /***************************************************************************
3 * Copyright 2012 BMW Car IT GmbH
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 ****************************************************************************/
19 #include "Expression.h"
23 #include <string.h> // memcpy
26 Expression::Expression(string name, Expression* parent)
28 , mPreviousWord(parent)
34 void Expression::setVarValue(string value)
39 bool Expression::isVar()
41 return mName[0] == '<' || (mName[0] == '[' && mName[1] == '<');
44 string Expression::getString(string name)
46 //remove brackets if needed
47 string noBrackets = mName;
48 noBrackets = noBrackets[0] == '['? noBrackets.substr(1, noBrackets.size()-1) : noBrackets;
49 noBrackets = noBrackets[noBrackets.size()-1] == ']'? noBrackets.substr(0, noBrackets.size()-1) : noBrackets;
51 noBrackets = noBrackets[0] == '<'? noBrackets.substr(1, noBrackets.size()-1) : noBrackets;
52 noBrackets = noBrackets[noBrackets.size()-1] == '>'? noBrackets.substr(0, noBrackets.size()-1) : noBrackets;
54 //remove default value (if needed)
55 string exprName = noBrackets.substr(0, noBrackets.find("="));
61 //if there was a match return the value
64 else if (noBrackets.find("=") != string::npos)
66 //return default value
67 return noBrackets.substr(noBrackets.find("=") + 1);
70 else if (mPreviousWord)
72 return mPreviousWord->getString(name);
78 unsigned int Expression::getUint(string name)
80 string stringVal = getString(name);
82 unsigned int value = 0;
83 sscanf(stringVal.c_str(), "%u", &value);
87 sscanf(stringVal.c_str(), "0x%x", &value);
92 void Expression::getUintArray(string name, unsigned int** array, unsigned int* count)
95 ss << getString(name);
97 unsigned int buffer[256]; // more than enough for all cases
101 while (getline( ss, stringVal, ',' ))
103 sscanf(stringVal.c_str(), "%u", &buffer[*count]);
107 sscanf(stringVal.c_str(), "0x%x", &buffer[*count]);
112 *array = new unsigned int[*count];
113 memcpy(*array, buffer, sizeof(unsigned int) * (*count));
116 int Expression::getInt(string name)
118 string stringVal = getString(name);
121 sscanf(stringVal.c_str(), "%d", &value);
125 sscanf(stringVal.c_str(), "0x%x", (unsigned int*) &value);
130 double Expression::getDouble(string name)
132 string stringVal = getString(name);
135 sscanf(stringVal.c_str(), "%lf", &value);
139 bool Expression::getBool(string name)
141 string stringVal = getString(name);
143 return sscanf(stringVal.c_str(), "%d", &value) && value;
146 bool Expression::contains(string name)
148 return mMatchText == name || (mPreviousWord && mPreviousWord->contains(name));
151 string Expression::getName()
156 bool ExpressionCompare(Expression* a, Expression* b)
158 return a->getName() < b->getName();
161 void Expression::addNextExpression(Expression* word)
163 mNextWords.push_back(word);
164 mNextWords.sort(ExpressionCompare);
167 ExpressionList Expression::getClosure(bool bypass)
169 ExpressionList closure;
173 //if expression is end of the optional expression
174 bool bypassChildren = mName[mName.length() - 1] != ']';
175 //get closure of children
176 ExpressionList::const_iterator iter = mNextWords.begin();
177 ExpressionList::const_iterator end = mNextWords.end();
178 for (; iter != end; ++iter)
180 ExpressionList childClosure = (*iter)->getClosure(bypassChildren);
181 closure.splice(closure.end(), childClosure);
186 closure.push_back(this);
187 //if start of optional expression
190 //get closure of elements after the end of the expression
191 ExpressionList restClosure = getClosure(true);
192 closure.splice(closure.end(), restClosure);
199 ExpressionList Expression::getNextExpressionClosure(string text)
201 ExpressionList nextClosure;
203 ExpressionList::const_iterator iter = mNextWords.begin();
204 ExpressionList::const_iterator end = mNextWords.end();
205 for (; iter != end; ++iter)
207 Expression* childExpr = *iter;
208 ExpressionList childClosure = childExpr->getClosure(false);
210 ExpressionList::const_iterator iter = childClosure.begin();
211 ExpressionList::const_iterator end = childClosure.end();
212 for (; iter != end; ++iter)
214 Expression* expr = *iter;
218 nextClosure.push_back(expr);
220 expr->setVarValue(text);
222 string exprName = expr->mName;
225 exprName = exprName[0] == '['? exprName.substr(1, exprName.size()-1) : exprName;
226 exprName = exprName[exprName.size()-1] == ']'? exprName.substr(0, exprName.size()-1) : exprName;
228 exprName = exprName[0] == '<'? exprName.substr(1, exprName.size()-1) : exprName;
229 exprName = exprName[exprName.size()-1] == '>'? exprName.substr(0, exprName.size()-1) : exprName;
231 //remove default value (if needed)
232 exprName = exprName.substr(0, exprName.find("="));
234 expr->mMatchText = exprName;
238 //remove brackets if needed
239 string exprName = expr->mName;
240 exprName = exprName[0] == '['? exprName.substr(1, exprName.size()-1) : exprName;
241 exprName = exprName[exprName.size()-1] == ']'? exprName.substr(0, exprName.size()-1) : exprName;
243 //check all alternatives (in case there are alternatives)
244 while (exprName.length() > 0)
247 string temp = exprName.substr(0, exprName.find("|", 1));
248 exprName = exprName.substr(temp.length());
250 //it there is a '|' at beginning remove it
251 temp = temp[0] == '|' ? temp.substr(1) : temp;
255 nextClosure.push_back(expr);
256 expr->mMatchText = text;
257 break; //from inner loop !
267 ExpressionList Expression::getNextExpressions()
269 return this->mNextWords;
272 Expression* Expression::getNextExpression(string text)
274 Expression* varMatch = NULL;
275 Expression* nameMatch = NULL;
277 ExpressionList::const_iterator iter = mNextWords.begin();
278 ExpressionList::const_iterator end = mNextWords.end();
279 for (; iter != end; ++iter)
281 Expression* expr = *iter;
282 string exprName = expr->getName();
284 if (exprName == text)
292 varMatch->setVarValue(text);
296 return nameMatch ? nameMatch : (varMatch ? varMatch : NULL);
299 ExpressionList Expression::getClosureExecutables(bool canBypass)
301 ExpressionList candidateExecutables;
305 string expName = this->mName;
306 if (mName[mName.length() - 1] == ']')
308 //as if this child was the "last consumed" expression by the user string input !
309 ExpressionList childExecutables = getClosureExecutables(false);
310 candidateExecutables.splice(candidateExecutables.end(), childExecutables);
314 ExpressionList::const_iterator iter = mNextWords.begin();
315 ExpressionList::const_iterator end = mNextWords.end();
316 for (; iter != end; ++iter)
318 string childName = (*iter)->mName;
320 ExpressionList childClosure = (*iter)->getClosureExecutables(true);
321 candidateExecutables.splice(candidateExecutables.end(), childClosure);
327 //add myself to candidate executables
328 candidateExecutables.push_back(this);
330 //get candidate executables from children
331 ExpressionList::const_iterator iter = mNextWords.begin();
332 ExpressionList::const_iterator end = mNextWords.end();
333 for (; iter != end; ++iter)
335 //if child is start of optional expression: get executable closure from the ends of this child
336 string childName = (*iter)->mName;
337 if (childName[0] == '[')
339 ExpressionList childClosure = (*iter)->getClosureExecutables(true);
340 candidateExecutables.splice(candidateExecutables.end(), childClosure);
345 //return only the executable expressions
346 ExpressionList executables;
348 ExpressionList::const_iterator iter = candidateExecutables.begin();
349 ExpressionList::const_iterator end = candidateExecutables.end();
350 for (; iter != end; ++iter)
352 Expression* expr = *iter;
354 //check if it already exists in the list
355 bool duplicate = std::find(executables.begin(), executables.end(), expr) != executables.end();
357 if ((! duplicate) && expr->isExecutable())
359 executables.push_back(expr);
366 void Expression::printTree(int level)
368 for (int i = 0; i < level; ++i)
370 cout << ((i + 1 != level) ? "| " : "|--");
381 cout << name.str() << endl;
383 ExpressionList::const_iterator iter = mNextWords.begin();
384 ExpressionList::const_iterator end = mNextWords.end();
385 for (; iter != end; ++iter)
387 (*iter)->printTree(level + 1);
391 void Expression::printList(string list)
393 if (mName != "[root]")
399 cout << list << "\n";
403 ExpressionList::const_iterator iter = mNextWords.begin();
404 ExpressionList::const_iterator end = mNextWords.end();
405 for (; iter != end; ++iter)
407 (*iter)->printList(list);
411 bool Expression::isExecutable()
416 void Expression::execute()
421 void Expression::setFunc(callback funcPtr)
426 Expression* Expression::getPreviousExpression()
428 return mPreviousWord;