My Project
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
condparser.cpp
Go to the documentation of this file.
1 
22 #include "condparser.h"
23 #include "config.h"
24 #include "message.h"
25 
26 // declarations
27 
34 bool CondParser::parse(const char *fileName,int lineNr,const char *expr)
35 {
36  m_expr = expr;
38 
39  // initialize all variables
40  m_e = m_expr; // let m_e point to the start of the expression
41 
42  bool answer=FALSE;
43  getToken();
44  if (m_tokenType==DELIMITER && m_token.isEmpty())
45  {
46  // empty expression: answer==FALSE
47  }
48  else if (m_err.isEmpty())
49  {
50  answer = parseLevel1();
51 
52 #if 0
53  // check for garbage at the end of the expression
54  // an expression ends with a character '\0' and token_type = delimeter
55  if (m_tokenType!=DELIMITER || !m_token.isEmpty())
56  {
57  if (m_tokenType == DELIMITER)
58  {
59  if (m_token=="(" || m_token==")")
60  {
61  m_err=QCString("Unexpected parenthesis ")+m_token+"'";
62  }
63  else
64  {
65  // user entered a not existing operator like "//"
66  m_err=QCString("Unexpected operator ")+m_token+"'";
67  }
68  }
69  else
70  {
71  m_err=QCString("Unexpected part '")+m_token+"'";
72  }
73  }
74 #endif
75  }
76  if (m_err)
77  {
78  warn(fileName,lineNr,"problem evaluating expression '%s': %s",
79  expr,m_err.data());
80  }
81  //printf("expr='%s' answer=%d\n",expr,answer);
82  return answer;
83 }
84 
85 
90 static bool isDelimiter(const char c)
91 {
92  return c=='&' || c=='|' || c=='!';
93 }
94 
98 static bool isAlpha(const char c)
99 {
100  return (c>='A' && c<='Z') || (c>='a' && c<='z') || c=='_';
101 }
102 
103 static bool isAlphaNum(const char c)
104 {
105  return isAlpha(c) || (c>='0' && c<='9');
106 }
107 
112 int CondParser::getOperatorId(const QCString &opName)
113 {
114  // level 2
115  if (opName=="&&") { return AND; }
116  if (opName=="||") { return OR; }
117 
118  // not operator
119  if (opName=="!") { return NOT; }
120 
121  return UNKNOWN_OP;
122 }
123 
130 {
132  m_token.resize(0);
133 
134  //printf("\tgetToken e:{%c}, ascii=%i, col=%i\n", *e, *e, e-expr);
135 
136  // skip over whitespaces
137  while (*m_e == ' ' || *m_e == '\t') // space or tab
138  {
139  m_e++;
140  }
141 
142  // check for end of expression
143  if (*m_e=='\0')
144  {
145  // token is still empty
147  return;
148  }
149 
150  // check for parentheses
151  if (*m_e == '(' || *m_e == ')')
152  {
154  m_token += *m_e++;
155  return;
156  }
157 
158  // check for operators (delimeters)
159  if (isDelimiter(*m_e))
160  {
162  while (isDelimiter(*m_e))
163  {
164  m_token += *m_e++;
165  }
166  return;
167  }
168 
169  // check for variables
170  if (isAlpha(*m_e))
171  {
173  while (isAlphaNum(*m_e))
174  {
175  m_token += *m_e++;
176  }
177  return;
178  }
179 
180  // something unknown is found, wrong characters -> a syntax error
182  while (*m_e)
183  {
184  m_token += *m_e++;
185  }
186  m_err = QCString("Syntax error in part '")+m_token+"'";
187  return;
188 }
189 
190 
195 {
196  bool ans = parseLevel2();
197  int opId = getOperatorId(m_token);
198 
199  while (opId==AND || opId==OR)
200  {
201  getToken();
202  ans = evalOperator(opId, ans, parseLevel2());
203  opId = getOperatorId(m_token);
204  }
205 
206  return ans;
207 }
208 
213 {
214  bool ans;
215  int opId = getOperatorId(m_token);
216  if (opId == NOT)
217  {
218  getToken();
219  ans = !parseLevel3();
220  }
221  else
222  {
223  ans = parseLevel3();
224  }
225 
226  return ans;
227 }
228 
229 
234 {
235  // check if it is a parenthesized expression
236  if (m_tokenType == DELIMITER)
237  {
238  if (m_token=="(")
239  {
240  getToken();
241  int ans = parseLevel1();
242  if (m_tokenType!=DELIMITER || m_token!=")")
243  {
244  m_err="Parenthesis ) missing";
245  return FALSE;
246  }
247  getToken();
248  return ans;
249  }
250  }
251 
252  // if not parenthesized then the expression is a variable
253  return parseVar();
254 }
255 
256 
258 {
259  bool ans = 0;
260  switch (m_tokenType)
261  {
262  case VARIABLE:
263  // this is a variable
264  ans = evalVariable(m_token);
265  getToken();
266  break;
267 
268  default:
269  // syntax error or unexpected end of expression
270  if (m_token.isEmpty())
271  {
272  m_err="Unexpected end of expression";
273  return FALSE;
274  }
275  else
276  {
277  m_err="Value expected";
278  return FALSE;
279  }
280  break;
281  }
282  return ans;
283 }
284 
288 bool CondParser::evalOperator(int opId, bool lhs, bool rhs)
289 {
290  switch (opId)
291  {
292  // level 2
293  case AND: return lhs && rhs;
294  case OR: return lhs || rhs;
295  }
296 
297  m_err = "Internal error unknown operator: id="+QCString().setNum(opId);
298  return FALSE;
299 }
300 
305 {
306  if (Config_getList(ENABLED_SECTIONS).find(varName)==-1) return FALSE;
307  return TRUE;
308 }
309