--- /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
+ GenDepex.c\r
+\r
+Abstract:\r
+\r
+ Generate Dependency Expression ("GenDepex")\r
+\r
+ Infix to Postfix Algorithm\r
+\r
+ This code has been scrubbed to be free of having any EFI core tree dependencies.\r
+ It 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 user file could be something like "Sample.DXS" whose contents are\r
+\r
+ #include "Tiano.h"\r
+\r
+ DEPENDENCY_START\r
+ NOT (DISK_IO_PROTOCOL AND SIMPLE_FILE_SYSTEM_PROTOCOL) \r
+ OR EFI_PXE_BASE_CODE_PROTOCOL\r
+ DEPENDENCY_END\r
+\r
+ This file is then washed through the C-preprocessor, viz.,\r
+\r
+ cl /EP Sample.DXS > Sample.TMP1\r
+\r
+ This yields the following file "Sample.TMP1" whose contents are\r
+\r
+ DEPENDENCY_START\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 }\r
+ DEPENDENCY_END\r
+\r
+ This file, in turn, will be fed into the utility, viz.,\r
+\r
+ GenDepex Sample.TMP1 Sample.TMP2\r
+\r
+ With a file that is 55 bytes long:\r
+\r
+ 55 bytes for the grammar binary\r
+ PUSH opcode - 1 byte\r
+ GUID Instance - 16 bytes\r
+ PUSH opcode - 1 byte\r
+ GUID Instance - 16 bytes\r
+ AND opcode - 1 byte\r
+ NOT opcode - 1 byte\r
+ PUSH opcode - 1 byte\r
+ GUID Instance - 16 bytes\r
+ OR opcode - 1 byte\r
+ END opcode - 1 byte\r
+\r
+ The file "Sample.TMP2" could be fed via a Section-builder utility \r
+ (GenSection) that would be used for the creation of a dependency\r
+ section file (.DPX) which in turn would be used by a generate FFS\r
+ utility (GenFfsFile) to produce a DXE driver/core (.DXE) or \r
+ a DXE application (.APP) file.\r
+\r
+ Complies with Tiano C Coding Standards Document, version 0.31, 12 Dec 2000.\r
+\r
+--*/\r
+\r
+#include "GenDepex.h"\r
+\r
+#define TOOL_NAME "GenDepex"\r
+\r
+extern\r
+ParseDepex (\r
+ IN INT8 *Pbegin,\r
+ IN UINT32 length\r
+ );\r
+\r
+VOID\r
+PrintGenDepexUtilityInfo (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Displays the standard utility information to SDTOUT.\r
+\r
+Arguments:\r
+\r
+ None\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ printf (\r
+ "%s, Tiano Dependency Expression Generation Utility. Version %d.%d.\n",\r
+ UTILITY_NAME,\r
+ UTILITY_MAJOR_VERSION,\r
+ UTILITY_MINOR_VERSION\r
+ );\r
+ printf ("Copyright (C) 1996-2002 Intel Corporation. All rights reserved.\n\n");\r
+}\r
+\r
+VOID\r
+PrintGenDepexUsageInfo (\r
+ VOID\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Displays the utility usage syntax to STDOUT.\r
+\r
+Arguments:\r
+\r
+ None\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ printf (\r
+ "Usage: %s -I <INFILE> -O <OUTFILE> [-P <Optional Boundary for padding up>] \n",\r
+ UTILITY_NAME\r
+ );\r
+ printf (" Where:\n");\r
+ printf (" <INFILE> is the input pre-processed dependency text files name.\n");\r
+ printf (" <OUTFILE> is the output binary dependency files name.\n");\r
+ printf (" <Optional Boundary for padding up> is the padding integer value.\n");\r
+ printf (" This is the boundary to align the output file size to.\n");\r
+}\r
+\r
+DEPENDENCY_OPCODE\r
+PopOpCode (\r
+ IN OUT VOID **Stack\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Pop an element from the Opcode stack.\r
+\r
+Arguments:\r
+\r
+ Stack Current top of the OpCode stack location\r
+\r
+Returns:\r
+\r
+ DEPENDENCY_OPCODE OpCode at the top of the OpCode stack.\r
+ Stack New top of the OpCode stack location\r
+\r
+\r
+--*/\r
+{\r
+ DEPENDENCY_OPCODE *OpCodePtr;\r
+\r
+ OpCodePtr = *Stack;\r
+ OpCodePtr--;\r
+ *Stack = OpCodePtr;\r
+ return *OpCodePtr;\r
+}\r
+\r
+VOID\r
+PushOpCode (\r
+ IN OUT VOID **Stack,\r
+ IN DEPENDENCY_OPCODE OpCode\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Push an element onto the Opcode Stack\r
+\r
+Arguments:\r
+\r
+ Stack Current top of the OpCode stack location\r
+ OpCode OpCode to push onto the stack\r
+\r
+Returns:\r
+\r
+ Stack New top of the OpCode stack location\r
+\r
+--*/\r
+{\r
+ DEPENDENCY_OPCODE *OpCodePtr;\r
+\r
+ OpCodePtr = *Stack;\r
+ *OpCodePtr = OpCode;\r
+ OpCodePtr++;\r
+ *Stack = OpCodePtr;\r
+}\r
+\r
+EFI_STATUS\r
+GenerateDependencyExpression (\r
+ IN FILE *InFile,\r
+ IN OUT FILE *OutFile,\r
+ IN INT8 Padding OPTIONAL\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This takes the pre-compiled dependency text file and \r
+ converts it into a binary dependency file.\r
+\r
+ The BNF for the dependency expression is as follows \r
+ (from the DXE 1.0 Draft specification).\r
+\r
+ The inputted BNF grammar is thus:\r
+ <depex> ::= sor <dep> | \r
+ before GUID <dep> | \r
+ after GUID <dep> | \r
+ <bool>\r
+\r
+ <dep> ::= <bool> |\r
+\r
+ <bool> ::= <bool> and <term> | \r
+ <bool> or <term> | \r
+ <term>\r
+\r
+ <term> ::= not <factor> | \r
+ <factor>\r
+\r
+ <factor> ::= ( <bool> ) | \r
+ <term> <term> | \r
+ GUID | \r
+ <boolval>\r
+\r
+ <boolval> ::= true | \r
+ false\r
+\r
+ The outputed binary grammer is thus:\r
+ <depex> ::= sor <dep> | \r
+ before <depinst> <dep> | \r
+ after <depinst> <dep> | \r
+ <bool>\r
+\r
+ <dep> ::= <bool> |\r
+\r
+ <bool> ::= <bool> and <term> | \r
+ <bool> or <term> | <term>\r
+\r
+ <term> ::= not <factor> | \r
+ <factor>\r
+\r
+ <factor> ::= ( <bool> ) | \r
+ <term> <term> | \r
+ <boolval> | \r
+ <depinst> | \r
+ <termval>\r
+\r
+ <boolval> ::= true | \r
+ false\r
+\r
+ <depinst> ::= push GUID\r
+\r
+ <termval> ::= end\r
+\r
+ BugBug: A correct grammer is parsed correctly. A file that violates the\r
+ grammer may parse when it should generate an error. There is some\r
+ error checking and it covers most of the case when it's an include\r
+ of definition issue. An ill formed expresion may not be detected.\r
+\r
+Arguments:\r
+\r
+ InFile - Input pre-compiled text file of the dependency expression.\r
+ This needs to be in ASCII.\r
+ The file pointer can not be NULL.\r
+\r
+ OutFile - Binary dependency file.\r
+ The file pointer can not be NULL.\r
+\r
+ Padding - OPTIONAL integer value to pad the output file to.\r
+\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS The function completed successfully.\r
+ EFI_INVALID_PARAMETER One of the parameters in the text file was invalid.\r
+ EFI_OUT_OF_RESOURCES Unable to allocate memory.\r
+ EFI_ABORTED An misc error occurred.\r
+\r
+--*/\r
+{\r
+ INT8 *Ptrx;\r
+ INT8 *Pend;\r
+ INT8 *EvaluationStack;\r
+ INT8 *StackPtr;\r
+ INT8 *Buffer;\r
+ INT8 Line[LINESIZE];\r
+ UINTN Index;\r
+ UINTN OutFileSize;\r
+ UINTN FileSize;\r
+ UINTN Results;\r
+ BOOLEAN NotDone;\r
+ BOOLEAN Before_Flag;\r
+ BOOLEAN After_Flag;\r
+ BOOLEAN Dep_Flag;\r
+ BOOLEAN SOR_Flag;\r
+ EFI_GUID Guid;\r
+ UINTN ArgCountParsed;\r
+ DEPENDENCY_OPCODE Opcode;\r
+\r
+ Before_Flag = FALSE;\r
+ After_Flag = FALSE;\r
+ Dep_Flag = FALSE;\r
+ SOR_Flag = FALSE;\r
+\r
+ memset (Line, 0, LINESIZE);\r
+\r
+ OutFileSize = 0;\r
+\r
+ EvaluationStack = (INT8 *) malloc (EVAL_STACK_SIZE);\r
+\r
+ if (EvaluationStack != NULL) {\r
+ StackPtr = EvaluationStack;\r
+ } else {\r
+ printf ("Unable to allocate memory to EvaluationStack - Out of resources\n");\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ Results = (UINTN) fseek (InFile, 0, SEEK_END);\r
+\r
+ if (Results != 0) {\r
+ printf ("FSEEK failed - Aborted\n");\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ FileSize = ftell (InFile);\r
+\r
+ if (FileSize == -1L) {\r
+ printf ("FTELL failed - Aborted\n");\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ Buffer = (INT8 *) malloc (FileSize + BUFFER_SIZE);\r
+\r
+ if (Buffer == NULL) {\r
+ printf ("Unable to allocate memory to Buffer - Out of resources\n");\r
+ free (EvaluationStack);\r
+\r
+ Results = (UINTN) fclose (InFile);\r
+ if (Results != 0) {\r
+ printf ("FCLOSE failed\n");\r
+ }\r
+\r
+ Results = (UINTN) fclose (OutFile);\r
+ if (Results != 0) {\r
+ printf ("FCLOSE failed\n");\r
+ }\r
+\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ Results = (UINTN) fseek (InFile, 0, SEEK_SET);\r
+\r
+ if (Results != 0) {\r
+ printf ("FSEEK failed - Aborted\n");\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ memset (Buffer, 0, FileSize + BUFFER_SIZE);\r
+ fread (Buffer, FileSize, 1, InFile);\r
+\r
+ Ptrx = Buffer;\r
+ Pend = Ptrx + FileSize - strlen (DEPENDENCY_END);\r
+ Index = FileSize;\r
+\r
+ NotDone = TRUE;\r
+ while ((Index--) && NotDone) {\r
+\r
+ if (strncmp (Pend, DEPENDENCY_END, strlen (DEPENDENCY_END)) == 0) {\r
+ NotDone = FALSE;\r
+ } else {\r
+ Pend--;\r
+ }\r
+ }\r
+\r
+ if (NotDone) {\r
+ printf ("Couldn't find end string %s\n", DEPENDENCY_END);\r
+\r
+ Results = (UINTN) fclose (InFile);\r
+ if (Results != 0) {\r
+ printf ("FCLOSE failed\n");\r
+ }\r
+\r
+ Results = (UINTN) fclose (OutFile);\r
+ if (Results != 0) {\r
+ printf ("FCLOSE failed\n");\r
+ }\r
+\r
+ free (Buffer);\r
+ free (EvaluationStack);\r
+\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Index = FileSize;\r
+\r
+ NotDone = TRUE;\r
+ while ((Index--) && NotDone) {\r
+\r
+ if (strncmp (Ptrx, DEPENDENCY_START, strlen (DEPENDENCY_START)) == 0) {\r
+ Ptrx += sizeof (DEPENDENCY_START);\r
+ NotDone = FALSE;\r
+ //\r
+ // BUGBUG -- should Index be decremented by sizeof(DEPENDENCY_START)?\r
+ //\r
+ } else {\r
+ Ptrx++;\r
+ }\r
+ }\r
+\r
+ if (NotDone) {\r
+ printf ("Couldn't find start string %s\n", DEPENDENCY_START);\r
+\r
+ Results = (UINTN) fclose (InFile);\r
+ if (Results != 0) {\r
+ printf ("FCLOSE failed\n");\r
+ }\r
+\r
+ Results = (UINTN) fclose (OutFile);\r
+ if (Results != 0) {\r
+ printf ("FCLOSE failed\n");\r
+ }\r
+\r
+ free (Buffer);\r
+ free (EvaluationStack);\r
+\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ //\r
+ // validate the syntax of expression\r
+ //\r
+ if (!ParseDepex (Ptrx, Pend - Ptrx - 1)) {\r
+ printf ("The syntax of expression is wrong\n");\r
+\r
+ Results = (UINTN) fclose (InFile);\r
+ if (Results != 0) {\r
+ printf ("FCLOSE failed\n");\r
+ }\r
+\r
+ Results = (UINTN) fclose (OutFile);\r
+ if (Results != 0) {\r
+ printf ("FCLOSE failed\n");\r
+ }\r
+\r
+ free (Buffer);\r
+ free (EvaluationStack);\r
+\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ NotDone = TRUE;\r
+\r
+ while ((Index--) && NotDone) {\r
+\r
+ if (*Ptrx == ' ') {\r
+ Ptrx++;\r
+ } else if (*Ptrx == '\n' || *Ptrx == '\r') {\r
+ Ptrx++;\r
+ } else if (strncmp (Ptrx, OPERATOR_SOR, strlen (OPERATOR_SOR)) == 0) {\r
+ //\r
+ // Checks for some invalid dependencies\r
+ //\r
+ if (Before_Flag) {\r
+\r
+ printf ("A BEFORE operator was detected.\n");\r
+ printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");\r
+ return EFI_INVALID_PARAMETER;\r
+\r
+ } else if (After_Flag) {\r
+\r
+ printf ("An AFTER operator was detected.\n");\r
+ printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");\r
+ return EFI_INVALID_PARAMETER;\r
+\r
+ } else if (SOR_Flag) {\r
+\r
+ printf ("Another SOR operator was detected.\n");\r
+ printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");\r
+ return EFI_INVALID_PARAMETER;\r
+\r
+ } else if (Dep_Flag) {\r
+\r
+ printf ("The Schedule On Request - SOR operator must be the first operator following DEPENDENCY_START\n");\r
+ return EFI_INVALID_PARAMETER;\r
+\r
+ } else {\r
+ //\r
+ // BUGBUG - This was not in the spec but is in the CORE code\r
+ // An OPERATOR_SOR has to be first - following the DEPENDENCY_START\r
+ //\r
+ fputc (EFI_DEP_SOR, OutFile);\r
+ OutFileSize++;\r
+ Ptrx += sizeof (OPERATOR_SOR);\r
+ SOR_Flag = TRUE;\r
+\r
+ }\r
+ } else if (strncmp (Ptrx, OPERATOR_BEFORE, strlen (OPERATOR_BEFORE)) == 0) {\r
+ //\r
+ // Checks for some invalid dependencies\r
+ //\r
+ if (Before_Flag) {\r
+\r
+ printf ("Another BEFORE operator was detected.\n");\r
+ printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");\r
+ return EFI_INVALID_PARAMETER;\r
+\r
+ } else if (After_Flag) {\r
+\r
+ printf ("An AFTER operator was detected.\n");\r
+ printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");\r
+ return EFI_INVALID_PARAMETER;\r
+\r
+ } else if (SOR_Flag) {\r
+\r
+ printf ("A SOR operator was detected.\n");\r
+ printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");\r
+ return EFI_INVALID_PARAMETER;\r
+\r
+ } else if (Dep_Flag) {\r
+\r
+ printf ("The BEFORE operator must be the first operator following DEPENDENCY_START\n");\r
+ return EFI_INVALID_PARAMETER;\r
+\r
+ } else {\r
+ fputc (EFI_DEP_BEFORE, OutFile);\r
+ OutFileSize++;\r
+ Ptrx += sizeof (OPERATOR_BEFORE);\r
+ Before_Flag = TRUE;\r
+ }\r
+ } else if (strncmp (Ptrx, OPERATOR_AFTER, strlen (OPERATOR_AFTER)) == 0) {\r
+ //\r
+ // Checks for some invalid dependencies\r
+ //\r
+ if (Before_Flag) {\r
+\r
+ printf ("A BEFORE operator was detected.\n");\r
+ printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");\r
+ return EFI_INVALID_PARAMETER;\r
+\r
+ } else if (After_Flag) {\r
+\r
+ printf ("Another AFTER operator was detected.\n");\r
+ printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");\r
+ return EFI_INVALID_PARAMETER;\r
+\r
+ } else if (SOR_Flag) {\r
+\r
+ printf ("A SOR operator was detected.\n");\r
+ printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");\r
+ return EFI_INVALID_PARAMETER;\r
+\r
+ } else if (Dep_Flag) {\r
+\r
+ printf ("The AFTER operator must be the first operator following DEPENDENCY_START\n");\r
+ return EFI_INVALID_PARAMETER;\r
+\r
+ } else {\r
+ fputc (EFI_DEP_AFTER, OutFile);\r
+ OutFileSize++;\r
+ Ptrx += sizeof (OPERATOR_AFTER);\r
+ Dep_Flag = TRUE;\r
+ After_Flag = TRUE;\r
+ }\r
+ } else if (strncmp (Ptrx, OPERATOR_AND, strlen (OPERATOR_AND)) == 0) {\r
+ while (StackPtr != EvaluationStack) {\r
+ Opcode = PopOpCode ((VOID **) &StackPtr);\r
+ if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {\r
+ fputc (Opcode, OutFile);\r
+ OutFileSize++;\r
+ } else {\r
+ PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);\r
+ break;\r
+ }\r
+ }\r
+\r
+ PushOpCode ((VOID **) &StackPtr, EFI_DEP_AND);\r
+ Ptrx += sizeof (OPERATOR_AND);\r
+ Dep_Flag = TRUE;\r
+\r
+ } else if (strncmp (Ptrx, OPERATOR_OR, strlen (OPERATOR_OR)) == 0) {\r
+ while (StackPtr != EvaluationStack) {\r
+ Opcode = PopOpCode ((VOID **) &StackPtr);\r
+ if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {\r
+ fputc (Opcode, OutFile);\r
+ OutFileSize++;\r
+ } else {\r
+ PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);\r
+ break;\r
+ }\r
+ }\r
+\r
+ PushOpCode ((VOID **) &StackPtr, EFI_DEP_OR);\r
+ Ptrx += sizeof (OPERATOR_OR);\r
+ Dep_Flag = TRUE;\r
+\r
+ } else if (strncmp (Ptrx, OPERATOR_NOT, strlen (OPERATOR_NOT)) == 0) {\r
+ while (StackPtr != EvaluationStack) {\r
+ Opcode = PopOpCode ((VOID **) &StackPtr);\r
+ if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {\r
+ fputc (Opcode, OutFile);\r
+ OutFileSize++;\r
+ } else {\r
+ PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);\r
+ break;\r
+ }\r
+ }\r
+\r
+ PushOpCode ((VOID **) &StackPtr, EFI_DEP_NOT);\r
+ Ptrx += sizeof (OPERATOR_NOT);\r
+ Dep_Flag = TRUE;\r
+\r
+ } else if (*Ptrx == '\t') {\r
+\r
+ printf ("File contains tabs. This violates the coding standard\n");\r
+ return EFI_INVALID_PARAMETER;\r
+\r
+ } else if (*Ptrx == '\n') {\r
+ //\r
+ // Skip the newline character in the file\r
+ //\r
+ Ptrx++;\r
+\r
+ } else if (strncmp (Ptrx, OPERATOR_LEFT_PARENTHESIS, strlen (OPERATOR_LEFT_PARENTHESIS)) == 0) {\r
+ PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);\r
+\r
+ Ptrx += strlen (OPERATOR_LEFT_PARENTHESIS);\r
+ Dep_Flag = TRUE;\r
+\r
+ } else if (strncmp (Ptrx, OPERATOR_RIGHT_PARENTHESIS, strlen (OPERATOR_RIGHT_PARENTHESIS)) == 0) {\r
+ while (StackPtr != EvaluationStack) {\r
+ Opcode = PopOpCode ((VOID **) &StackPtr);\r
+ if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {\r
+ fputc (Opcode, OutFile);\r
+ OutFileSize++;\r
+ } else {\r
+ break;\r
+ }\r
+ }\r
+\r
+ Ptrx += strlen (OPERATOR_RIGHT_PARENTHESIS);\r
+ Dep_Flag = TRUE;\r
+\r
+ } else if (strncmp (Ptrx, OPERATOR_TRUE, strlen (OPERATOR_TRUE)) == 0) {\r
+\r
+ fputc (EFI_DEP_TRUE, OutFile);\r
+\r
+ OutFileSize++;\r
+\r
+ //\r
+ // OutFileSize += sizeof (EFI_DEP_TRUE);\r
+ //\r
+ Dep_Flag = TRUE;\r
+\r
+ Ptrx += strlen (OPERATOR_TRUE);\r
+\r
+ } else if (strncmp (Ptrx, OPERATOR_FALSE, strlen (OPERATOR_FALSE)) == 0) {\r
+\r
+ fputc (EFI_DEP_FALSE, OutFile);\r
+\r
+ OutFileSize++;\r
+\r
+ //\r
+ // OutFileSize += sizeof (EFI_DEP_FALSE);\r
+ //\r
+ Dep_Flag = TRUE;\r
+\r
+ Ptrx += strlen (OPERATOR_FALSE);\r
+\r
+ } else if (*Ptrx == '{') {\r
+ Ptrx++;\r
+\r
+ if (*Ptrx == ' ') {\r
+ Ptrx++;\r
+ }\r
+\r
+ {\r
+ int byte_index;\r
+ // This is an array of UINT32s. sscanf will trash memory\r
+ // if you try to read into a UINT8 with a %x formatter.\r
+ UINT32 Guid_Data4[8];\r
+\r
+ ArgCountParsed = sscanf (\r
+ Ptrx,\r
+ "%x, %x, %x, { %x, %x, %x, %x, %x, %x, %x, %x }",\r
+ &Guid.Data1,\r
+ &Guid.Data2,\r
+ &Guid.Data3,\r
+ &Guid_Data4[0],\r
+ &Guid_Data4[1],\r
+ &Guid_Data4[2],\r
+ &Guid_Data4[3],\r
+ &Guid_Data4[4],\r
+ &Guid_Data4[5],\r
+ &Guid_Data4[6],\r
+ &Guid_Data4[7]\r
+ );\r
+ \r
+ // Now we can copy the 32 bit ints into the GUID.\r
+ for (byte_index=0; byte_index<8; byte_index++) {\r
+ Guid.Data4[byte_index] = (UINT8) Guid_Data4[byte_index];\r
+ }\r
+ }\r
+\r
+ if (ArgCountParsed != 11) {\r
+ printf ("We have found an illegal GUID\n");\r
+ printf ("Fix your depex\n");\r
+ exit (-1);\r
+ }\r
+\r
+ while (*Ptrx != '}') {\r
+ Ptrx++;\r
+ }\r
+\r
+ Ptrx++;\r
+ while (*Ptrx != '}') {\r
+ Ptrx++;\r
+ }\r
+ //\r
+ // Absorb the closing }\r
+ //\r
+ Ptrx++;\r
+\r
+ //\r
+ // Don't provide a PUSH Opcode for the Before and After case\r
+ //\r
+ if ((!Before_Flag) && (!After_Flag)) {\r
+ fputc (EFI_DEP_PUSH, OutFile);\r
+ OutFileSize++;\r
+ }\r
+\r
+ fwrite (&Guid, sizeof (EFI_GUID), 1, OutFile);\r
+\r
+ OutFileSize += sizeof (EFI_GUID);\r
+ Dep_Flag = TRUE;\r
+\r
+ } else if (strncmp (Ptrx, DEPENDENCY_END, strlen (DEPENDENCY_END)) == 0) {\r
+ NotDone = FALSE;\r
+ } else {\r
+ //\r
+ // Not a valid construct. Null terminate somewhere out there and\r
+ // print an error message.\r
+ //\r
+ *(Ptrx + 20) = 0;\r
+ printf (TOOL_NAME " ERROR: Unrecognized input at: \"%s\"...\n", Ptrx);\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ }\r
+ //\r
+ // DRAIN();\r
+ //\r
+ while (StackPtr != EvaluationStack) {\r
+ fputc (PopOpCode ((VOID **) &StackPtr), OutFile);\r
+ OutFileSize++;\r
+ }\r
+\r
+ if (OutFileSize == 0) {\r
+ printf ("Grammer contains no operators or constants\n");\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ fputc (EFI_DEP_END, OutFile);\r
+\r
+ OutFileSize++;\r
+\r
+ //\r
+ // Checks for invalid padding values\r
+ //\r
+ if (Padding < 0) {\r
+\r
+ printf ("The inputted padding value was %d\n", Padding);\r
+ printf ("The optional padding value can not be less than ZERO\n");\r
+ return EFI_INVALID_PARAMETER;\r
+\r
+ } else if (Padding > 0) {\r
+\r
+ while ((OutFileSize % Padding) != 0) {\r
+\r
+ fputc (' ', OutFile);\r
+ OutFileSize++;\r
+ }\r
+ }\r
+\r
+ Results = (UINTN) fclose (InFile);\r
+ if (Results != 0) {\r
+ printf ("FCLOSE failed\n");\r
+ }\r
+\r
+ Results = (UINTN) fclose (OutFile);\r
+ if (Results != 0) {\r
+ printf ("FCLOSE failed\n");\r
+ }\r
+\r
+ free (Buffer);\r
+ free (EvaluationStack);\r
+\r
+ return EFI_SUCCESS;\r
+} // End GenerateDependencyExpression function\r
+\r
+int\r
+main (\r
+ IN UINTN argc,\r
+ IN CHAR8 *argv[]\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Parse user entries. Print some rudimentary help\r
+\r
+Arguments:\r
+\r
+ argc The count of input arguments\r
+ argv The input arguments string array\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS The function completed successfully.\r
+ EFI_INVALID_PARAMETER One of the input parameters was invalid or one of the parameters in the text file was invalid.\r
+ EFI_OUT_OF_RESOURCES Unable to allocate memory.\r
+ EFI_ABORTED Unable to open/create a file or a misc error.\r
+\r
+--*/\r
+// TODO: ] - add argument and description to function comment\r
+{\r
+ FILE *OutFile;\r
+ FILE *InFile;\r
+ UINT8 Padding;\r
+ UINTN Index;\r
+ BOOLEAN Input_Flag;\r
+ BOOLEAN Output_Flag;\r
+ BOOLEAN Pad_Flag;\r
+\r
+ InFile = NULL;\r
+ OutFile = NULL;\r
+ Padding = 0;\r
+ Input_Flag = FALSE;\r
+ Output_Flag = FALSE;\r
+ Pad_Flag = FALSE;\r
+\r
+ if (argc < 5) {\r
+ printf ("Not enough arguments\n");\r
+ PrintGenDepexUsageInfo ();\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ for (Index = 1; Index < argc - 1; Index++) {\r
+\r
+ if ((strcmp (argv[Index], "-I") == 0) || (strcmp (argv[Index], "-i") == 0)) {\r
+\r
+ if (!Input_Flag) {\r
+\r
+ InFile = fopen (argv[Index + 1], "rb");\r
+ Input_Flag = TRUE;\r
+\r
+ } else {\r
+ printf ("GenDepex only allows one INPUT (-I) argument\n");\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ } else if ((strcmp (argv[Index], "-O") == 0) || (strcmp (argv[Index], "-o") == 0)) {\r
+\r
+ if (!Output_Flag) {\r
+\r
+ OutFile = fopen (argv[Index + 1], "wb");\r
+ Output_Flag = TRUE;\r
+\r
+ } else {\r
+ printf ("GenDepex only allows one OUTPUT (-O) argument\n");\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ } else if ((strcmp (argv[Index], "-P") == 0) || (strcmp (argv[Index], "-p") == 0)) {\r
+\r
+ if (!Pad_Flag) {\r
+\r
+ Padding = (UINT8) atoi (argv[Index + 1]);\r
+ Pad_Flag = TRUE;\r
+\r
+ } else {\r
+ printf ("GenDepex only allows one PADDING (-P) argument\n");\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ }\r
+ }\r
+\r
+ PrintGenDepexUtilityInfo ();\r
+\r
+ if (InFile == NULL) {\r
+ printf ("Can not open <INFILE> for reading.\n");\r
+ PrintGenDepexUsageInfo ();\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ if (OutFile == NULL) {\r
+ printf ("Can not open <OUTFILE> for writting.\n");\r
+ PrintGenDepexUsageInfo ();\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ return GenerateDependencyExpression (InFile, OutFile, Padding);\r
+}\r