]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Sample/Tools/Source/GenDepex/DepexParser.c
Add in the 1st version of ECP.
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / Source / GenDepex / DepexParser.c
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenDepex/DepexParser.c b/EdkCompatibilityPkg/Sample/Tools/Source/GenDepex/DepexParser.c
new file mode 100644 (file)
index 0000000..5cd1533
--- /dev/null
@@ -0,0 +1,890 @@
+/*++\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