LayerManagerControl: added support for optional expressions in commands
[profile/ivi/layer-management.git] / LayerManagerControl / src / Expression.cpp
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
26 Expression::Expression(string name, Expression* parent)
27 : mName(name)
28 , mPreviousWord(parent)
29 , mFuncPtr(NULL)
30 , mMatchText("")
31 {
32 }
33
34 void Expression::setVarValue(string value)
35 {
36     mVarValue = value;
37 }
38
39 bool Expression::isVar()
40 {
41     return mName[0] == '<' || (mName[0] == '[' && mName[1] == '<');
42 }
43
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
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
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
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
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
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
146 bool Expression::contains(string name)
147 {
148     return mMatchText == name || (mPreviousWord && mPreviousWord->contains(name));
149 }
150
151 string Expression::getName()
152 {
153     return mName;
154 }
155
156 bool ExpressionCompare(Expression* a, Expression* b)
157 {
158     return a->getName() < b->getName();
159 }
160
161 void Expression::addNextExpression(Expression* word)
162 {
163     mNextWords.push_back(word);
164     mNextWords.sort(ExpressionCompare);
165 }
166
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
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->isVar())
217             {
218                 nextClosure.push_back(expr);
219
220                 expr->setVarValue(text);
221
222                 string exprName = expr->mName;
223
224                 //remove brakcets
225                 exprName = exprName[0] == '['? exprName.substr(1, exprName.size()-1) : exprName;
226                 exprName = exprName[exprName.size()-1] == ']'? exprName.substr(0, exprName.size()-1) : exprName;
227
228                 exprName = exprName[0] == '<'? exprName.substr(1, exprName.size()-1) : exprName;
229                 exprName = exprName[exprName.size()-1] == '>'? exprName.substr(0, exprName.size()-1) : exprName;
230
231                 //remove default value (if needed)
232                 exprName = exprName.substr(0, exprName.find("="));
233
234                 expr->mMatchText = exprName;
235             }
236             else
237             {
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;
242
243                 //check all alternatives (in case there are alternatives)
244                 while (exprName.length() > 0)
245                 {
246                     //get next part
247                     string temp = exprName.substr(0, exprName.find("|", 1));
248                     exprName = exprName.substr(temp.length());
249
250                     //it there is a '|' at beginning remove it
251                     temp = temp[0] == '|' ? temp.substr(1) : temp;
252                     if (temp == text)
253                     {
254                         //add to result !
255                         nextClosure.push_back(expr);
256                         expr->mMatchText = text;
257                         break; //from inner loop !
258                     }
259                 }
260             }
261         }
262     }
263
264     return nextClosure;
265 }
266
267 ExpressionList Expression::getNextExpressions()
268 {
269     return this->mNextWords;
270 }
271
272 Expression* Expression::getNextExpression(string text)
273 {
274     Expression* varMatch = NULL;
275     Expression* nameMatch = NULL;
276
277     ExpressionList::const_iterator iter = mNextWords.begin();
278     ExpressionList::const_iterator end = mNextWords.end();
279     for (; iter != end; ++iter)
280     {
281         Expression* expr = *iter;
282         string exprName = expr->getName();
283
284         if (exprName == text)
285         {
286             nameMatch = expr;
287         }
288
289         if (expr->isVar())
290         {
291             varMatch = expr;
292             varMatch->setVarValue(text);
293         }
294     }
295
296     return nameMatch ? nameMatch : (varMatch ? varMatch : NULL);
297 }
298
299 ExpressionList Expression::getClosureExecutables(bool canBypass)
300 {
301     ExpressionList candidateExecutables;
302
303     if (canBypass)
304     {
305         string expName = this->mName;
306         if (mName[mName.length() - 1] == ']')
307         {
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);
311         }
312         else
313         {
314             ExpressionList::const_iterator iter = mNextWords.begin();
315             ExpressionList::const_iterator end = mNextWords.end();
316             for (; iter != end; ++iter)
317             {
318                 string childName = (*iter)->mName;
319
320                 ExpressionList childClosure = (*iter)->getClosureExecutables(true);
321                 candidateExecutables.splice(candidateExecutables.end(), childClosure);
322             }
323         }
324     }
325     else
326     {
327         //add myself to candidate executables
328         candidateExecutables.push_back(this);
329
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)
334         {
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] == '[')
338             {
339                 ExpressionList childClosure = (*iter)->getClosureExecutables(true);
340                 candidateExecutables.splice(candidateExecutables.end(), childClosure);
341             }
342         }
343     }
344
345     //return only the executable expressions
346     ExpressionList executables;
347
348     ExpressionList::const_iterator iter = candidateExecutables.begin();
349     ExpressionList::const_iterator end = candidateExecutables.end();
350     for (; iter != end; ++iter)
351     {
352         Expression* expr = *iter;
353
354         //check if it already exists in the list
355         bool duplicate = std::find(executables.begin(), executables.end(), expr) != executables.end();
356
357         if ((! duplicate) && expr->isExecutable())
358         {
359             executables.push_back(expr);
360         }
361     }
362
363     return executables;
364 }
365
366 void Expression::printTree(int level)
367 {
368     for (int i = 0; i < level; ++i)
369     {
370         cout << ((i + 1 != level) ? "|  " : "|--");
371     }
372
373     stringstream name;
374     name << mName;
375
376     if (isExecutable())
377     {
378         name << "*";
379     }
380
381     cout << name.str() << endl;
382
383     ExpressionList::const_iterator iter = mNextWords.begin();
384     ExpressionList::const_iterator end = mNextWords.end();
385     for (; iter != end; ++iter)
386     {
387         (*iter)->printTree(level + 1);
388     }
389 }
390
391 void Expression::printList(string list)
392 {
393     if (mName != "[root]")
394     {
395         list += mName;
396         list += " ";
397         if (isExecutable())
398         {
399             cout << list << "\n";
400         }
401     }
402
403     ExpressionList::const_iterator iter = mNextWords.begin();
404     ExpressionList::const_iterator end = mNextWords.end();
405     for (; iter != end; ++iter)
406     {
407         (*iter)->printList(list);
408     }
409 }
410
411 bool Expression::isExecutable()
412 {
413     return mFuncPtr;
414 }
415
416 void Expression::execute()
417 {
418     (*mFuncPtr)(this);
419 }
420
421 void Expression::setFunc(callback funcPtr)
422 {
423     mFuncPtr = funcPtr;
424 }
425
426 Expression* Expression::getPreviousExpression()
427 {
428     return mPreviousWord;
429 }