Home | History | Annotate | Download | only in GenDepex
      1 /*++
      2 
      3 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
      4 This program and the accompanying materials
      5 are licensed and made available under the terms and conditions of the BSD License
      6 which accompanies this distribution.  The full text of the license may be found at
      7 http://opensource.org/licenses/bsd-license.php
      8 
      9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 
     12 Module Name:
     13 
     14   GenDepex.c
     15 
     16 Abstract:
     17 
     18   Generate Dependency Expression ("GenDepex")
     19 
     20   Infix to Postfix Algorithm
     21 
     22   This code has been scrubbed to be free of having any EFI core tree dependencies.
     23   It should build in any environment that supports a standard C-library w/ string
     24   operations and File I/O services.
     25 
     26   As an example of usage, consider the following:
     27 
     28   The input user file could be something like "Sample.DXS" whose contents are
     29 
     30     #include "Tiano.h"
     31 
     32     DEPENDENCY_START
     33       NOT (DISK_IO_PROTOCOL AND SIMPLE_FILE_SYSTEM_PROTOCOL)
     34         OR EFI_PXE_BASE_CODE_PROTOCOL
     35     DEPENDENCY_END
     36 
     37   This file is then washed through the C-preprocessor, viz.,
     38 
     39     cl /EP Sample.DXS > Sample.TMP1
     40 
     41   This yields the following file "Sample.TMP1" whose contents are
     42 
     43     DEPENDENCY_START
     44       NOT ({ 0xce345171, 0xba0b, 0x11d2, 0x8e, 0x4f, 0x0, 0xa0, 0xc9, 0x69, 0x72,
     45         0x3b } AND { 0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69,
     46         0x72, 0x3b }) OR { 0x03c4e603, 0xac28, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x27,
     47         0x3f, 0xc1, 0x4d }
     48     DEPENDENCY_END
     49 
     50   This file, in turn, will be fed into the utility, viz.,
     51 
     52     GenDepex Sample.TMP1 Sample.TMP2
     53 
     54   With a file that is 55 bytes long:
     55 
     56      55 bytes for the grammar binary
     57         PUSH opcode         - 1  byte
     58         GUID Instance       - 16 bytes
     59         PUSH opcode         - 1  byte
     60         GUID Instance       - 16 bytes
     61         AND opcode          - 1  byte
     62         NOT opcode          - 1  byte
     63         PUSH opcode         - 1  byte
     64         GUID Instance       - 16 bytes
     65         OR opcode           - 1  byte
     66         END opcode          - 1  byte
     67 
     68   The file "Sample.TMP2" could be fed via a Section-builder utility
     69   (GenSection) that would be used for the creation of a dependency
     70   section file (.DPX) which in turn would be used by a generate FFS
     71   utility (GenFfsFile) to produce a DXE driver/core (.DXE) or
     72   a DXE application (.APP) file.
     73 
     74   Complies with Tiano C Coding Standards Document, version 0.31, 12 Dec 2000.
     75 
     76 --*/
     77 
     78 #include "GenDepex.h"
     79 
     80 //
     81 // Utility Name
     82 //
     83 #define UTILITY_NAME  "GenDepex"
     84 
     85 //
     86 // Utility version information
     87 //
     88 #define UTILITY_VERSION "v1.0"
     89 
     90 extern
     91 BOOLEAN
     92 ParseDepex (
     93   IN      INT8      *Pbegin,
     94   IN      UINT32    length
     95   );
     96 
     97 VOID
     98 PrintGenDepexUtilityInfo (
     99   VOID
    100   )
    101 /*++
    102 
    103 Routine Description:
    104 
    105   Displays the standard utility information to SDTOUT.
    106 
    107 Arguments:
    108 
    109   None
    110 
    111 Returns:
    112 
    113   None
    114 
    115 --*/
    116 {
    117   int         Index;
    118   const char  *Str[] = {
    119     UTILITY_NAME" "UTILITY_VERSION" - Intel Generate Dependency Expression Utility",
    120     "  Copyright (C), 1996 - 2008 Intel Corporation",
    121 
    122 #if ( defined(UTILITY_BUILD) && defined(UTILITY_VENDOR) )
    123     "  Built from "UTILITY_BUILD", project of "UTILITY_VENDOR,
    124 #endif
    125     NULL
    126   };
    127   for (Index = 0; Str[Index] != NULL; Index++) {
    128     fprintf (stdout, "%s\n", Str[Index]);
    129   }
    130 }
    131 
    132 VOID
    133 PrintGenDepexUsageInfo (
    134   VOID
    135   )
    136 /*++
    137 
    138 Routine Description:
    139 
    140   Displays the utility usage syntax to STDOUT.
    141 
    142 Arguments:
    143 
    144   None
    145 
    146 Returns:
    147 
    148   None
    149 
    150 --*/
    151 {
    152   int         Index;
    153   const char  *Str[] = {
    154     "",
    155     "Usage:",
    156     "  "UTILITY_NAME" [OPTION]...",
    157     "Options:",
    158     "  -I INFILE    The input pre-processed dependency text files name",
    159     "  -O OUTFILE   The output binary dependency files name",
    160     "  -P BOUNDARY  The padding integer value to align the output file size",
    161     NULL
    162   };
    163 
    164   PrintGenDepexUtilityInfo ();
    165   for (Index = 0; Str[Index] != NULL; Index++) {
    166     fprintf (stdout, "%s\n", Str[Index]);
    167   }
    168 }
    169 
    170 DEPENDENCY_OPCODE
    171 PopOpCode (
    172   IN OUT VOID **Stack
    173   )
    174 /*++
    175 
    176 Routine Description:
    177 
    178   Pop an element from the Opcode stack.
    179 
    180 Arguments:
    181 
    182   Stack               Current top of the OpCode stack location
    183 
    184 Returns:
    185 
    186   DEPENDENCY_OPCODE   OpCode at the top of the OpCode stack.
    187   Stack               New top of the OpCode stack location
    188 
    189 
    190 --*/
    191 {
    192   DEPENDENCY_OPCODE *OpCodePtr;
    193 
    194   OpCodePtr = *Stack;
    195   OpCodePtr--;
    196   *Stack = OpCodePtr;
    197   return *OpCodePtr;
    198 }
    199 
    200 VOID
    201 PushOpCode (
    202   IN OUT  VOID                **Stack,
    203   IN      DEPENDENCY_OPCODE   OpCode
    204   )
    205 /*++
    206 
    207 Routine Description:
    208 
    209   Push an element onto the Opcode Stack
    210 
    211 Arguments:
    212 
    213   Stack     Current top of the OpCode stack location
    214   OpCode    OpCode to push onto the stack
    215 
    216 Returns:
    217 
    218   Stack     New top of the OpCode stack location
    219 
    220 --*/
    221 {
    222   DEPENDENCY_OPCODE *OpCodePtr;
    223 
    224   OpCodePtr   = *Stack;
    225   *OpCodePtr  = OpCode;
    226   OpCodePtr++;
    227   *Stack = OpCodePtr;
    228 }
    229 
    230 EFI_STATUS
    231 GenerateDependencyExpression (
    232   IN     FILE           *InFile,
    233   IN OUT FILE           *OutFile,
    234   IN     UINT8          Padding  OPTIONAL
    235   )
    236 /*++
    237 
    238 Routine Description:
    239 
    240   This takes the pre-compiled dependency text file and
    241   converts it into a binary dependency file.
    242 
    243   The BNF for the dependency expression is as follows
    244   (from the DXE 1.0 Draft specification).
    245 
    246   The inputted BNF grammar is thus:
    247     <depex> ::= sor <dep> |
    248                 before GUID <dep> |
    249                 after GUID <dep> |
    250                 <bool>
    251 
    252     <dep> ::=   <bool> |
    253 
    254     <bool> ::=  <bool> and <term> |
    255                 <bool> or <term> |
    256                 <term>
    257 
    258     <term> ::=  not <factor> |
    259                 <factor>
    260 
    261     <factor> ::= ( <bool> ) |
    262                  <term> <term> |
    263                  GUID |
    264                  <boolval>
    265 
    266     <boolval> ::= true |
    267                   false
    268 
    269   The outputed binary grammer is thus:
    270     <depex> ::= sor <dep> |
    271                 before <depinst> <dep> |
    272                 after <depinst> <dep> |
    273                 <bool>
    274 
    275     <dep> ::=   <bool> |
    276 
    277     <bool> ::=  <bool> and <term> |
    278                 <bool> or <term> | <term>
    279 
    280     <term> ::=  not <factor> |
    281                 <factor>
    282 
    283     <factor> ::= ( <bool> ) |
    284                  <term> <term> |
    285                  <boolval> |
    286                  <depinst> |
    287                  <termval>
    288 
    289     <boolval> ::= true |
    290                   false
    291 
    292     <depinst> ::= push GUID
    293 
    294     <termval> ::= end
    295 
    296   BugBug: A correct grammer is parsed correctly. A file that violates the
    297           grammer may parse when it should generate an error. There is some
    298           error checking and it covers most of the case when it's an include
    299           of definition issue. An ill formed expresion may not be detected.
    300 
    301 Arguments:
    302 
    303   InFile -  Input pre-compiled text file of the dependency expression.
    304             This needs to be in ASCII.
    305             The file pointer can not be NULL.
    306 
    307   OutFile - Binary dependency file.
    308             The file pointer can not be NULL.
    309 
    310   Padding - OPTIONAL integer value to pad the output file to.
    311 
    312 
    313 Returns:
    314 
    315   EFI_SUCCESS             The function completed successfully.
    316   EFI_INVALID_PARAMETER   One of the parameters in the text file was invalid.
    317   EFI_OUT_OF_RESOURCES    Unable to allocate memory.
    318   EFI_ABORTED             An misc error occurred.
    319 
    320 --*/
    321 {
    322   INT8              *Ptrx;
    323   INT8              *Pend;
    324   INT8              *EvaluationStack;
    325   INT8              *StackPtr;
    326   INT8              *Buffer;
    327   INT8              Line[LINESIZE];
    328   UINTN             Index;
    329   UINTN             OutFileSize;
    330   UINTN             FileSize;
    331   UINTN             Results;
    332   BOOLEAN           NotDone;
    333   BOOLEAN           Before_Flag;
    334   BOOLEAN           After_Flag;
    335   BOOLEAN           Dep_Flag;
    336   BOOLEAN           SOR_Flag;
    337   EFI_GUID          Guid;
    338   UINTN             ArgCountParsed;
    339   DEPENDENCY_OPCODE Opcode;
    340 
    341   Before_Flag = FALSE;
    342   After_Flag  = FALSE;
    343   Dep_Flag    = FALSE;
    344   SOR_Flag    = FALSE;
    345 
    346   memset (Line, 0, LINESIZE);
    347 
    348   OutFileSize     = 0;
    349 
    350   EvaluationStack = (INT8 *) malloc (EVAL_STACK_SIZE);
    351 
    352   if (EvaluationStack != NULL) {
    353     StackPtr = EvaluationStack;
    354   } else {
    355     printf ("Unable to allocate memory to EvaluationStack - Out of resources\n");
    356     return EFI_OUT_OF_RESOURCES;
    357   }
    358 
    359   Results = (UINTN) fseek (InFile, 0, SEEK_END);
    360 
    361   if (Results != 0) {
    362     printf ("FSEEK failed - Aborted\n");
    363     return EFI_ABORTED;
    364   }
    365 
    366   FileSize = ftell (InFile);
    367 
    368   if (FileSize == -1L) {
    369     printf ("FTELL failed - Aborted\n");
    370     return EFI_ABORTED;
    371   }
    372 
    373   Buffer = (INT8 *) malloc (FileSize + BUFFER_SIZE);
    374 
    375   if (Buffer == NULL) {
    376     printf ("Unable to allocate memory to Buffer - Out of resources\n");
    377     free (EvaluationStack);
    378 
    379     Results = (UINTN) fclose (InFile);
    380     if (Results != 0) {
    381       printf ("FCLOSE failed\n");
    382     }
    383 
    384     Results = (UINTN) fclose (OutFile);
    385     if (Results != 0) {
    386       printf ("FCLOSE failed\n");
    387     }
    388 
    389     return EFI_OUT_OF_RESOURCES;
    390   }
    391 
    392   Results = (UINTN) fseek (InFile, 0, SEEK_SET);
    393 
    394   if (Results != 0) {
    395     printf ("FSEEK failed - Aborted\n");
    396     return EFI_ABORTED;
    397   }
    398 
    399   fread (Buffer, FileSize, 1, InFile);
    400 
    401   Ptrx    = Buffer;
    402   Pend    = Ptrx + FileSize - strlen (DEPENDENCY_END);
    403   Index   = FileSize;
    404 
    405   NotDone = TRUE;
    406   while ((Index--) && NotDone) {
    407 
    408     if (strncmp (Pend, DEPENDENCY_END, strlen (DEPENDENCY_END)) == 0) {
    409       NotDone = FALSE;
    410     } else {
    411       Pend--;
    412     }
    413   }
    414 
    415   if (NotDone) {
    416     printf ("Couldn't find end string %s\n", DEPENDENCY_END);
    417 
    418     Results = (UINTN) fclose (InFile);
    419     if (Results != 0) {
    420       printf ("FCLOSE failed\n");
    421     }
    422 
    423     Results = (UINTN) fclose (OutFile);
    424     if (Results != 0) {
    425       printf ("FCLOSE failed\n");
    426     }
    427 
    428     free (Buffer);
    429     free (EvaluationStack);
    430 
    431     return EFI_INVALID_PARAMETER;
    432   }
    433 
    434   Index   = FileSize;
    435 
    436   NotDone = TRUE;
    437   while ((Index--) && NotDone) {
    438 
    439     if (strncmp (Ptrx, DEPENDENCY_START, strlen (DEPENDENCY_START)) == 0) {
    440       Ptrx += strlen (DEPENDENCY_START);
    441       NotDone = FALSE;
    442       //
    443       // BUGBUG -- should Index be decremented by sizeof(DEPENDENCY_START)?
    444       //
    445     } else {
    446       Ptrx++;
    447     }
    448   }
    449 
    450   if (NotDone) {
    451     printf ("Couldn't find start string %s\n", DEPENDENCY_START);
    452 
    453     Results = (UINTN) fclose (InFile);
    454     if (Results != 0) {
    455       printf ("FCLOSE failed\n");
    456     }
    457 
    458     Results = (UINTN) fclose (OutFile);
    459     if (Results != 0) {
    460       printf ("FCLOSE failed\n");
    461     }
    462 
    463     free (Buffer);
    464     free (EvaluationStack);
    465 
    466     return EFI_INVALID_PARAMETER;
    467   }
    468   //
    469   //  validate the syntax of expression
    470   //
    471   if (!ParseDepex (Ptrx, Pend - Ptrx - 1)) {
    472     printf ("The syntax of expression is wrong\n");
    473 
    474     Results = (UINTN) fclose (InFile);
    475     if (Results != 0) {
    476       printf ("FCLOSE failed\n");
    477     }
    478 
    479     Results = (UINTN) fclose (OutFile);
    480     if (Results != 0) {
    481       printf ("FCLOSE failed\n");
    482     }
    483 
    484     free (Buffer);
    485     free (EvaluationStack);
    486 
    487     return EFI_INVALID_PARAMETER;
    488   }
    489 
    490   NotDone = TRUE;
    491 
    492   while ((Index--) && NotDone) {
    493 
    494     if (*Ptrx == ' ') {
    495       Ptrx++;
    496     } else if (*Ptrx == '\n' || *Ptrx == '\r') {
    497       Ptrx++;
    498     } else if (strncmp (Ptrx, OPERATOR_SOR, strlen (OPERATOR_SOR)) == 0) {
    499       //
    500       //  Checks for some invalid dependencies
    501       //
    502       if (Before_Flag) {
    503 
    504         printf ("A BEFORE operator was detected.\n");
    505         printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
    506         return EFI_INVALID_PARAMETER;
    507 
    508       } else if (After_Flag) {
    509 
    510         printf ("An AFTER operator was detected.\n");
    511         printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
    512         return EFI_INVALID_PARAMETER;
    513 
    514       } else if (SOR_Flag) {
    515 
    516         printf ("Another SOR operator was detected.\n");
    517         printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
    518         return EFI_INVALID_PARAMETER;
    519 
    520       } else if (Dep_Flag) {
    521 
    522         printf ("The Schedule On Request - SOR operator must be the first operator following DEPENDENCY_START\n");
    523         return EFI_INVALID_PARAMETER;
    524 
    525       } else {
    526         //
    527         //  BUGBUG - This was not in the spec but is in the CORE code
    528         //  An OPERATOR_SOR has to be first - following the DEPENDENCY_START
    529         //
    530         fputc (EFI_DEP_SOR, OutFile);
    531         OutFileSize++;
    532         Ptrx += strlen (OPERATOR_SOR);
    533         SOR_Flag = TRUE;
    534 
    535       }
    536     } else if (strncmp (Ptrx, OPERATOR_BEFORE, strlen (OPERATOR_BEFORE)) == 0) {
    537       //
    538       //  Checks for some invalid dependencies
    539       //
    540       if (Before_Flag) {
    541 
    542         printf ("Another BEFORE operator was detected.\n");
    543         printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
    544         return EFI_INVALID_PARAMETER;
    545 
    546       } else if (After_Flag) {
    547 
    548         printf ("An AFTER operator was detected.\n");
    549         printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
    550         return EFI_INVALID_PARAMETER;
    551 
    552       } else if (SOR_Flag) {
    553 
    554         printf ("A SOR operator was detected.\n");
    555         printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
    556         return EFI_INVALID_PARAMETER;
    557 
    558       } else if (Dep_Flag) {
    559 
    560         printf ("The BEFORE operator must be the first operator following DEPENDENCY_START\n");
    561         return EFI_INVALID_PARAMETER;
    562 
    563       } else {
    564         fputc (EFI_DEP_BEFORE, OutFile);
    565         OutFileSize++;
    566         Ptrx += strlen (OPERATOR_BEFORE);
    567         Before_Flag = TRUE;
    568       }
    569     } else if (strncmp (Ptrx, OPERATOR_AFTER, strlen (OPERATOR_AFTER)) == 0) {
    570       //
    571       //  Checks for some invalid dependencies
    572       //
    573       if (Before_Flag) {
    574 
    575         printf ("A BEFORE operator was detected.\n");
    576         printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
    577         return EFI_INVALID_PARAMETER;
    578 
    579       } else if (After_Flag) {
    580 
    581         printf ("Another AFTER operator was detected.\n");
    582         printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
    583         return EFI_INVALID_PARAMETER;
    584 
    585       } else if (SOR_Flag) {
    586 
    587         printf ("A SOR operator was detected.\n");
    588         printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
    589         return EFI_INVALID_PARAMETER;
    590 
    591       } else if (Dep_Flag) {
    592 
    593         printf ("The AFTER operator must be the first operator following DEPENDENCY_START\n");
    594         return EFI_INVALID_PARAMETER;
    595 
    596       } else {
    597         fputc (EFI_DEP_AFTER, OutFile);
    598         OutFileSize++;
    599         Ptrx += strlen (OPERATOR_AFTER);
    600         Dep_Flag    = TRUE;
    601         After_Flag  = TRUE;
    602       }
    603     } else if (strncmp (Ptrx, OPERATOR_AND, strlen (OPERATOR_AND)) == 0) {
    604       while (StackPtr != EvaluationStack) {
    605         Opcode = PopOpCode ((VOID **) &StackPtr);
    606         if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {
    607           fputc (Opcode, OutFile);
    608           OutFileSize++;
    609         } else {
    610           PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);
    611           break;
    612         }
    613       }
    614 
    615       PushOpCode ((VOID **) &StackPtr, EFI_DEP_AND);
    616       Ptrx += strlen (OPERATOR_AND);
    617       Dep_Flag = TRUE;
    618 
    619     } else if (strncmp (Ptrx, OPERATOR_OR, strlen (OPERATOR_OR)) == 0) {
    620       while (StackPtr != EvaluationStack) {
    621         Opcode = PopOpCode ((VOID **) &StackPtr);
    622         if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {
    623           fputc (Opcode, OutFile);
    624           OutFileSize++;
    625         } else {
    626           PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);
    627           break;
    628         }
    629       }
    630 
    631       PushOpCode ((VOID **) &StackPtr, EFI_DEP_OR);
    632       Ptrx += strlen (OPERATOR_OR);
    633       Dep_Flag = TRUE;
    634 
    635     } else if (strncmp (Ptrx, OPERATOR_NOT, strlen (OPERATOR_NOT)) == 0) {
    636       while (StackPtr != EvaluationStack) {
    637         Opcode = PopOpCode ((VOID **) &StackPtr);
    638         if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {
    639           fputc (Opcode, OutFile);
    640           OutFileSize++;
    641         } else {
    642           PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);
    643           break;
    644         }
    645       }
    646 
    647       PushOpCode ((VOID **) &StackPtr, EFI_DEP_NOT);
    648       Ptrx += strlen (OPERATOR_NOT);
    649       Dep_Flag = TRUE;
    650 
    651     } else if (*Ptrx == '\t') {
    652 
    653       printf ("File contains tabs. This violates the coding standard\n");
    654       return EFI_INVALID_PARAMETER;
    655 
    656     } else if (*Ptrx == '\n') {
    657       //
    658       // Skip the newline character in the file
    659       //
    660       Ptrx++;
    661 
    662     } else if (strncmp (Ptrx, OPERATOR_LEFT_PARENTHESIS, strlen (OPERATOR_LEFT_PARENTHESIS)) == 0) {
    663       PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);
    664 
    665       Ptrx += strlen (OPERATOR_LEFT_PARENTHESIS);
    666       Dep_Flag = TRUE;
    667 
    668     } else if (strncmp (Ptrx, OPERATOR_RIGHT_PARENTHESIS, strlen (OPERATOR_RIGHT_PARENTHESIS)) == 0) {
    669       while (StackPtr != EvaluationStack) {
    670         Opcode = PopOpCode ((VOID **) &StackPtr);
    671         if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {
    672           fputc (Opcode, OutFile);
    673           OutFileSize++;
    674         } else {
    675           break;
    676         }
    677       }
    678 
    679       Ptrx += strlen (OPERATOR_RIGHT_PARENTHESIS);
    680       Dep_Flag = TRUE;
    681 
    682     } else if (strncmp (Ptrx, OPERATOR_TRUE, strlen (OPERATOR_TRUE)) == 0) {
    683 
    684       fputc (EFI_DEP_TRUE, OutFile);
    685 
    686       OutFileSize++;
    687 
    688       //
    689       // OutFileSize += sizeof (EFI_DEP_TRUE);
    690       //
    691       Dep_Flag = TRUE;
    692 
    693       Ptrx += strlen (OPERATOR_TRUE);
    694 
    695     } else if (strncmp (Ptrx, OPERATOR_FALSE, strlen (OPERATOR_FALSE)) == 0) {
    696 
    697       fputc (EFI_DEP_FALSE, OutFile);
    698 
    699       OutFileSize++;
    700 
    701       //
    702       // OutFileSize += sizeof (EFI_DEP_FALSE);
    703       //
    704       Dep_Flag = TRUE;
    705 
    706       Ptrx += strlen (OPERATOR_FALSE);
    707 
    708     } else if (*Ptrx == '{') {
    709       Ptrx++;
    710 
    711       if (*Ptrx == ' ') {
    712         Ptrx++;
    713       }
    714 
    715       ArgCountParsed = sscanf (
    716                         Ptrx,
    717                         "%x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x",
    718                         &Guid.Data1,
    719                         &Guid.Data2,
    720                         &Guid.Data3,
    721                         &Guid.Data4[0],
    722                         &Guid.Data4[1],
    723                         &Guid.Data4[2],
    724                         &Guid.Data4[3],
    725                         &Guid.Data4[4],
    726                         &Guid.Data4[5],
    727                         &Guid.Data4[6],
    728                         &Guid.Data4[7]
    729                         );
    730 
    731       if (ArgCountParsed != 11) {
    732         printf ("We have found an illegal GUID\n");
    733         printf ("Fix your depex\n");
    734         exit (-1);
    735       }
    736 
    737       while (*Ptrx != '}') {
    738         Ptrx++;
    739       }
    740       //
    741       // Absorb the closing }
    742       //
    743       Ptrx++;
    744 
    745       //
    746       // Don't provide a PUSH Opcode for the Before and After case
    747       //
    748       if ((!Before_Flag) && (!After_Flag)) {
    749         fputc (EFI_DEP_PUSH, OutFile);
    750         OutFileSize++;
    751       }
    752 
    753       fwrite (&Guid, sizeof (EFI_GUID), 1, OutFile);
    754 
    755       OutFileSize += sizeof (EFI_GUID);
    756       Dep_Flag = TRUE;
    757 
    758     } else if (strncmp (Ptrx, DEPENDENCY_END, strlen (DEPENDENCY_END)) == 0) {
    759       NotDone = FALSE;
    760     } else {
    761       //
    762       // Not a valid construct. Null terminate somewhere out there and
    763       // print an error message.
    764       //
    765       *(Ptrx + 20) = 0;
    766       printf (UTILITY_NAME" ERROR: Unrecognized input at: \"%s\"...\n", Ptrx);
    767       return EFI_INVALID_PARAMETER;
    768     }
    769   }
    770   //
    771   //  DRAIN();
    772   //
    773   while (StackPtr != EvaluationStack) {
    774     fputc (PopOpCode ((VOID **) &StackPtr), OutFile);
    775     OutFileSize++;
    776   }
    777 
    778   if (OutFileSize == 0) {
    779     printf ("Grammer contains no operators or constants\n");
    780     return EFI_INVALID_PARAMETER;
    781   }
    782 
    783   fputc (EFI_DEP_END, OutFile);
    784 
    785   OutFileSize++;
    786 
    787   //
    788   //  Checks for invalid padding values
    789   //
    790   if (Padding < 0) {
    791 
    792     printf ("The inputted padding value was %d\n", Padding);
    793     printf ("The optional padding value can not be less than ZERO\n");
    794     return EFI_INVALID_PARAMETER;
    795 
    796   } else if (Padding > 0) {
    797 
    798     while ((OutFileSize % Padding) != 0) {
    799 
    800       fputc (' ', OutFile);
    801       OutFileSize++;
    802     }
    803   }
    804 
    805   Results = (UINTN) fclose (InFile);
    806   if (Results != 0) {
    807     printf ("FCLOSE failed\n");
    808   }
    809 
    810   Results = (UINTN) fclose (OutFile);
    811   if (Results != 0) {
    812     printf ("FCLOSE failed\n");
    813   }
    814 
    815   free (Buffer);
    816   free (EvaluationStack);
    817 
    818   return EFI_SUCCESS;
    819 } // End GenerateDependencyExpression function
    820 
    821 EFI_STATUS
    822 main (
    823   IN UINTN argc,
    824   IN CHAR8 *argv[]
    825   )
    826 /*++
    827 
    828 Routine Description:
    829 
    830   Parse user entries.  Print some rudimentary help
    831 
    832 Arguments:
    833 
    834   argc    The count of input arguments
    835   argv    The input arguments string array
    836 
    837 Returns:
    838 
    839   EFI_SUCCESS             The function completed successfully.
    840   EFI_INVALID_PARAMETER   One of the input parameters was invalid or one of the parameters in the text file was invalid.
    841   EFI_OUT_OF_RESOURCES    Unable to allocate memory.
    842   EFI_ABORTED             Unable to open/create a file or a misc error.
    843 
    844 --*/
    845 // TODO:    ] - add argument and description to function comment
    846 {
    847   FILE    *OutFile;
    848   FILE    *InFile;
    849   UINT8   Padding;
    850   UINTN   Index;
    851   BOOLEAN Input_Flag;
    852   BOOLEAN Output_Flag;
    853   BOOLEAN Pad_Flag;
    854 
    855   InFile      = NULL;
    856   OutFile     = NULL;
    857   Padding     = 0;
    858   Input_Flag  = FALSE;
    859   Output_Flag = FALSE;
    860   Pad_Flag    = FALSE;
    861 
    862   //
    863   //  Output the calling arguments
    864   //
    865   //printf ("\n\n");
    866   //for (Index = 0; Index < argc; Index++) {
    867   //  printf ("%s ", argv[Index]);
    868   //}
    869   //
    870   //printf ("\n\n");
    871 
    872   if (argc < 5) {
    873     printf ("Not enough arguments\n");
    874     PrintGenDepexUsageInfo ();
    875     return EFI_INVALID_PARAMETER;
    876   }
    877 
    878   for (Index = 1; Index < argc - 1; Index++) {
    879 
    880     if ((strcmp (argv[Index], "-I") == 0) || (strcmp (argv[Index], "-i") == 0)) {
    881 
    882       if (!Input_Flag) {
    883 
    884         InFile      = fopen (argv[Index + 1], "rb");
    885         Input_Flag  = TRUE;
    886 
    887       } else {
    888         printf ("GenDepex only allows one INPUT (-I) argument\n");
    889         return EFI_INVALID_PARAMETER;
    890       }
    891 
    892     } else if ((strcmp (argv[Index], "-O") == 0) || (strcmp (argv[Index], "-o") == 0)) {
    893 
    894       if (!Output_Flag) {
    895 
    896         OutFile     = fopen (argv[Index + 1], "wb");
    897         Output_Flag = TRUE;
    898 
    899       } else {
    900         printf ("GenDepex only allows one OUTPUT (-O) argument\n");
    901         return EFI_INVALID_PARAMETER;
    902       }
    903 
    904     } else if ((strcmp (argv[Index], "-P") == 0) || (strcmp (argv[Index], "-p") == 0)) {
    905 
    906       if (!Pad_Flag) {
    907 
    908         Padding   = (UINT8) atoi (argv[Index + 1]);
    909         Pad_Flag  = TRUE;
    910 
    911       } else {
    912         printf ("GenDepex only allows one PADDING (-P) argument\n");
    913         return EFI_INVALID_PARAMETER;
    914       }
    915     }
    916   }
    917 
    918   PrintGenDepexUtilityInfo ();
    919 
    920   if (InFile == NULL) {
    921     printf ("Can not open <INFILE> for reading.\n");
    922     PrintGenDepexUsageInfo ();
    923     return EFI_ABORTED;
    924   }
    925 
    926   if (OutFile == NULL) {
    927     printf ("Can not open <OUTFILE> for writting.\n");
    928     PrintGenDepexUsageInfo ();
    929     return EFI_ABORTED;
    930   }
    931 
    932   return GenerateDependencyExpression (InFile, OutFile, Padding);
    933 }
    934