]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Common/Expression.py
BaseTools: Expression - remove redundant variable
[mirror_edk2.git] / BaseTools / Source / Python / Common / Expression.py
CommitLineData
0d2711a6
LG
1## @file\r
2# This file is used to parse and evaluate expression in directive or PCD value.\r
3#\r
35f613d9 4# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
0d2711a6
LG
5# This program and the accompanying materials\r
6# are licensed and made available under the terms and conditions of the BSD License\r
7# which accompanies this distribution. The full text of the license may be found at\r
8# http://opensource.org/licenses/bsd-license.php\r
9#\r
10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13## Import Modules\r
14#\r
15from Common.GlobalData import *\r
16from CommonDataClass.Exceptions import BadExpression\r
0d2711a6 17from CommonDataClass.Exceptions import WrnExpression\r
8565b582 18from Misc import GuidStringToGuidStructureString, ParseFieldValue, IsFieldValueAnArray\r
726c501c
YZ
19import Common.EdkLogger as EdkLogger\r
20import copy\r
0d2711a6
LG
21\r
22ERR_STRING_EXPR = 'This operator cannot be used in string expression: [%s].'\r
23ERR_SNYTAX = 'Syntax error, the rest of expression cannot be evaluated: [%s].'\r
24ERR_MATCH = 'No matching right parenthesis.'\r
25ERR_STRING_TOKEN = 'Bad string token: [%s].'\r
26ERR_MACRO_TOKEN = 'Bad macro token: [%s].'\r
27ERR_EMPTY_TOKEN = 'Empty token is not allowed.'\r
28ERR_PCD_RESOLVE = 'PCD token cannot be resolved: [%s].'\r
29ERR_VALID_TOKEN = 'No more valid token found from rest of string: [%s].'\r
30ERR_EXPR_TYPE = 'Different types found in expression.'\r
31ERR_OPERATOR_UNSUPPORT = 'Unsupported operator: [%s]'\r
32ERR_REL_NOT_IN = 'Expect "IN" after "not" operator.'\r
33WRN_BOOL_EXPR = 'Operand of boolean type cannot be used in arithmetic expression.'\r
34WRN_EQCMP_STR_OTHERS = '== Comparison between Operand of string type and Boolean/Number Type always return False.'\r
35WRN_NECMP_STR_OTHERS = '!= Comparison between Operand of string type and Boolean/Number Type always return True.'\r
36ERR_RELCMP_STR_OTHERS = 'Operator taking Operand of string type and Boolean/Number Type is not allowed: [%s].'\r
37ERR_STRING_CMP = 'Unicode string and general string cannot be compared: [%s %s %s]'\r
38ERR_ARRAY_TOKEN = 'Bad C array or C format GUID token: [%s].'\r
39ERR_ARRAY_ELE = 'This must be HEX value for NList or Array: [%s].'\r
d0acc87a 40ERR_EMPTY_EXPR = 'Empty expression is not allowed.'\r
64b2609f 41ERR_IN_OPERAND = 'Macro after IN operator can only be: $(FAMILY), $(ARCH), $(TOOL_CHAIN_TAG) and $(TARGET).'\r
0d2711a6
LG
42\r
43## SplitString\r
44# Split string to list according double quote\r
45# For example: abc"de\"f"ghi"jkl"mn will be: ['abc', '"de\"f"', 'ghi', '"jkl"', 'mn']\r
46#\r
47def SplitString(String):\r
ea927d2f 48 # There might be escaped quote: "abc\"def\\\"ghi", 'abc\'def\\\'ghi'\r
0d2711a6 49 RetList = []\r
ea927d2f
FY
50 InSingleQuote = False\r
51 InDoubleQuote = False\r
0d2711a6 52 Item = ''\r
ae4cc2b0 53 for i, ch in enumerate(String):\r
ea927d2f 54 if ch == '"' and not InSingleQuote:\r
ae4cc2b0 55 if String[i - 1] != '\\':\r
ea927d2f
FY
56 InDoubleQuote = not InDoubleQuote\r
57 if not InDoubleQuote:\r
58 Item += String[i]\r
59 RetList.append(Item)\r
60 Item = ''\r
61 continue\r
62 if Item:\r
63 RetList.append(Item)\r
64 Item = ''\r
65 elif ch == "'" and not InDoubleQuote:\r
ae4cc2b0 66 if String[i - 1] != '\\':\r
ea927d2f
FY
67 InSingleQuote = not InSingleQuote\r
68 if not InSingleQuote:\r
0d2711a6
LG
69 Item += String[i]\r
70 RetList.append(Item)\r
71 Item = ''\r
72 continue\r
73 if Item:\r
74 RetList.append(Item)\r
75 Item = ''\r
76 Item += String[i]\r
ea927d2f 77 if InSingleQuote or InDoubleQuote:\r
0d2711a6
LG
78 raise BadExpression(ERR_STRING_TOKEN % Item)\r
79 if Item:\r
80 RetList.append(Item)\r
81 return RetList\r
82\r
3be421e9
FY
83def SplitPcdValueString(String):\r
84 # There might be escaped comma in GUID() or DEVICE_PATH() or " "\r
85 # or ' ' or L' ' or L" "\r
3be421e9
FY
86 RetList = []\r
87 InParenthesis = 0\r
88 InSingleQuote = False\r
89 InDoubleQuote = False\r
90 Item = ''\r
ae4cc2b0 91 for i, ch in enumerate(String):\r
3be421e9
FY
92 if ch == '(':\r
93 InParenthesis += 1\r
94 if ch == ')':\r
95 if InParenthesis:\r
96 InParenthesis -= 1\r
97 else:\r
98 raise BadExpression(ERR_STRING_TOKEN % Item)\r
99 if ch == '"' and not InSingleQuote:\r
100 if String[i-1] != '\\':\r
101 InDoubleQuote = not InDoubleQuote\r
102 if ch == "'" and not InDoubleQuote:\r
103 if String[i-1] != '\\':\r
104 InSingleQuote = not InSingleQuote\r
105 if ch == ',':\r
106 if InParenthesis or InSingleQuote or InDoubleQuote:\r
107 Item += String[i]\r
108 continue\r
109 elif Item:\r
110 RetList.append(Item)\r
111 Item = ''\r
112 continue\r
113 Item += String[i]\r
114 if InSingleQuote or InDoubleQuote or InParenthesis:\r
115 raise BadExpression(ERR_STRING_TOKEN % Item)\r
116 if Item:\r
117 RetList.append(Item)\r
118 return RetList\r
119\r
5ac0a545
FY
120def IsValidCString(Str):\r
121 ValidString = re.compile(r'[_a-zA-Z][_0-9a-zA-Z]*$')\r
122 if not ValidString.match(Str):\r
123 return False\r
124 return True\r
125\r
8565b582
YZ
126def BuildOptionValue(PcdValue, GuidDict):\r
127 IsArray = False\r
128 if PcdValue.startswith('H'):\r
129 InputValue = PcdValue[1:]\r
130 elif PcdValue.startswith("L'") or PcdValue.startswith("'"):\r
131 InputValue = PcdValue\r
132 elif PcdValue.startswith('L'):\r
133 InputValue = 'L"' + PcdValue[1:] + '"'\r
134 else:\r
135 InputValue = PcdValue\r
136 if IsFieldValueAnArray(InputValue):\r
137 IsArray = True\r
138 if IsArray:\r
139 try:\r
140 PcdValue = ValueExpressionEx(InputValue, 'VOID*', GuidDict)(True)\r
141 except:\r
142 pass\r
143 return PcdValue\r
144\r
0d2711a6
LG
145## ReplaceExprMacro\r
146#\r
147def ReplaceExprMacro(String, Macros, ExceptionList = None):\r
148 StrList = SplitString(String)\r
149 for i, String in enumerate(StrList):\r
150 InQuote = False\r
151 if String.startswith('"'):\r
152 InQuote = True\r
153 MacroStartPos = String.find('$(')\r
154 if MacroStartPos < 0:\r
c8d07c5e
YZ
155 for Pcd in gPlatformPcds.keys():\r
156 if Pcd in String:\r
157 if Pcd not in gConditionalPcds:\r
158 gConditionalPcds.append(Pcd)\r
0d2711a6
LG
159 continue\r
160 RetStr = ''\r
161 while MacroStartPos >= 0:\r
162 RetStr = String[0:MacroStartPos]\r
163 MacroEndPos = String.find(')', MacroStartPos)\r
164 if MacroEndPos < 0:\r
165 raise BadExpression(ERR_MACRO_TOKEN % String[MacroStartPos:])\r
166 Macro = String[MacroStartPos+2:MacroEndPos]\r
167 if Macro not in Macros:\r
168 # From C reference manual:\r
169 # If an undefined macro name appears in the constant-expression of\r
170 # !if or !elif, it is replaced by the integer constant 0.\r
171 RetStr += '0'\r
64b2609f
LG
172 elif not InQuote:\r
173 Tklst = RetStr.split()\r
174 if Tklst and Tklst[-1] in ['IN', 'in'] and ExceptionList and Macro not in ExceptionList:\r
175 raise BadExpression(ERR_IN_OPERAND)\r
0d2711a6
LG
176 # Make sure the macro in exception list is encapsulated by double quote\r
177 # For example: DEFINE ARCH = IA32 X64\r
178 # $(ARCH) is replaced with "IA32 X64"\r
64b2609f
LG
179 if ExceptionList and Macro in ExceptionList:\r
180 RetStr += '"' + Macros[Macro] + '"'\r
181 elif Macros[Macro].strip():\r
0d2711a6
LG
182 RetStr += Macros[Macro]\r
183 else:\r
184 RetStr += '""'\r
64b2609f
LG
185 else:\r
186 RetStr += Macros[Macro]\r
0d2711a6
LG
187 RetStr += String[MacroEndPos+1:]\r
188 String = RetStr\r
189 MacroStartPos = String.find('$(')\r
190 StrList[i] = RetStr\r
191 return ''.join(StrList)\r
192\r
726c501c
YZ
193# transfer int to string for in/not in expression\r
194def IntToStr(Value):\r
195 StrList = []\r
196 while Value > 0:\r
197 StrList.append(chr(Value & 0xff))\r
198 Value = Value >> 8\r
199 Value = '"' + ''.join(StrList) + '"'\r
200 return Value\r
201\r
64b2609f
LG
202SupportedInMacroList = ['TARGET', 'TOOL_CHAIN_TAG', 'ARCH', 'FAMILY']\r
203\r
0d2711a6
LG
204class ValueExpression(object):\r
205 # Logical operator mapping\r
206 LogicalOperators = {\r
207 '&&' : 'and', '||' : 'or',\r
208 '!' : 'not', 'AND': 'and',\r
209 'OR' : 'or' , 'NOT': 'not',\r
210 'XOR': '^' , 'xor': '^',\r
211 'EQ' : '==' , 'NE' : '!=',\r
212 'GT' : '>' , 'LT' : '<',\r
213 'GE' : '>=' , 'LE' : '<=',\r
214 'IN' : 'in'\r
215 }\r
216\r
bc0d7233 217 NonLetterOpLst = ['+', '-', '*', '/', '%', '&', '|', '^', '~', '<<', '>>', '!', '=', '>', '<', '?', ':']\r
0d2711a6
LG
218\r
219 PcdPattern = re.compile(r'[_a-zA-Z][0-9A-Za-z_]*\.[_a-zA-Z][0-9A-Za-z_]*$')\r
220 HexPattern = re.compile(r'0[xX][0-9a-fA-F]+$')\r
221 RegGuidPattern = re.compile(r'[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}')\r
222\r
223 SymbolPattern = re.compile("("\r
224 "\$\([A-Z][A-Z0-9_]*\)|\$\(\w+\.\w+\)|\w+\.\w+|"\r
225 "&&|\|\||!(?!=)|"\r
226 "(?<=\W)AND(?=\W)|(?<=\W)OR(?=\W)|(?<=\W)NOT(?=\W)|(?<=\W)XOR(?=\W)|"\r
227 "(?<=\W)EQ(?=\W)|(?<=\W)NE(?=\W)|(?<=\W)GT(?=\W)|(?<=\W)LT(?=\W)|(?<=\W)GE(?=\W)|(?<=\W)LE(?=\W)"\r
228 ")")\r
229\r
230 @staticmethod\r
231 def Eval(Operator, Oprand1, Oprand2 = None):\r
232 WrnExp = None\r
d0acc87a 233\r
9efe8d60
YF
234 if Operator not in ["==", "!=", ">=", "<=", ">", "<", "in", "not in"] and \\r
235 (type(Oprand1) == type('') or type(Oprand2) == type('')):\r
236 raise BadExpression(ERR_STRING_EXPR % Operator)\r
726c501c
YZ
237 if Operator in ['in', 'not in']:\r
238 if type(Oprand1) != type(''):\r
239 Oprand1 = IntToStr(Oprand1)\r
240 if type(Oprand2) != type(''):\r
241 Oprand2 = IntToStr(Oprand2)\r
0d2711a6
LG
242 TypeDict = {\r
243 type(0) : 0,\r
244 type(0L) : 0,\r
245 type('') : 1,\r
246 type(True) : 2\r
247 }\r
248\r
249 EvalStr = ''\r
250 if Operator in ["!", "NOT", "not"]:\r
251 if type(Oprand1) == type(''):\r
252 raise BadExpression(ERR_STRING_EXPR % Operator)\r
253 EvalStr = 'not Oprand1'\r
5e06f1a0
YZ
254 elif Operator in ["~"]:\r
255 if type(Oprand1) == type(''):\r
256 raise BadExpression(ERR_STRING_EXPR % Operator)\r
257 EvalStr = '~ Oprand1'\r
0d2711a6
LG
258 else:\r
259 if Operator in ["+", "-"] and (type(True) in [type(Oprand1), type(Oprand2)]):\r
260 # Boolean in '+'/'-' will be evaluated but raise warning\r
261 WrnExp = WrnExpression(WRN_BOOL_EXPR)\r
262 elif type('') in [type(Oprand1), type(Oprand2)] and type(Oprand1)!= type(Oprand2):\r
263 # == between string and number/boolean will always return False, != return True\r
264 if Operator == "==":\r
265 WrnExp = WrnExpression(WRN_EQCMP_STR_OTHERS)\r
266 WrnExp.result = False\r
267 raise WrnExp\r
268 elif Operator == "!=":\r
269 WrnExp = WrnExpression(WRN_NECMP_STR_OTHERS)\r
270 WrnExp.result = True\r
271 raise WrnExp\r
272 else:\r
273 raise BadExpression(ERR_RELCMP_STR_OTHERS % Operator)\r
d0acc87a 274 elif TypeDict[type(Oprand1)] != TypeDict[type(Oprand2)]:\r
0d2711a6
LG
275 if Operator in ["==", "!=", ">=", "<=", ">", "<"] and set((TypeDict[type(Oprand1)], TypeDict[type(Oprand2)])) == set((TypeDict[type(True)], TypeDict[type(0)])):\r
276 # comparison between number and boolean is allowed\r
277 pass\r
d0acc87a 278 elif Operator in ['&', '|', '^', "and", "or"] and set((TypeDict[type(Oprand1)], TypeDict[type(Oprand2)])) == set((TypeDict[type(True)], TypeDict[type(0)])):\r
0d2711a6 279 # bitwise and logical operation between number and boolean is allowed\r
d0acc87a 280 pass\r
0d2711a6
LG
281 else:\r
282 raise BadExpression(ERR_EXPR_TYPE)\r
283 if type(Oprand1) == type('') and type(Oprand2) == type(''):\r
284 if (Oprand1.startswith('L"') and not Oprand2.startswith('L"')) or \\r
285 (not Oprand1.startswith('L"') and Oprand2.startswith('L"')):\r
286 raise BadExpression(ERR_STRING_CMP % (Oprand1, Operator, Oprand2))\r
287 if 'in' in Operator and type(Oprand2) == type(''):\r
288 Oprand2 = Oprand2.split()\r
289 EvalStr = 'Oprand1 ' + Operator + ' Oprand2'\r
290\r
291 # Local symbols used by built in eval function\r
292 Dict = {\r
293 'Oprand1' : Oprand1,\r
294 'Oprand2' : Oprand2\r
295 }\r
296 try:\r
297 Val = eval(EvalStr, {}, Dict)\r
298 except Exception, Excpt:\r
299 raise BadExpression(str(Excpt))\r
300\r
301 if Operator in ['and', 'or']:\r
302 if Val:\r
303 Val = True\r
304 else:\r
305 Val = False\r
d0acc87a 306\r
0d2711a6
LG
307 if WrnExp:\r
308 WrnExp.result = Val\r
309 raise WrnExp\r
310 return Val\r
311\r
312 def __init__(self, Expression, SymbolTable={}):\r
313 self._NoProcess = False\r
314 if type(Expression) != type(''):\r
315 self._Expr = Expression\r
316 self._NoProcess = True\r
317 return\r
318\r
319 self._Expr = ReplaceExprMacro(Expression.strip(),\r
320 SymbolTable,\r
64b2609f 321 SupportedInMacroList)\r
0d2711a6
LG
322\r
323 if not self._Expr.strip():\r
d0acc87a 324 raise BadExpression(ERR_EMPTY_EXPR)\r
0d2711a6
LG
325\r
326 #\r
327 # The symbol table including PCD and macro mapping\r
328 #\r
726c501c 329 self._Symb = copy.deepcopy(SymbolTable)\r
0d2711a6
LG
330 self._Symb.update(self.LogicalOperators)\r
331 self._Idx = 0\r
332 self._Len = len(self._Expr)\r
333 self._Token = ''\r
d0acc87a 334 self._WarnExcept = None\r
0d2711a6
LG
335\r
336 # Literal token without any conversion\r
337 self._LiteralToken = ''\r
338\r
339 # Public entry for this class\r
d0acc87a
LG
340 # @param RealValue: False: only evaluate if the expression is true or false, used for conditional expression\r
341 # True : return the evaluated str(value), used for PCD value\r
342 #\r
343 # @return: True or False if RealValue is False\r
344 # Evaluated value of string format if RealValue is True\r
345 #\r
4afd3d04 346 def __call__(self, RealValue=False, Depth=0):\r
0d2711a6
LG
347 if self._NoProcess:\r
348 return self._Expr\r
349\r
4afd3d04
LG
350 self._Depth = Depth\r
351\r
d0acc87a 352 self._Expr = self._Expr.strip()\r
4afd3d04 353 if RealValue and Depth == 0:\r
d0acc87a
LG
354 self._Token = self._Expr\r
355 if self.__IsNumberToken():\r
356 return self._Expr\r
35f613d9 357 Token = ''\r
25918452
LG
358 try:\r
359 Token = self._GetToken()\r
25918452
LG
360 except BadExpression:\r
361 pass\r
35f613d9 362 if type(Token) == type('') and Token.startswith('{') and Token.endswith('}') and self._Idx >= self._Len:\r
35f613d9 363 return self._Expr\r
d0acc87a
LG
364\r
365 self._Idx = 0\r
366 self._Token = ''\r
367\r
bc0d7233 368 Val = self._ConExpr()\r
d0acc87a
LG
369 RealVal = Val\r
370 if type(Val) == type(''):\r
371 if Val == 'L""':\r
372 Val = False\r
373 elif not Val:\r
374 Val = False\r
375 RealVal = '""'\r
726c501c 376 elif not Val.startswith('L"') and not Val.startswith('{') and not Val.startswith("L'"):\r
d0acc87a
LG
377 Val = True\r
378 RealVal = '"' + RealVal + '"'\r
0d2711a6
LG
379\r
380 # The expression has been parsed, but the end of expression is not reached\r
381 # It means the rest does not comply EBNF of <Expression>\r
382 if self._Idx != self._Len:\r
383 raise BadExpression(ERR_SNYTAX % self._Expr[self._Idx:])\r
384\r
d0acc87a
LG
385 if RealValue:\r
386 RetVal = str(RealVal)\r
387 elif Val:\r
388 RetVal = True\r
389 else:\r
390 RetVal = False\r
391\r
392 if self._WarnExcept:\r
393 self._WarnExcept.result = RetVal\r
394 raise self._WarnExcept\r
395 else:\r
396 return RetVal\r
0d2711a6
LG
397\r
398 # Template function to parse binary operators which have same precedence\r
399 # Expr [Operator Expr]*\r
400 def _ExprFuncTemplate(self, EvalFunc, OpLst):\r
401 Val = EvalFunc()\r
402 while self._IsOperator(OpLst):\r
403 Op = self._Token\r
bc0d7233
YF
404 if Op == '?':\r
405 Val2 = EvalFunc()\r
406 if self._IsOperator(':'):\r
407 Val3 = EvalFunc()\r
408 if Val:\r
409 Val = Val2\r
410 else:\r
411 Val = Val3\r
412 continue\r
d0acc87a
LG
413 try:\r
414 Val = self.Eval(Op, Val, EvalFunc())\r
415 except WrnExpression, Warn:\r
416 self._WarnExcept = Warn\r
417 Val = Warn.result\r
0d2711a6 418 return Val\r
bc0d7233
YF
419 # A [? B]*\r
420 def _ConExpr(self):\r
421 return self._ExprFuncTemplate(self._OrExpr, ['?', ':'])\r
0d2711a6
LG
422\r
423 # A [|| B]*\r
424 def _OrExpr(self):\r
425 return self._ExprFuncTemplate(self._AndExpr, ["OR", "or", "||"])\r
426\r
427 # A [&& B]*\r
428 def _AndExpr(self):\r
429 return self._ExprFuncTemplate(self._BitOr, ["AND", "and", "&&"])\r
430\r
431 # A [ | B]*\r
432 def _BitOr(self):\r
433 return self._ExprFuncTemplate(self._BitXor, ["|"])\r
434\r
435 # A [ ^ B]*\r
436 def _BitXor(self):\r
437 return self._ExprFuncTemplate(self._BitAnd, ["XOR", "xor", "^"])\r
438\r
439 # A [ & B]*\r
440 def _BitAnd(self):\r
441 return self._ExprFuncTemplate(self._EqExpr, ["&"])\r
442\r
443 # A [ == B]*\r
444 def _EqExpr(self):\r
445 Val = self._RelExpr()\r
446 while self._IsOperator(["==", "!=", "EQ", "NE", "IN", "in", "!", "NOT", "not"]):\r
447 Op = self._Token\r
448 if Op in ["!", "NOT", "not"]:\r
449 if not self._IsOperator(["IN", "in"]):\r
450 raise BadExpression(ERR_REL_NOT_IN)\r
451 Op += ' ' + self._Token\r
d0acc87a
LG
452 try:\r
453 Val = self.Eval(Op, Val, self._RelExpr())\r
454 except WrnExpression, Warn:\r
455 self._WarnExcept = Warn\r
456 Val = Warn.result\r
0d2711a6
LG
457 return Val\r
458\r
459 # A [ > B]*\r
460 def _RelExpr(self):\r
5e06f1a0
YZ
461 return self._ExprFuncTemplate(self._ShiftExpr, ["<=", ">=", "<", ">", "LE", "GE", "LT", "GT"])\r
462\r
463 def _ShiftExpr(self):\r
464 return self._ExprFuncTemplate(self._AddExpr, ["<<", ">>"])\r
0d2711a6
LG
465\r
466 # A [ + B]*\r
467 def _AddExpr(self):\r
5e06f1a0
YZ
468 return self._ExprFuncTemplate(self._MulExpr, ["+", "-"])\r
469\r
470 # A [ * B]*\r
471 def _MulExpr(self):\r
472 return self._ExprFuncTemplate(self._UnaryExpr, ["*", "/", "%"])\r
0d2711a6
LG
473\r
474 # [!]*A\r
475 def _UnaryExpr(self):\r
476 if self._IsOperator(["!", "NOT", "not"]):\r
477 Val = self._UnaryExpr()\r
d0acc87a
LG
478 try:\r
479 return self.Eval('not', Val)\r
480 except WrnExpression, Warn:\r
481 self._WarnExcept = Warn\r
482 return Warn.result\r
5e06f1a0
YZ
483 if self._IsOperator(["~"]):\r
484 Val = self._UnaryExpr()\r
485 try:\r
486 return self.Eval('~', Val)\r
487 except WrnExpression, Warn:\r
488 self._WarnExcept = Warn\r
489 return Warn.result\r
0d2711a6
LG
490 return self._IdenExpr()\r
491\r
492 # Parse identifier or encapsulated expression\r
493 def _IdenExpr(self):\r
494 Tk = self._GetToken()\r
495 if Tk == '(':\r
bc0d7233 496 Val = self._ConExpr()\r
0d2711a6
LG
497 try:\r
498 # _GetToken may also raise BadExpression\r
499 if self._GetToken() != ')':\r
500 raise BadExpression(ERR_MATCH)\r
501 except BadExpression:\r
502 raise BadExpression(ERR_MATCH)\r
503 return Val\r
504 return Tk\r
505\r
506 # Skip whitespace or tab\r
507 def __SkipWS(self):\r
508 for Char in self._Expr[self._Idx:]:\r
509 if Char not in ' \t':\r
510 break\r
511 self._Idx += 1\r
512\r
513 # Try to convert string to number\r
514 def __IsNumberToken(self):\r
515 Radix = 10\r
516 if self._Token.lower()[0:2] == '0x' and len(self._Token) > 2:\r
517 Radix = 16\r
35f613d9
YF
518 if self._Token.startswith('"') or self._Token.startswith('L"'):\r
519 Flag = 0\r
520 for Index in range(len(self._Token)):\r
521 if self._Token[Index] in ['"']:\r
ea927d2f
FY
522 if self._Token[Index - 1] == '\\':\r
523 continue\r
35f613d9
YF
524 Flag += 1\r
525 if Flag == 2 and self._Token.endswith('"'):\r
35f613d9
YF
526 return True\r
527 if self._Token.startswith("'") or self._Token.startswith("L'"):\r
726c501c
YZ
528 Flag = 0\r
529 for Index in range(len(self._Token)):\r
35f613d9 530 if self._Token[Index] in ["'"]:\r
ea927d2f
FY
531 if self._Token[Index - 1] == '\\':\r
532 continue\r
726c501c 533 Flag += 1\r
35f613d9 534 if Flag == 2 and self._Token.endswith("'"):\r
726c501c 535 return True\r
0d2711a6
LG
536 try:\r
537 self._Token = int(self._Token, Radix)\r
538 return True\r
539 except ValueError:\r
540 return False\r
541 except TypeError:\r
542 return False\r
543\r
544 # Parse array: {...}\r
545 def __GetArray(self):\r
546 Token = '{'\r
547 self._Idx += 1\r
548 self.__GetNList(True)\r
549 Token += self._LiteralToken\r
550 if self._Idx >= self._Len or self._Expr[self._Idx] != '}':\r
551 raise BadExpression(ERR_ARRAY_TOKEN % Token)\r
552 Token += '}'\r
553\r
554 # All whitespace and tabs in array are already stripped.\r
555 IsArray = IsGuid = False\r
556 if len(Token.split(',')) == 11 and len(Token.split(',{')) == 2 \\r
557 and len(Token.split('},')) == 1:\r
558 HexLen = [11,6,6,5,4,4,4,4,4,4,6]\r
559 HexList= Token.split(',')\r
560 if HexList[3].startswith('{') and \\r
561 not [Index for Index, Hex in enumerate(HexList) if len(Hex) > HexLen[Index]]:\r
562 IsGuid = True\r
563 if Token.lstrip('{').rstrip('}').find('{') == -1:\r
564 if not [Hex for Hex in Token.lstrip('{').rstrip('}').split(',') if len(Hex) > 4]:\r
565 IsArray = True\r
566 if not IsArray and not IsGuid:\r
567 raise BadExpression(ERR_ARRAY_TOKEN % Token)\r
568 self._Idx += 1\r
569 self._Token = self._LiteralToken = Token\r
570 return self._Token\r
571\r
572 # Parse string, the format must be: "..."\r
573 def __GetString(self):\r
574 Idx = self._Idx\r
575\r
576 # Skip left quote\r
577 self._Idx += 1\r
578\r
579 # Replace escape \\\", \"\r
ea927d2f
FY
580 if self._Expr[Idx] == '"':\r
581 Expr = self._Expr[self._Idx:].replace('\\\\', '//').replace('\\\"', '\\\'')\r
582 for Ch in Expr:\r
583 self._Idx += 1\r
584 if Ch == '"':\r
585 break\r
586 self._Token = self._LiteralToken = self._Expr[Idx:self._Idx]\r
587 if not self._Token.endswith('"'):\r
588 raise BadExpression(ERR_STRING_TOKEN % self._Token)\r
589 #Replace escape \\\', \'\r
590 elif self._Expr[Idx] == "'":\r
591 Expr = self._Expr[self._Idx:].replace('\\\\', '//').replace("\\\'", "\\\"")\r
592 for Ch in Expr:\r
593 self._Idx += 1\r
594 if Ch == "'":\r
595 break\r
596 self._Token = self._LiteralToken = self._Expr[Idx:self._Idx]\r
597 if not self._Token.endswith("'"):\r
598 raise BadExpression(ERR_STRING_TOKEN % self._Token)\r
0d2711a6
LG
599 self._Token = self._Token[1:-1]\r
600 return self._Token\r
601\r
602 # Get token that is comprised by alphanumeric, underscore or dot(used by PCD)\r
603 # @param IsAlphaOp: Indicate if parsing general token or script operator(EQ, NE...)\r
604 def __GetIdToken(self, IsAlphaOp = False):\r
605 IdToken = ''\r
606 for Ch in self._Expr[self._Idx:]:\r
bc0d7233 607 if not self.__IsIdChar(Ch) or ('?' in self._Expr and Ch == ':'):\r
0d2711a6
LG
608 break\r
609 self._Idx += 1\r
610 IdToken += Ch\r
611\r
612 self._Token = self._LiteralToken = IdToken\r
613 if not IsAlphaOp:\r
614 self.__ResolveToken()\r
615 return self._Token\r
616\r
617 # Try to resolve token\r
618 def __ResolveToken(self):\r
619 if not self._Token:\r
620 raise BadExpression(ERR_EMPTY_TOKEN)\r
621\r
622 # PCD token\r
623 if self.PcdPattern.match(self._Token):\r
624 if self._Token not in self._Symb:\r
64b2609f
LG
625 Ex = BadExpression(ERR_PCD_RESOLVE % self._Token)\r
626 Ex.Pcd = self._Token\r
627 raise Ex\r
4afd3d04 628 self._Token = ValueExpression(self._Symb[self._Token], self._Symb)(True, self._Depth+1)\r
0d2711a6
LG
629 if type(self._Token) != type(''):\r
630 self._LiteralToken = hex(self._Token)\r
631 return\r
632\r
633 if self._Token.startswith('"'):\r
634 self._Token = self._Token[1:-1]\r
635 elif self._Token in ["FALSE", "false", "False"]:\r
636 self._Token = False\r
637 elif self._Token in ["TRUE", "true", "True"]:\r
638 self._Token = True\r
639 else:\r
640 self.__IsNumberToken()\r
641\r
642 def __GetNList(self, InArray=False):\r
643 self._GetSingleToken()\r
644 if not self.__IsHexLiteral():\r
645 if InArray:\r
646 raise BadExpression(ERR_ARRAY_ELE % self._Token)\r
647 return self._Token\r
648\r
649 self.__SkipWS()\r
650 Expr = self._Expr[self._Idx:]\r
651 if not Expr.startswith(','):\r
652 return self._Token\r
653\r
654 NList = self._LiteralToken\r
655 while Expr.startswith(','):\r
656 NList += ','\r
657 self._Idx += 1\r
658 self.__SkipWS()\r
659 self._GetSingleToken()\r
660 if not self.__IsHexLiteral():\r
661 raise BadExpression(ERR_ARRAY_ELE % self._Token)\r
662 NList += self._LiteralToken\r
663 self.__SkipWS()\r
664 Expr = self._Expr[self._Idx:]\r
665 self._Token = self._LiteralToken = NList\r
666 return self._Token\r
667\r
668 def __IsHexLiteral(self):\r
669 if self._LiteralToken.startswith('{') and \\r
670 self._LiteralToken.endswith('}'):\r
671 return True\r
672\r
673 if self.HexPattern.match(self._LiteralToken):\r
674 Token = self._LiteralToken[2:]\r
0d2711a6
LG
675 if not Token:\r
676 self._LiteralToken = '0x0'\r
677 else:\r
35f613d9 678 self._LiteralToken = '0x' + Token\r
0d2711a6
LG
679 return True\r
680 return False\r
681\r
682 def _GetToken(self):\r
683 return self.__GetNList()\r
684\r
685 @staticmethod\r
686 def __IsIdChar(Ch):\r
5e06f1a0 687 return Ch in '._:' or Ch.isalnum()\r
0d2711a6
LG
688\r
689 # Parse operand\r
690 def _GetSingleToken(self):\r
691 self.__SkipWS()\r
692 Expr = self._Expr[self._Idx:]\r
693 if Expr.startswith('L"'):\r
694 # Skip L\r
695 self._Idx += 1\r
696 UStr = self.__GetString()\r
697 self._Token = 'L"' + UStr + '"'\r
726c501c
YZ
698 return self._Token\r
699 elif Expr.startswith("L'"):\r
700 # Skip L\r
701 self._Idx += 1\r
702 UStr = self.__GetString()\r
703 self._Token = "L'" + UStr + "'"\r
0d2711a6 704 return self._Token\r
726c501c
YZ
705 elif Expr.startswith("'"):\r
706 UStr = self.__GetString()\r
707 self._Token = "'" + UStr + "'"\r
726c501c
YZ
708 return self._Token\r
709 elif Expr.startswith('UINT'):\r
710 Re = re.compile('(?:UINT8|UINT16|UINT32|UINT64)\((.+)\)')\r
711 try:\r
712 RetValue = Re.search(Expr).group(1)\r
713 except:\r
714 raise BadExpression('Invalid Expression %s' % Expr)\r
715 Idx = self._Idx\r
716 for Ch in Expr:\r
717 self._Idx += 1\r
718 if Ch == '(':\r
719 Prefix = self._Expr[Idx:self._Idx - 1]\r
720 Idx = self._Idx\r
721 if Ch == ')':\r
722 TmpValue = self._Expr[Idx :self._Idx - 1]\r
723 TmpValue = ValueExpression(TmpValue)(True)\r
724 TmpValue = '0x%x' % int(TmpValue) if type(TmpValue) != type('') else TmpValue\r
725 break\r
726 self._Token, Size = ParseFieldValue(Prefix + '(' + TmpValue + ')')\r
727 return self._Token\r
0d2711a6
LG
728\r
729 self._Token = ''\r
730 if Expr:\r
731 Ch = Expr[0]\r
732 Match = self.RegGuidPattern.match(Expr)\r
733 if Match and not Expr[Match.end():Match.end()+1].isalnum() \\r
734 and Expr[Match.end():Match.end()+1] != '_':\r
735 self._Idx += Match.end()\r
4afd3d04 736 self._Token = ValueExpression(GuidStringToGuidStructureString(Expr[0:Match.end()]))(True, self._Depth+1)\r
0d2711a6
LG
737 return self._Token\r
738 elif self.__IsIdChar(Ch):\r
739 return self.__GetIdToken()\r
740 elif Ch == '"':\r
741 return self.__GetString()\r
742 elif Ch == '{':\r
743 return self.__GetArray()\r
744 elif Ch == '(' or Ch == ')':\r
745 self._Idx += 1\r
746 self._Token = Ch\r
747 return self._Token\r
748\r
749 raise BadExpression(ERR_VALID_TOKEN % Expr)\r
750\r
751 # Parse operator\r
752 def _GetOperator(self):\r
753 self.__SkipWS()\r
bc0d7233 754 LegalOpLst = ['&&', '||', '!=', '==', '>=', '<='] + self.NonLetterOpLst + ['?',':']\r
0d2711a6
LG
755\r
756 self._Token = ''\r
757 Expr = self._Expr[self._Idx:]\r
758\r
759 # Reach end of expression\r
760 if not Expr:\r
761 return ''\r
762\r
763 # Script operator: LT, GT, LE, GE, EQ, NE, and, or, xor, not\r
764 if Expr[0].isalpha():\r
765 return self.__GetIdToken(True)\r
766\r
767 # Start to get regular operator: +, -, <, > ...\r
768 if Expr[0] not in self.NonLetterOpLst:\r
769 return ''\r
770\r
771 OpToken = ''\r
772 for Ch in Expr:\r
773 if Ch in self.NonLetterOpLst:\r
d0acc87a 774 if '!' == Ch and OpToken:\r
0d2711a6
LG
775 break\r
776 self._Idx += 1\r
777 OpToken += Ch\r
778 else:\r
779 break\r
780\r
781 if OpToken not in LegalOpLst:\r
782 raise BadExpression(ERR_OPERATOR_UNSUPPORT % OpToken)\r
783 self._Token = OpToken\r
784 return OpToken\r
785\r
786 # Check if current token matches the operators given from OpList\r
787 def _IsOperator(self, OpList):\r
788 Idx = self._Idx\r
789 self._GetOperator()\r
790 if self._Token in OpList:\r
791 if self._Token in self.LogicalOperators:\r
792 self._Token = self.LogicalOperators[self._Token]\r
793 return True\r
794 self._Idx = Idx\r
795 return False\r
796\r
726c501c
YZ
797class ValueExpressionEx(ValueExpression):\r
798 def __init__(self, PcdValue, PcdType, SymbolTable={}):\r
799 ValueExpression.__init__(self, PcdValue, SymbolTable)\r
800 self.PcdValue = PcdValue\r
801 self.PcdType = PcdType\r
802\r
803 def __call__(self, RealValue=False, Depth=0):\r
804 PcdValue = self.PcdValue\r
805 try:\r
806 PcdValue = ValueExpression.__call__(self, RealValue, Depth)\r
35f613d9 807 if self.PcdType == 'VOID*' and (PcdValue.startswith("'") or PcdValue.startswith("L'")):\r
0e6b8673
FY
808 PcdValue, Size = ParseFieldValue(PcdValue)\r
809 PcdValueList = []\r
810 for I in range(Size):\r
811 PcdValueList.append('0x%02X'%(PcdValue & 0xff))\r
812 PcdValue = PcdValue >> 8\r
813 PcdValue = '{' + ','.join(PcdValueList) + '}'\r
35f613d9
YF
814 elif self.PcdType in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN'] and (PcdValue.startswith("'") or \\r
815 PcdValue.startswith('"') or PcdValue.startswith("L'") or PcdValue.startswith('L"') or PcdValue.startswith('{')):\r
816 raise BadExpression\r
726c501c
YZ
817 except WrnExpression, Value:\r
818 PcdValue = Value.result\r
9efe8d60 819 except BadExpression, Value:\r
35f613d9
YF
820 if self.PcdType in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:\r
821 PcdValue = PcdValue.strip()\r
822 if type(PcdValue) == type('') and PcdValue.startswith('{') and PcdValue.endswith('}'):\r
3be421e9 823 PcdValue = SplitPcdValueString(PcdValue[1:-1])\r
35f613d9
YF
824 if type(PcdValue) == type([]):\r
825 TmpValue = 0\r
726c501c 826 Size = 0\r
3be421e9 827 ValueType = ''\r
35f613d9 828 for Item in PcdValue:\r
3be421e9 829 Item = Item.strip()\r
0e6b8673
FY
830 if Item.startswith('UINT8'):\r
831 ItemSize = 1\r
3be421e9
FY
832 ValueType = 'UINT8'\r
833 elif Item.startswith('UINT16'):\r
35f613d9 834 ItemSize = 2\r
3be421e9 835 ValueType = 'UINT16'\r
35f613d9
YF
836 elif Item.startswith('UINT32'):\r
837 ItemSize = 4\r
3be421e9 838 ValueType = 'UINT32'\r
35f613d9
YF
839 elif Item.startswith('UINT64'):\r
840 ItemSize = 8\r
3be421e9
FY
841 ValueType = 'UINT64'\r
842 elif Item.startswith('"') or Item.startswith("'") or Item.startswith('L'):\r
843 ItemSize = 0\r
844 ValueType = 'VOID*'\r
35f613d9
YF
845 else:\r
846 ItemSize = 0\r
3be421e9
FY
847 ValueType = 'UINT8'\r
848 Item = ValueExpressionEx(Item, ValueType, self._Symb)(True)\r
35f613d9
YF
849\r
850 if ItemSize == 0:\r
3be421e9
FY
851 try:\r
852 tmpValue = int(Item, 16) if Item.upper().startswith('0X') else int(Item, 0)\r
853 if tmpValue > 255:\r
854 raise BadExpression("Byte array number %s should less than 0xFF." % Item)\r
855 except BadExpression, Value:\r
856 raise BadExpression(Value)\r
857 except ValueError:\r
858 pass\r
35f613d9
YF
859 ItemValue, ItemSize = ParseFieldValue(Item)\r
860 else:\r
861 ItemValue = ParseFieldValue(Item)[0]\r
862\r
863 if type(ItemValue) == type(''):\r
864 ItemValue = int(ItemValue, 16) if ItemValue.startswith('0x') else int(ItemValue)\r
865\r
866 TmpValue = (ItemValue << (Size * 8)) | TmpValue\r
867 Size = Size + ItemSize\r
868 else:\r
0e6b8673
FY
869 try:\r
870 TmpValue, Size = ParseFieldValue(PcdValue)\r
9efe8d60
YF
871 except BadExpression, Value:\r
872 raise BadExpression("Type: %s, Value: %s, %s" % (self.PcdType, PcdValue, Value))\r
35f613d9 873 if type(TmpValue) == type(''):\r
9efe8d60
YF
874 try:\r
875 TmpValue = int(TmpValue)\r
876 except:\r
877 raise BadExpression(Value)\r
35f613d9
YF
878 else:\r
879 PcdValue = '0x%0{}X'.format(Size) % (TmpValue)\r
880 if TmpValue < 0:\r
881 raise BadExpression('Type %s PCD Value is negative' % self.PcdType)\r
882 if self.PcdType == 'UINT8' and Size > 1:\r
883 raise BadExpression('Type %s PCD Value Size is Larger than 1 byte' % self.PcdType)\r
884 if self.PcdType == 'UINT16' and Size > 2:\r
885 raise BadExpression('Type %s PCD Value Size is Larger than 2 byte' % self.PcdType)\r
886 if self.PcdType == 'UINT32' and Size > 4:\r
887 raise BadExpression('Type %s PCD Value Size is Larger than 4 byte' % self.PcdType)\r
888 if self.PcdType == 'UINT64' and Size > 8:\r
889 raise BadExpression('Type %s PCD Value Size is Larger than 8 byte' % self.PcdType)\r
6f49996c 890 else:\r
35f613d9
YF
891 try:\r
892 TmpValue = long(PcdValue)\r
893 TmpList = []\r
894 if TmpValue.bit_length() == 0:\r
895 PcdValue = '{0x00}'\r
726c501c 896 else:\r
35f613d9
YF
897 for I in range((TmpValue.bit_length() + 7) / 8):\r
898 TmpList.append('0x%02x' % ((TmpValue >> I * 8) & 0xff))\r
899 PcdValue = '{' + ', '.join(TmpList) + '}'\r
900 except:\r
901 if PcdValue.strip().startswith('{'):\r
3be421e9
FY
902 PcdValueList = SplitPcdValueString(PcdValue.strip()[1:-1])\r
903 LabelDict = {}\r
904 NewPcdValueList = []\r
905 ReLabel = re.compile('LABEL\((\w+)\)')\r
906 ReOffset = re.compile('OFFSET_OF\((\w+)\)')\r
907 LabelOffset = 0\r
908 for Index, Item in enumerate(PcdValueList):\r
909 # compute byte offset of every LABEL\r
5ac0a545 910 LabelList = ReLabel.findall(Item)\r
b31501c9
FY
911 Item = ReLabel.sub('', Item)\r
912 Item = Item.strip()\r
5ac0a545 913 if LabelList:\r
3be421e9 914 for Label in LabelList:\r
5ac0a545
FY
915 if not IsValidCString(Label):\r
916 raise BadExpression('%s is not a valid c variable name' % Label)\r
3be421e9
FY
917 if Label not in LabelDict.keys():\r
918 LabelDict[Label] = str(LabelOffset)\r
3be421e9
FY
919 if Item.startswith('UINT8'):\r
920 LabelOffset = LabelOffset + 1\r
921 elif Item.startswith('UINT16'):\r
922 LabelOffset = LabelOffset + 2\r
923 elif Item.startswith('UINT32'):\r
924 LabelOffset = LabelOffset + 4\r
925 elif Item.startswith('UINT64'):\r
926 LabelOffset = LabelOffset + 8\r
927 else:\r
8bd72d7c 928 try:\r
8bd72d7c
KM
929 ItemValue, ItemSize = ParseFieldValue(Item)\r
930 LabelOffset = LabelOffset + ItemSize\r
35f613d9 931 except:\r
3be421e9
FY
932 LabelOffset = LabelOffset + 1\r
933\r
934 for Index, Item in enumerate(PcdValueList):\r
935 # for LABEL parse\r
936 Item = Item.strip()\r
937 try:\r
938 Item = ReLabel.sub('', Item)\r
939 except:\r
940 pass\r
941 try:\r
942 OffsetList = ReOffset.findall(Item)\r
943 except:\r
944 pass\r
945 for Offset in OffsetList:\r
946 if Offset in LabelDict.keys():\r
947 Re = re.compile('OFFSET_OF\(%s\)' % Offset)\r
948 Item = Re.sub(LabelDict[Offset], Item)\r
949 else:\r
950 raise BadExpression('%s not defined' % Offset)\r
951 NewPcdValueList.append(Item)\r
952\r
953 AllPcdValueList = []\r
954 for Item in NewPcdValueList:\r
955 Size = 0\r
956 ValueStr = ''\r
957 TokenSpaceGuidName = ''\r
958 if Item.startswith('GUID') and Item.endswith(')'):\r
35f613d9 959 try:\r
3be421e9 960 TokenSpaceGuidName = re.search('GUID\((\w+)\)', Item).group(1)\r
35f613d9
YF
961 except:\r
962 pass\r
3be421e9
FY
963 if TokenSpaceGuidName and TokenSpaceGuidName in self._Symb:\r
964 Item = 'GUID(' + self._Symb[TokenSpaceGuidName] + ')'\r
965 elif TokenSpaceGuidName:\r
966 raise BadExpression('%s not found in DEC file' % TokenSpaceGuidName)\r
967 Item, Size = ParseFieldValue(Item)\r
968 for Index in range(0, Size):\r
969 ValueStr = '0x%02X' % (int(Item) & 255)\r
970 Item >>= 8\r
971 AllPcdValueList.append(ValueStr)\r
972 continue\r
973 elif Item.startswith('DEVICE_PATH') and Item.endswith(')'):\r
974 Item, Size = ParseFieldValue(Item)\r
975 AllPcdValueList.append(Item[1:-1])\r
976 continue\r
977 else:\r
35f613d9 978 ValueType = ""\r
0e6b8673 979 if Item.startswith('UINT8'):\r
35f613d9
YF
980 ItemSize = 1\r
981 ValueType = "UINT8"\r
982 elif Item.startswith('UINT16'):\r
983 ItemSize = 2\r
984 ValueType = "UINT16"\r
985 elif Item.startswith('UINT32'):\r
986 ItemSize = 4\r
a35918ca 987 ValueType = "UINT32"\r
35f613d9
YF
988 elif Item.startswith('UINT64'):\r
989 ItemSize = 8\r
a35918ca 990 ValueType = "UINT64"\r
35f613d9
YF
991 else:\r
992 ItemSize = 0\r
993 if ValueType:\r
994 TmpValue = ValueExpressionEx(Item, ValueType, self._Symb)(True)\r
995 else:\r
996 TmpValue = ValueExpressionEx(Item, self.PcdType, self._Symb)(True)\r
997 Item = '0x%x' % TmpValue if type(TmpValue) != type('') else TmpValue\r
998 if ItemSize == 0:\r
999 ItemValue, ItemSize = ParseFieldValue(Item)\r
3be421e9
FY
1000 if not (Item.startswith('"') or Item.startswith('L') or Item.startswith('{')) and ItemSize > 1:\r
1001 raise BadExpression("Byte array number %s should less than 0xFF." % Item)\r
35f613d9
YF
1002 else:\r
1003 ItemValue = ParseFieldValue(Item)[0]\r
1004 for I in range(0, ItemSize):\r
3be421e9 1005 ValueStr = '0x%02X' % (int(ItemValue) & 255)\r
35f613d9 1006 ItemValue >>= 8\r
3be421e9 1007 AllPcdValueList.append(ValueStr)\r
35f613d9
YF
1008 Size += ItemSize\r
1009\r
3be421e9
FY
1010 if Size > 0:\r
1011 PcdValue = '{' + ','.join(AllPcdValueList) + '}'\r
0e6b8673 1012 else:\r
9efe8d60 1013 raise BadExpression("Type: %s, Value: %s, %s"%(self.PcdType, PcdValue, Value))\r
0e6b8673 1014\r
35f613d9
YF
1015 if PcdValue == 'True':\r
1016 PcdValue = '1'\r
1017 if PcdValue == 'False':\r
1018 PcdValue = '0'\r
726c501c 1019\r
726c501c
YZ
1020 if RealValue:\r
1021 return PcdValue\r
1022\r
0d2711a6
LG
1023if __name__ == '__main__':\r
1024 pass\r
d0acc87a
LG
1025 while True:\r
1026 input = raw_input('Input expr: ')\r
1027 if input in 'qQ':\r
1028 break\r
1029 try:\r
1030 print ValueExpression(input)(True)\r
1031 print ValueExpression(input)(False)\r
1032 except WrnExpression, Ex:\r
1033 print Ex.result\r
1034 print str(Ex)\r
1035 except Exception, Ex:\r
1036 print str(Ex)\r