• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***************************************************************************
2  *
3  * Copyright 2012 BMW Car IT GmbH
4  *
5  *
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
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  ****************************************************************************/
19 #include "Expression.h"
20 #include <iostream>
21 #include <sstream>
22 #include <stdio.h>
23 #include <string.h>  // memcpy
24 #include <algorithm>
25 
Expression(string name,Expression * parent)26 Expression::Expression(string name, Expression* parent)
27 : mName(name)
28 , mPreviousWord(parent)
29 , mFuncPtr(NULL)
30 , mMatchText("")
31 {
32 }
33 
setVarValue(string value)34 void Expression::setVarValue(string value)
35 {
36     mVarValue = value;
37 }
38 
isVar()39 bool Expression::isVar()
40 {
41     return mName[0] == '<' || (mName[0] == '[' && mName[1] == '<');
42 }
43 
getString(string name)44 string Expression::getString(string name)
45 {
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;
50 
51     noBrackets = noBrackets[0] == '<' ? noBrackets.substr(1, noBrackets.size() - 1) : noBrackets;
52     noBrackets = noBrackets[noBrackets.size() - 1] == '>' ? noBrackets.substr(0, noBrackets.size() - 1) : noBrackets;
53 
54     //remove default value (if needed)
55     string exprName = noBrackets.substr(0, noBrackets.find("="));
56 
57     if (exprName == name)
58     {
59         if (mMatchText != "")
60         {
61             //if there was a match return the value
62             return mVarValue;
63         }
64         else if (noBrackets.find("=") != string::npos)
65         {
66             //return default value
67             return noBrackets.substr(noBrackets.find("=") + 1);
68         }
69     }
70     else if (mPreviousWord)
71     {
72         return mPreviousWord->getString(name);
73     }
74 
75     return "";
76 }
77 
getUint(string name)78 unsigned int Expression::getUint(string name)
79 {
80     string stringVal = getString(name);
81 
82     unsigned int value = 0;
83     sscanf(stringVal.c_str(), "%u", &value);
84 
85     if (!value)
86     {
87         sscanf(stringVal.c_str(), "0x%x", &value);
88     }
89     return value;
90 }
91 
getUintArray(string name,unsigned int ** array,unsigned int * count)92 void Expression::getUintArray(string name, unsigned int** array, unsigned int* count)
93 {
94     stringstream ss;
95     ss << getString(name);
96 
97     unsigned int buffer[256]; // more than enough for all cases
98     *count = 0;
99 
100     string stringVal;
101     while (getline(ss, stringVal, ','))
102     {
103         sscanf(stringVal.c_str(), "%u", &buffer[*count]);
104 
105         if (!buffer[*count])
106         {
107             sscanf(stringVal.c_str(), "0x%x", &buffer[*count]);
108         }
109         ++(*count);
110     }
111 
112     *array = new unsigned int[*count];
113     memcpy(*array, buffer, sizeof(unsigned int) * (*count));
114 }
115 
getInt(string name)116 int Expression::getInt(string name)
117 {
118     string stringVal = getString(name);
119 
120     int value = 0;
121     sscanf(stringVal.c_str(), "%d", &value);
122 
123     if (!value)
124     {
125         sscanf(stringVal.c_str(), "0x%x", (unsigned int*) &value);
126     }
127     return value;
128 }
129 
getDouble(string name)130 double Expression::getDouble(string name)
131 {
132     string stringVal = getString(name);
133 
134     double value = 0;
135     sscanf(stringVal.c_str(), "%lf", &value);
136     return value;
137 }
138 
getBool(string name)139 bool Expression::getBool(string name)
140 {
141     string stringVal = getString(name);
142     int value = 0;
143     return sscanf(stringVal.c_str(), "%d", &value) && value;
144 }
145 
contains(string name)146 bool Expression::contains(string name)
147 {
148     return mMatchText == name || (mPreviousWord && mPreviousWord->contains(name));
149 }
150 
getName()151 string Expression::getName()
152 {
153     return mName;
154 }
155 
ExpressionCompare(Expression * a,Expression * b)156 bool ExpressionCompare(Expression* a, Expression* b)
157 {
158     return a->getName() < b->getName();
159 }
160 
addNextExpression(Expression * word)161 void Expression::addNextExpression(Expression* word)
162 {
163     mNextWords.push_back(word);
164     mNextWords.sort(ExpressionCompare);
165 }
166 
getClosure(bool bypass)167 ExpressionList Expression::getClosure(bool bypass)
168 {
169     ExpressionList closure;
170 
171     if (bypass)
172     {
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)
179         {
180             ExpressionList childClosure = (*iter)->getClosure(bypassChildren);
181             closure.splice(closure.end(), childClosure);
182         }
183     }
184     else
185     {
186         closure.push_back(this);
187         //if start of optional expression
188         if (mName[0] == '[')
189         {
190             //get closure of elements after the end of the expression
191             ExpressionList restClosure = getClosure(true);
192             closure.splice(closure.end(), restClosure);
193         }
194     }
195 
196     return closure;
197 }
198 
getNextExpressionClosure(string text)199 ExpressionList Expression::getNextExpressionClosure(string text)
200 {
201     ExpressionList nextClosure;
202 
203     ExpressionList::const_iterator iter = mNextWords.begin();
204     ExpressionList::const_iterator end = mNextWords.end();
205     for (; iter != end; ++iter)
206     {
207         Expression* childExpr = *iter;
208         ExpressionList childClosure = childExpr->getClosure(false);
209 
210         ExpressionList::const_iterator iter = childClosure.begin();
211         ExpressionList::const_iterator end = childClosure.end();
212         for (; iter != end; ++iter)
213         {
214             Expression* expr = *iter;
215 
216             if((expr->mName).compare("<file>") &&
217                (expr->mName).compare("<filename>"))
218             {
219                 transform(text.begin(), text.end(), text.begin(), ::tolower);
220             }
221 
222             if (expr->isVar())
223             {
224                 nextClosure.push_back(expr);
225 
226                 expr->setVarValue(text);
227 
228                 string exprName = expr->mName;
229 
230                 //remove brakcets
231                 exprName = exprName[0] == '[' ? exprName.substr(1, exprName.size() - 1) : exprName;
232                 exprName = exprName[exprName.size() - 1] == ']' ? exprName.substr(0, exprName.size() - 1) : exprName;
233 
234                 exprName = exprName[0] == '<' ? exprName.substr(1, exprName.size()-1) : exprName;
235                 exprName = exprName[exprName.size() - 1] == '>' ? exprName.substr(0, exprName.size() - 1) : exprName;
236 
237                 //remove default value (if needed)
238                 exprName = exprName.substr(0, exprName.find("="));
239 
240                 expr->mMatchText = exprName;
241             }
242             else
243             {
244                 //remove brackets if needed
245                 string exprName = expr->mName;
246                 exprName = exprName[0] == '[' ? exprName.substr(1, exprName.size() - 1) : exprName;
247                 exprName = exprName[exprName.size() - 1] == ']' ? exprName.substr(0, exprName.size() - 1) : exprName;
248 
249                 //check all alternatives (in case there are alternatives)
250                 while (exprName.length() > 0)
251                 {
252                     //get next part
253                     string temp = exprName.substr(0, exprName.find("|", 1));
254                     exprName = exprName.substr(temp.length());
255 
256                     //it there is a '|' at beginning remove it
257                     temp = temp[0] == '|' ? temp.substr(1) : temp;
258                     if (temp == text)
259                     {
260                         //add to result !
261                         nextClosure.push_back(expr);
262                         expr->mMatchText = text;
263                         break; //from inner loop !
264                     }
265                 }
266             }
267         }
268     }
269 
270     return nextClosure;
271 }
272 
getNextExpressions()273 ExpressionList Expression::getNextExpressions()
274 {
275     return this->mNextWords;
276 }
277 
getNextExpression(string text)278 Expression* Expression::getNextExpression(string text)
279 {
280     Expression* varMatch = NULL;
281     Expression* nameMatch = NULL;
282 
283     ExpressionList::const_iterator iter = mNextWords.begin();
284     ExpressionList::const_iterator end = mNextWords.end();
285     for (; iter != end; ++iter)
286     {
287         Expression* expr = *iter;
288         string exprName = expr->getName();
289 
290         if (exprName == text)
291         {
292             nameMatch = expr;
293         }
294 
295         if (expr->isVar())
296         {
297             varMatch = expr;
298             varMatch->setVarValue(text);
299         }
300     }
301 
302     return nameMatch ? nameMatch : (varMatch ? varMatch : NULL);
303 }
304 
getClosureExecutables(bool canBypass)305 ExpressionList Expression::getClosureExecutables(bool canBypass)
306 {
307     ExpressionList candidateExecutables;
308 
309     if (canBypass)
310     {
311         string expName = this->mName;
312         if (mName[mName.length() - 1] == ']')
313         {
314             //as if this child was the "last consumed" expression by the user string input !
315             ExpressionList childExecutables = getClosureExecutables(false);
316             candidateExecutables.splice(candidateExecutables.end(), childExecutables);
317         }
318         else
319         {
320             ExpressionList::const_iterator iter = mNextWords.begin();
321             ExpressionList::const_iterator end = mNextWords.end();
322             for (; iter != end; ++iter)
323             {
324                 string childName = (*iter)->mName;
325 
326                 ExpressionList childClosure = (*iter)->getClosureExecutables(true);
327                 candidateExecutables.splice(candidateExecutables.end(), childClosure);
328             }
329         }
330     }
331     else
332     {
333         //add myself to candidate executables
334         candidateExecutables.push_back(this);
335 
336         //get candidate executables from children
337         ExpressionList::const_iterator iter = mNextWords.begin();
338         ExpressionList::const_iterator end = mNextWords.end();
339         for (; iter != end; ++iter)
340         {
341             //if child is start of optional expression: get executable closure from the ends of this child
342             string childName = (*iter)->mName;
343             if (childName[0] == '[')
344             {
345                 ExpressionList childClosure = (*iter)->getClosureExecutables(true);
346                 candidateExecutables.splice(candidateExecutables.end(), childClosure);
347             }
348         }
349     }
350 
351     //return only the executable expressions
352     ExpressionList executables;
353 
354     ExpressionList::const_iterator iter = candidateExecutables.begin();
355     ExpressionList::const_iterator end = candidateExecutables.end();
356     for (; iter != end; ++iter)
357     {
358         Expression* expr = *iter;
359 
360         //check if it already exists in the list
361         bool duplicate = std::find(executables.begin(), executables.end(), expr) != executables.end();
362 
363         if ((! duplicate) && expr->isExecutable())
364         {
365             executables.push_back(expr);
366         }
367     }
368 
369     return executables;
370 }
371 
printTree(int level)372 void Expression::printTree(int level)
373 {
374     for (int i = 0; i < level; ++i)
375     {
376         cout << ((i + 1 != level) ? "|  " : "|--");
377     }
378 
379     stringstream name;
380     name << mName;
381 
382     if (isExecutable())
383     {
384         name << "*";
385     }
386 
387     cout << name.str() << endl;
388 
389     ExpressionList::const_iterator iter = mNextWords.begin();
390     ExpressionList::const_iterator end = mNextWords.end();
391     for (; iter != end; ++iter)
392     {
393         (*iter)->printTree(level + 1);
394     }
395 }
396 
printList(string list)397 void Expression::printList(string list)
398 {
399     if (mName != "[root]")
400     {
401         list += mName;
402         list += " ";
403         if (isExecutable())
404         {
405             cout << list << "\n";
406         }
407     }
408 
409     ExpressionList::const_iterator iter = mNextWords.begin();
410     ExpressionList::const_iterator end = mNextWords.end();
411     for (; iter != end; ++iter)
412     {
413         (*iter)->printList(list);
414     }
415 }
416 
isExecutable()417 bool Expression::isExecutable()
418 {
419     return mFuncPtr;
420 }
421 
execute()422 void Expression::execute()
423 {
424     (*mFuncPtr)(this);
425 }
426 
setFunc(callback funcPtr)427 void Expression::setFunc(callback funcPtr)
428 {
429     mFuncPtr = funcPtr;
430 }
431 
getPreviousExpression()432 Expression* Expression::getPreviousExpression()
433 {
434     return mPreviousWord;
435 }
436