--- /dev/null
+/*++\r
+\r
+Copyright (c) 2004, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ DepexParser.c\r
+\r
+Abstract:\r
+\r
+ Validate Dependency Expression syntax\r
+ recursive descent Algorithm\r
+\r
+ The original BNF grammar(taken from "Pre EFI Initialization Core Interface Specification \r
+ draft review 0.9") is thus:\r
+ <depex> ::= BEFORE <guid> END\r
+ | AFTER <guid> END\r
+ | SOR <bool> END\r
+ | <bool> END \r
+ <bool> ::= <bool> AND <term> \r
+ | <bool> OR <term> \r
+ | <term> \r
+ <term> ::= NOT <factor> \r
+ | <factor> \r
+ <factor> ::= <bool> \r
+ | TRUE \r
+ | FALSE \r
+ | GUID\r
+\r
+ <guid> ::= '{' <hex32> ',' <hex16> ',' <hex16> ','\r
+ <hex8> ',' <hex8> ',' <hex8> ',' <hex8> ',' \r
+ <hex8> ',' <hex8> ',' <hex8> ',' <hex8> '}'\r
+ <hex32> ::= <hexprefix> <hexvalue>\r
+ <hex16> ::= <hexprefix> <hexvalue>\r
+ <hex8> ::= <hexprefix> <hexvalue>\r
+ <hexprefix>::= '0' 'x'\r
+ | '0' 'X'\r
+ <hexvalue> ::= <hexdigit> <hexvalue>\r
+ | <hexdigit>\r
+ <hexdigit> ::= [0-9]\r
+ | [a-f]\r
+ | [A-F]\r
+\r
+ After cleaning left recursive and parentheses supported, the BNF grammar used in this module is thus:\r
+ <depex> ::= BEFORE <guid>\r
+ | AFTER <guid>\r
+ | SOR <bool>\r
+ | <bool>\r
+ <bool> ::= <term><rightbool>\r
+ <rightbool>::= AND <term><rightbool>\r
+ | OR <term><rightbool>\r
+ | ''\r
+ <term> ::= NOT <factor>\r
+ | <factor>\r
+ <factor> ::= '('<bool>')'<rightfactor>\r
+ | NOT <factor> <rightbool> <rightfactor>\r
+ | TRUE <rightfactor>\r
+ | FALSE <rightfactor>\r
+ | END <rightfactor>\r
+ | <guid> <rightfactor> \r
+ <rightfactor> ::=AND <term><rightbool> <rightfactor> \r
+ | OR <term><rightbool> <rightfactor> \r
+ | ''\r
+ <guid> ::= '{' <hex32> ',' <hex16> ',' <hex16> ','\r
+ <hex8> ',' <hex8> ',' <hex8> ',' <hex8> ',' \r
+ <hex8> ',' <hex8> ',' <hex8> ',' <hex8> '}'\r
+ <hex32> ::= <hexprefix> <hexvalue>\r
+ <hex16> ::= <hexprefix> <hexvalue>\r
+ <hex8> ::= <hexprefix> <hexvalue>\r
+ <hexprefix>::= '0' 'x'\r
+ | '0' 'X'\r
+ <hexvalue> ::= <hexdigit> <hexvalue>\r
+ | <hexdigit>\r
+ <hexdigit> ::= [0-9]\r
+ | [a-f]\r
+ | [A-F]\r
+ \r
+ Note: 1. There's no precedence in operators except parentheses;\r
+ 2. For hex32, less and equal than 8 bits is valid, more than 8 bits is invalid.\r
+ Same constraint for hex16 is 4, hex8 is 2. All hex should contains at least 1 bit.\r
+ 3. "<factor> ::= '('<bool>')'<rightfactor>" is added to support parentheses;\r
+ 4. "<factor> ::= GUID" is changed to "<factor> ::= <guid>";\r
+ 5. "DEPENDENCY_END" is the terminal of the expression. But it has been filtered by caller. \r
+ During parsing, "DEPENDENCY_END" will be treated as illegal factor;\r
+ \r
+ This code should build in any environment that supports a standard C-library w/ string\r
+ operations and File I/O services.\r
+\r
+ As an example of usage, consider the following:\r
+\r
+ The input string could be something like: \r
+ \r
+ NOT ({ 0xce345171, 0xba0b, 0x11d2, 0x8e, 0x4f, 0x0, 0xa0, 0xc9, 0x69, 0x72,\r
+ 0x3b } AND { 0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69,\r
+ 0x72, 0x3b }) OR { 0x03c4e603, 0xac28, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x27,\r
+ 0x3f, 0xc1, 0x4d } AND\r
+\r
+ It's invalid for an extra "AND" in the end.\r
+\r
+ Complies with Tiano C Coding Standards Document, version 0.33, 16 Aug 2001.\r
+\r
+--*/\r
+\r
+#include "DepexParser.h"\r
+\r
+BOOLEAN\r
+ParseBool (\r
+ IN INT8 *Pbegin,\r
+ IN UINT32 length,\r
+ IN OUT INT8 **Pindex\r
+ );\r
+\r
+BOOLEAN\r
+ParseTerm (\r
+ IN INT8 *Pbegin,\r
+ IN UINT32 length,\r
+ IN OUT INT8 **Pindex\r
+ );\r
+\r
+BOOLEAN\r
+ParseRightBool (\r
+ IN INT8 *Pbegin,\r
+ IN UINT32 length,\r
+ IN OUT INT8 **Pindex\r
+ );\r
+\r
+BOOLEAN\r
+ParseFactor (\r
+ IN INT8 *Pbegin,\r
+ IN UINT32 length,\r
+ IN OUT INT8 **Pindex\r
+ );\r
+\r
+VOID\r
+LeftTrim (\r
+ IN INT8 *Pbegin,\r
+ IN UINT32 length,\r
+ IN OUT INT8 **Pindex\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Left trim the space, '\n' and '\r' character in string.\r
+ The space at the end does not need trim.\r
+\r
+\r
+Arguments:\r
+\r
+ Pbegin The pointer to the string \r
+ length length of the string\r
+ Pindex The pointer of pointer to the next parse character in the string\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+\r
+--*/\r
+{\r
+ while\r
+ (\r
+ ((*Pindex) < (Pbegin + length)) &&\r
+ ((strncmp (*Pindex, " ", 1) == 0) || (strncmp (*Pindex, "\n", 1) == 0) || (strncmp (*Pindex, "\r", 1) == 0))\r
+ ) {\r
+ (*Pindex)++;\r
+ }\r
+}\r
+\r
+BOOLEAN\r
+ParseHexdigit (\r
+ IN INT8 *Pbegin,\r
+ IN UINT32 length,\r
+ IN OUT INT8 **Pindex\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Parse Hex bit in dependency expression. \r
+\r
+Arguments:\r
+\r
+ Pbegin The pointer to the string \r
+ length Length of the string\r
+ Pindex The pointer of pointer to the next parse character in the string\r
+\r
+Returns:\r
+\r
+ BOOLEAN If parses a valid hex bit, return TRUE, otherwise FALSE\r
+\r
+\r
+--*/\r
+{\r
+ //\r
+ // <hexdigit> ::= [0-9] | [a-f] | [A-F]\r
+ //\r
+ if (((**Pindex) >= '0' && (**Pindex) <= '9') ||\r
+ ((**Pindex) >= 'a' && (**Pindex) <= 'f') ||\r
+ ((**Pindex) >= 'A' && (**Pindex) <= 'F')\r
+ ) {\r
+ (*Pindex)++;\r
+ return TRUE;\r
+ } else {\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+BOOLEAN\r
+ParseHex32 (\r
+ IN INT8 *Pbegin,\r
+ IN UINT32 length,\r
+ IN OUT INT8 **Pindex\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Parse Hex32 in dependency expression. \r
+\r
+Arguments:\r
+\r
+ Pbegin The pointer to the string \r
+ length Length of the string\r
+ Pindex The pointer of point to the next parse character in the string\r
+\r
+Returns:\r
+\r
+ BOOLEAN If parses a valid hex32, return TRUE, otherwise FALSE\r
+\r
+\r
+--*/\r
+{\r
+ INT32 Index;\r
+ INT8 *Pin;\r
+\r
+ Index = 0;\r
+ Pin = *Pindex;\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if ((strncmp (*Pindex, "0x", 2) != 0) && (strncmp (*Pindex, "0X", 2) != 0)) {\r
+ return FALSE;\r
+ }\r
+ (*Pindex) += 2;\r
+\r
+ while (ParseHexdigit (Pbegin, length, Pindex)) {\r
+ Index++;\r
+ }\r
+\r
+ if (Index > 0 && Index <= 8) {\r
+ return TRUE;\r
+ } else {\r
+ *Pindex = Pin;\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+BOOLEAN\r
+ParseHex16 (\r
+ IN INT8 *Pbegin,\r
+ IN UINT32 length,\r
+ IN OUT INT8 **Pindex\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Parse Hex16 in dependency expression. \r
+\r
+Arguments:\r
+\r
+ Pbegin The pointer to the string \r
+ length Length of the string\r
+ Pindex The pointer of pointer to the next parse character in the string\r
+\r
+Returns:\r
+\r
+ BOOLEAN If parses a valid hex16, return TRUE, otherwise FALSE\r
+\r
+\r
+--*/\r
+{\r
+ int Index;\r
+ INT8 *Pin;\r
+\r
+ Index = 0;\r
+ Pin = *Pindex;\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if ((strncmp (*Pindex, "0x", 2) != 0) && (strncmp (*Pindex, "0X", 2) != 0)) {\r
+ return FALSE;\r
+ }\r
+ (*Pindex) += 2;\r
+\r
+ while (ParseHexdigit (Pbegin, length, Pindex)) {\r
+ Index++;\r
+ }\r
+\r
+ if (Index > 0 && Index <= 4) {\r
+ return TRUE;\r
+ } else {\r
+ *Pindex = Pin;\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+BOOLEAN\r
+ParseHex8 (\r
+ IN INT8 *Pbegin,\r
+ IN UINT32 length,\r
+ IN OUT INT8 **Pindex\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Parse Hex8 in dependency expression. \r
+\r
+Arguments:\r
+\r
+ Pbegin The pointer to the string \r
+ length Length of the string\r
+ Pindex The pointer of pointer to the next parse character in the string\r
+\r
+Returns:\r
+\r
+ BOOLEAN If parses a valid hex8, return TRUE, otherwise FALSE\r
+\r
+\r
+--*/\r
+{\r
+ int Index;\r
+ INT8 *Pin;\r
+\r
+ Index = 0;\r
+ Pin = *Pindex;\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if ((strncmp (*Pindex, "0x", 2) != 0) && (strncmp (*Pindex, "0X", 2) != 0)) {\r
+ return FALSE;\r
+ }\r
+ (*Pindex) += 2;\r
+\r
+ while (ParseHexdigit (Pbegin, length, Pindex)) {\r
+ Index++;\r
+ }\r
+\r
+ if (Index > 0 && Index <= 2) {\r
+ return TRUE;\r
+ } else {\r
+ *Pindex = Pin;\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+BOOLEAN\r
+ParseGuid (\r
+ IN INT8 *Pbegin,\r
+ IN UINT32 length,\r
+ IN OUT INT8 **Pindex\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Parse guid in dependency expression.\r
+ There can be any number of spaces between '{' and hexword, ',' and hexword, \r
+ hexword and ',', hexword and '}'. The hexword include hex32, hex16 and hex8.\r
+\r
+Arguments:\r
+\r
+ Pbegin The pointer to the string \r
+ length length of the string\r
+ Pindex The pointer of pointer to the next parse character in the string\r
+\r
+Returns:\r
+\r
+ BOOLEAN If parses a valid guid, return TRUE, otherwise FALSE\r
+\r
+\r
+--*/\r
+{\r
+ INT32 Index;\r
+ INT8 *Pin;\r
+ Pin = *Pindex;\r
+ LeftTrim (Pbegin, length, Pindex);\r
+ if (strncmp (*Pindex, "{", 1) != 0) {\r
+ return FALSE;\r
+ }\r
+ (*Pindex)++;\r
+\r
+ LeftTrim (Pbegin, length, Pindex);\r
+ if (!ParseHex32 (Pbegin, length, Pindex)) {\r
+ *Pindex = Pin;\r
+ return FALSE;\r
+ }\r
+\r
+ LeftTrim (Pbegin, length, Pindex);\r
+ if (strncmp (*Pindex, ",", 1) != 0) {\r
+ return FALSE;\r
+ } else {\r
+ (*Pindex)++;\r
+ }\r
+\r
+ for (Index = 0; Index < 2; Index++) {\r
+ LeftTrim (Pbegin, length, Pindex);\r
+ if (!ParseHex16 (Pbegin, length, Pindex)) {\r
+ *Pindex = Pin;\r
+ return FALSE;\r
+ }\r
+\r
+ LeftTrim (Pbegin, length, Pindex);\r
+ if (strncmp (*Pindex, ",", 1) != 0) {\r
+ return FALSE;\r
+ } else {\r
+ (*Pindex)++;\r
+ }\r
+ }\r
+\r
+ for (Index = 0; Index < 7; Index++) {\r
+ LeftTrim (Pbegin, length, Pindex);\r
+ if (!ParseHex8 (Pbegin, length, Pindex)) {\r
+ *Pindex = Pin;\r
+ return FALSE;\r
+ }\r
+\r
+ LeftTrim (Pbegin, length, Pindex);\r
+ if (strncmp (*Pindex, ",", 1) != 0) {\r
+ return FALSE;\r
+ } else {\r
+ (*Pindex)++;\r
+ }\r
+ }\r
+\r
+ LeftTrim (Pbegin, length, Pindex);\r
+ if (!ParseHex8 (Pbegin, length, Pindex)) {\r
+ *Pindex = Pin;\r
+ return FALSE;\r
+ }\r
+\r
+ LeftTrim (Pbegin, length, Pindex);\r
+ if (strncmp (*Pindex, "}", 1) != 0) {\r
+ return FALSE;\r
+ } else {\r
+ (*Pindex)++;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+BOOLEAN\r
+ParseRightFactor (\r
+ IN INT8 *Pbegin,\r
+ IN UINT32 length,\r
+ IN OUT INT8 **Pindex\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Parse rightfactor in bool expression.\r
+\r
+Arguments:\r
+\r
+ Pbegin The pointer to the string \r
+ length length of the string\r
+ Pindex The pointer of pointer to the next parse character in the string\r
+\r
+Returns:\r
+\r
+ BOOLEAN If string is a valid rightfactor expression, return TRUE, otherwise FALSE\r
+\r
+\r
+--*/\r
+{\r
+ INT8 *Pin;\r
+\r
+ Pin = *Pindex;\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ //\r
+ // <rightfactor> ::=AND <term> <rightbool> <rightfactor>\r
+ //\r
+ if (strncmp (*Pindex, OPERATOR_AND, strlen (OPERATOR_AND)) == 0) {\r
+ *Pindex += strlen (OPERATOR_AND);\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if (ParseTerm (Pbegin, length, Pindex)) {\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if (ParseRightBool (Pbegin, length, Pindex)) {\r
+ LeftTrim (Pbegin, length, Pindex);\r
+ if (ParseRightFactor (Pbegin, length, Pindex)) {\r
+ return TRUE;\r
+ } else {\r
+ *Pindex = Pin;\r
+ }\r
+ } else {\r
+ *Pindex = Pin;\r
+ }\r
+ } else {\r
+ *Pindex = Pin;\r
+ }\r
+ }\r
+ //\r
+ // <rightfactor> ::=OR <term> <rightbool> <rightfactor>\r
+ //\r
+ if (strncmp (*Pindex, OPERATOR_OR, strlen (OPERATOR_OR)) == 0) {\r
+ *Pindex += strlen (OPERATOR_OR);\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if (ParseTerm (Pbegin, length, Pindex)) {\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if (ParseRightBool (Pbegin, length, Pindex)) {\r
+ LeftTrim (Pbegin, length, Pindex);\r
+ if (ParseRightFactor (Pbegin, length, Pindex)) {\r
+ return TRUE;\r
+ } else {\r
+ *Pindex = Pin;\r
+ }\r
+ } else {\r
+ *Pindex = Pin;\r
+ }\r
+ } else {\r
+ *Pindex = Pin;\r
+ }\r
+ }\r
+ //\r
+ // <rightfactor> ::= ''\r
+ //\r
+ *Pindex = Pin;\r
+ return TRUE;\r
+}\r
+\r
+BOOLEAN\r
+ParseRightBool (\r
+ IN INT8 *Pbegin,\r
+ IN UINT32 length,\r
+ IN OUT INT8 **Pindex\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Parse rightbool in bool expression.\r
+\r
+Arguments:\r
+\r
+ Pbegin The pointer to the string \r
+ length length of the string\r
+ Pindex The pointer of pointer to the next parse character in the string\r
+\r
+Returns:\r
+\r
+ BOOLEAN If string is a valid rightbool expression, return TRUE, otherwise FALSE\r
+\r
+\r
+--*/\r
+{\r
+ INT8 *Pin;\r
+\r
+ Pin = *Pindex;\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ //\r
+ // <rightbool>::= AND <term><rightbool>\r
+ //\r
+ if (strncmp (*Pindex, OPERATOR_AND, strlen (OPERATOR_AND)) == 0) {\r
+ *Pindex += strlen (OPERATOR_AND);\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if (ParseTerm (Pbegin, length, Pindex)) {\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if (ParseRightBool (Pbegin, length, Pindex)) {\r
+ return TRUE;\r
+ } else {\r
+ *Pindex = Pin;\r
+ }\r
+ } else {\r
+ *Pindex = Pin;\r
+ }\r
+ }\r
+ //\r
+ // <rightbool>::= OR <term><rightbool>\r
+ //\r
+ if (strncmp (*Pindex, OPERATOR_OR, strlen (OPERATOR_OR)) == 0) {\r
+ *Pindex += strlen (OPERATOR_OR);\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if (ParseTerm (Pbegin, length, Pindex)) {\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if (ParseRightBool (Pbegin, length, Pindex)) {\r
+ return TRUE;\r
+ } else {\r
+ *Pindex = Pin;\r
+ }\r
+ } else {\r
+ *Pindex = Pin;\r
+ }\r
+ }\r
+ //\r
+ // <rightbool>::= ''\r
+ //\r
+ *Pindex = Pin;\r
+ return TRUE;\r
+}\r
+\r
+BOOLEAN\r
+ParseFactor (\r
+ IN INT8 *Pbegin,\r
+ IN UINT32 length,\r
+ IN OUT INT8 **Pindex\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Parse factor in bool expression.\r
+\r
+Arguments:\r
+\r
+ Pbegin The pointer to the string \r
+ length length of the string\r
+ Pindex The pointer of pointer to the next parse character in the string\r
+\r
+Returns:\r
+\r
+ BOOLEAN If string is a valid factor, return TRUE, otherwise FALSE\r
+\r
+\r
+--*/\r
+{\r
+ INT8 *Pin;\r
+\r
+ Pin = *Pindex;\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ //\r
+ // <factor> ::= '('<bool>')'<rightfactor>\r
+ //\r
+ if (strncmp (*Pindex, OPERATOR_LEFT_PARENTHESIS, strlen (OPERATOR_LEFT_PARENTHESIS)) == 0) {\r
+ *Pindex += strlen (OPERATOR_LEFT_PARENTHESIS);\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if (!ParseBool (Pbegin, length, Pindex)) {\r
+ *Pindex = Pin;\r
+ } else {\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if (strncmp (*Pindex, OPERATOR_RIGHT_PARENTHESIS, strlen (OPERATOR_RIGHT_PARENTHESIS)) == 0) {\r
+ *Pindex += strlen (OPERATOR_RIGHT_PARENTHESIS);\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if (ParseRightFactor (Pbegin, length, Pindex)) {\r
+ return TRUE;\r
+ } else {\r
+ *Pindex = Pin;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ //\r
+ // <factor> ::= NOT <factor> <rightbool> <rightfactor>\r
+ //\r
+ if (strncmp (*Pindex, OPERATOR_NOT, strlen (OPERATOR_NOT)) == 0) {\r
+ *Pindex += strlen (OPERATOR_NOT);\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if (ParseFactor (Pbegin, length, Pindex)) {\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if (ParseRightBool (Pbegin, length, Pindex)) {\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if (ParseRightFactor (Pbegin, length, Pindex)) {\r
+ return TRUE;\r
+ } else {\r
+ *Pindex = Pin;\r
+ }\r
+ } else {\r
+ *Pindex = Pin;\r
+ }\r
+ } else {\r
+ *Pindex = Pin;\r
+ }\r
+ }\r
+ //\r
+ // <factor> ::= TRUE <rightfactor>\r
+ //\r
+ if (strncmp (*Pindex, OPERATOR_TRUE, strlen (OPERATOR_TRUE)) == 0) {\r
+ *Pindex += strlen (OPERATOR_TRUE);\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if (ParseRightFactor (Pbegin, length, Pindex)) {\r
+ return TRUE;\r
+ } else {\r
+ *Pindex = Pin;\r
+ }\r
+ }\r
+ //\r
+ // <factor> ::= FALSE <rightfactor>\r
+ //\r
+ if (strncmp (*Pindex, OPERATOR_FALSE, strlen (OPERATOR_FALSE)) == 0) {\r
+ *Pindex += strlen (OPERATOR_FALSE);\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if (ParseRightFactor (Pbegin, length, Pindex)) {\r
+ return TRUE;\r
+ } else {\r
+ *Pindex = Pin;\r
+ }\r
+ }\r
+ //\r
+ // <factor> ::= <guid> <rightfactor>\r
+ //\r
+ if (ParseGuid (Pbegin, length, Pindex)) {\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if (ParseRightFactor (Pbegin, length, Pindex)) {\r
+ return TRUE;\r
+ } else {\r
+ *Pindex = Pin;\r
+ return FALSE;\r
+ }\r
+ } else {\r
+ *Pindex = Pin;\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+BOOLEAN\r
+ParseTerm (\r
+ IN INT8 *Pbegin,\r
+ IN UINT32 length,\r
+ IN OUT INT8 **Pindex\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Parse term in bool expression.\r
+\r
+Arguments:\r
+\r
+ Pbegin The pointer to the string \r
+ length length of the string\r
+ Pindex The pointer of pointer to the next parse character in the string\r
+\r
+Returns:\r
+\r
+ BOOLEAN If string is a valid term, return TRUE, otherwise FALSE\r
+\r
+\r
+--*/\r
+{\r
+ INT8 *Pin;\r
+\r
+ Pin = *Pindex;\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ //\r
+ // <term> ::= NOT <factor>\r
+ //\r
+ if (strncmp (*Pindex, OPERATOR_NOT, strlen (OPERATOR_NOT)) == 0) {\r
+ *Pindex += strlen (OPERATOR_NOT);\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if (!ParseFactor (Pbegin, length, Pindex)) {\r
+ *Pindex = Pin;\r
+ } else {\r
+ return TRUE;\r
+ }\r
+ }\r
+ //\r
+ // <term> ::=<factor>\r
+ //\r
+ if (ParseFactor (Pbegin, length, Pindex)) {\r
+ return TRUE;\r
+ } else {\r
+ *Pindex = Pin;\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+BOOLEAN\r
+ParseBool (\r
+ IN INT8 *Pbegin,\r
+ IN UINT32 length,\r
+ IN OUT INT8 **Pindex\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Parse bool expression.\r
+\r
+Arguments:\r
+\r
+ Pbegin The pointer to the string \r
+ length length of the string\r
+ Pindex The pointer of pointer to the next parse character in the string\r
+\r
+Returns:\r
+\r
+ BOOLEAN If string is a valid bool expression, return TRUE, otherwise FALSE\r
+\r
+\r
+--*/\r
+{\r
+ INT8 *Pin;\r
+ Pin = *Pindex;\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if (ParseTerm (Pbegin, length, Pindex)) {\r
+ LeftTrim (Pbegin, length, Pindex);\r
+\r
+ if (!ParseRightBool (Pbegin, length, Pindex)) {\r
+ *Pindex = Pin;\r
+ return FALSE;\r
+ } else {\r
+ return TRUE;\r
+ }\r
+ } else {\r
+ *Pindex = Pin;\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+BOOLEAN\r
+ParseDepex (\r
+ IN INT8 *Pbegin,\r
+ IN UINT32 length\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Parse whole dependency expression.\r
+\r
+Arguments:\r
+\r
+ Pbegin The pointer to the string \r
+ length length of the string\r
+\r
+Returns:\r
+\r
+ BOOLEAN If string is a valid dependency expression, return TRUE, otherwise FALSE\r
+\r
+\r
+--*/\r
+{\r
+ BOOLEAN Result;\r
+ INT8 **Pindex;\r
+ INT8 *temp;\r
+\r
+ Result = FALSE;\r
+ temp = Pbegin;\r
+ Pindex = &temp;\r
+\r
+ LeftTrim (Pbegin, length, Pindex);\r
+ if (strncmp (*Pindex, OPERATOR_BEFORE, strlen (OPERATOR_BEFORE)) == 0) {\r
+ (*Pindex) += strlen (OPERATOR_BEFORE);\r
+ Result = ParseGuid (Pbegin, length, Pindex);\r
+\r
+ } else if (strncmp (*Pindex, OPERATOR_AFTER, strlen (OPERATOR_AFTER)) == 0) {\r
+ (*Pindex) += strlen (OPERATOR_AFTER);\r
+ Result = ParseGuid (Pbegin, length, Pindex);\r
+\r
+ } else if (strncmp (*Pindex, OPERATOR_SOR, strlen (OPERATOR_SOR)) == 0) {\r
+ (*Pindex) += strlen (OPERATOR_SOR);\r
+ Result = ParseBool (Pbegin, length, Pindex);\r
+\r
+ } else {\r
+ Result = ParseBool (Pbegin, length, Pindex);\r
+\r
+ }\r
+\r
+ LeftTrim (Pbegin, length, Pindex);\r
+ return (BOOLEAN) (Result && (*Pindex) >= (Pbegin + length));\r
+}\r