EDK2 doxygen online documents - Firmware Encoding Index 1
EDK2 doxygen online documents - Firmware Encoding Index

EdkCompatibilityPkg/Sample/Tools/Source/GenDepex/GenDepex.c

Go to the documentation of this file.
00001 /*++
00002 
00003 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
00004 This program and the accompanying materials                          
00005 are licensed and made available under the terms and conditions of the BSD License         
00006 which accompanies this distribution.  The full text of the license may be found at        
00007 http://opensource.org/licenses/bsd-license.php                                            
00008                                                                                           
00009 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
00010 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
00011 
00012 Module Name:
00013 
00014   GenDepex.c
00015 
00016 Abstract:
00017 
00018   Generate Dependency Expression ("GenDepex")
00019 
00020   Infix to Postfix Algorithm
00021 
00022   This code has been scrubbed to be free of having any EFI core tree dependencies.
00023   It should build in any environment that supports a standard C-library w/ string
00024   operations and File I/O services.
00025 
00026   As an example of usage, consider the following:
00027 
00028   The input user file could be something like "Sample.DXS" whose contents are
00029 
00030     #include "Tiano.h"
00031 
00032     DEPENDENCY_START
00033       NOT (DISK_IO_PROTOCOL AND SIMPLE_FILE_SYSTEM_PROTOCOL) 
00034         OR EFI_PXE_BASE_CODE_PROTOCOL
00035     DEPENDENCY_END
00036 
00037   This file is then washed through the C-preprocessor, viz.,
00038 
00039     cl /EP Sample.DXS > Sample.TMP1
00040 
00041   This yields the following file "Sample.TMP1" whose contents are
00042 
00043     DEPENDENCY_START
00044       NOT ({ 0xce345171, 0xba0b, 0x11d2, 0x8e, 0x4f, 0x0, 0xa0, 0xc9, 0x69, 0x72,
00045         0x3b } AND { 0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69,
00046         0x72, 0x3b }) OR { 0x03c4e603, 0xac28, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x27,
00047         0x3f, 0xc1, 0x4d }
00048     DEPENDENCY_END
00049 
00050   This file, in turn, will be fed into the utility, viz.,
00051 
00052     GenDepex Sample.TMP1 Sample.TMP2
00053 
00054   With a file that is 55 bytes long:
00055 
00056      55 bytes for the grammar binary
00057         PUSH opcode         - 1  byte
00058         GUID Instance       - 16 bytes
00059         PUSH opcode         - 1  byte
00060         GUID Instance       - 16 bytes
00061         AND opcode          - 1  byte
00062         NOT opcode          - 1  byte
00063         PUSH opcode         - 1  byte
00064         GUID Instance       - 16 bytes
00065         OR opcode           - 1  byte
00066         END opcode          - 1  byte
00067 
00068   The file "Sample.TMP2" could be fed via a Section-builder utility 
00069   (GenSection) that would be used for the creation of a dependency
00070   section file (.DPX) which in turn would be used by a generate FFS
00071   utility (GenFfsFile) to produce a DXE driver/core (.DXE) or 
00072   a DXE application (.APP) file.
00073 
00074   Complies with Tiano C Coding Standards Document, version 0.31, 12 Dec 2000.
00075 
00076 --*/
00077 
00078 #include "GenDepex.h"
00079 
00080 //
00081 // Utility Name
00082 //
00083 #define UTILITY_NAME  "GenDepex"
00084 
00085 //
00086 // Utility version information
00087 //
00088 #define UTILITY_VERSION "v1.0"
00089 
00090 extern
00091 BOOLEAN
00092 ParseDepex (
00093   IN      INT8      *Pbegin,
00094   IN      UINT32    length
00095   );
00096 
00097 VOID
00098 PrintGenDepexUtilityInfo (
00099   VOID
00100   )
00101 /*++
00102 
00103 Routine Description:
00104 
00105   Displays the standard utility information to SDTOUT.
00106 
00107 Arguments:
00108 
00109   None
00110 
00111 Returns:
00112 
00113   None
00114 
00115 --*/
00116 {
00117   int         Index;
00118   const char  *Str[] = {
00119     UTILITY_NAME" "UTILITY_VERSION" - Intel Generate Dependency Expression Utility",
00120     "  Copyright (C), 1996 - 2008 Intel Corporation",
00121     
00122 #if ( defined(UTILITY_BUILD) && defined(UTILITY_VENDOR) )
00123     "  Built from "UTILITY_BUILD", project of "UTILITY_VENDOR,
00124 #endif
00125     NULL
00126   };
00127   for (Index = 0; Str[Index] != NULL; Index++) {
00128     fprintf (stdout, "%s\n", Str[Index]);
00129   }
00130 }
00131 
00132 VOID
00133 PrintGenDepexUsageInfo (
00134   VOID
00135   )
00136 /*++
00137 
00138 Routine Description:
00139 
00140   Displays the utility usage syntax to STDOUT.
00141 
00142 Arguments:
00143 
00144   None
00145 
00146 Returns:
00147 
00148   None
00149 
00150 --*/
00151 {
00152   int         Index;
00153   const char  *Str[] = {
00154     "",
00155     "Usage:",
00156     "  "UTILITY_NAME" [OPTION]...",
00157     "Options:",
00158     "  -I INFILE    The input pre-processed dependency text files name",
00159     "  -O OUTFILE   The output binary dependency files name",
00160     "  -P BOUNDARY  The padding integer value to align the output file size",
00161     NULL
00162   };
00163 
00164   PrintGenDepexUtilityInfo ();
00165   for (Index = 0; Str[Index] != NULL; Index++) {
00166     fprintf (stdout, "%s\n", Str[Index]);
00167   }
00168 }
00169 
00170 DEPENDENCY_OPCODE
00171 PopOpCode (
00172   IN OUT VOID **Stack
00173   )
00174 /*++
00175 
00176 Routine Description:
00177 
00178   Pop an element from the Opcode stack.
00179 
00180 Arguments:
00181 
00182   Stack               Current top of the OpCode stack location
00183 
00184 Returns:
00185 
00186   DEPENDENCY_OPCODE   OpCode at the top of the OpCode stack.
00187   Stack               New top of the OpCode stack location
00188 
00189 
00190 --*/
00191 {
00192   DEPENDENCY_OPCODE *OpCodePtr;
00193 
00194   OpCodePtr = *Stack;
00195   OpCodePtr--;
00196   *Stack = OpCodePtr;
00197   return *OpCodePtr;
00198 }
00199 
00200 VOID
00201 PushOpCode (
00202   IN OUT  VOID                **Stack,
00203   IN      DEPENDENCY_OPCODE   OpCode
00204   )
00205 /*++
00206 
00207 Routine Description:
00208 
00209   Push an element onto the Opcode Stack
00210 
00211 Arguments:
00212 
00213   Stack     Current top of the OpCode stack location
00214   OpCode    OpCode to push onto the stack
00215 
00216 Returns:
00217 
00218   Stack     New top of the OpCode stack location
00219 
00220 --*/
00221 {
00222   DEPENDENCY_OPCODE *OpCodePtr;
00223 
00224   OpCodePtr   = *Stack;
00225   *OpCodePtr  = OpCode;
00226   OpCodePtr++;
00227   *Stack = OpCodePtr;
00228 }
00229 
00230 EFI_STATUS
00231 GenerateDependencyExpression (
00232   IN     FILE           *InFile,
00233   IN OUT FILE           *OutFile,
00234   IN     UINT8          Padding  OPTIONAL
00235   )
00236 /*++
00237 
00238 Routine Description:
00239 
00240   This takes the pre-compiled dependency text file and 
00241   converts it into a binary dependency file.
00242 
00243   The BNF for the dependency expression is as follows 
00244   (from the DXE 1.0 Draft specification).
00245 
00246   The inputted BNF grammar is thus:
00247     <depex> ::= sor <dep> | 
00248                 before GUID <dep> | 
00249                 after GUID <dep> | 
00250                 <bool>
00251 
00252     <dep> ::=   <bool> |
00253 
00254     <bool> ::=  <bool> and <term> | 
00255                 <bool> or <term> | 
00256                 <term>
00257 
00258     <term> ::=  not <factor> | 
00259                 <factor>
00260 
00261     <factor> ::= ( <bool> ) | 
00262                  <term> <term> | 
00263                  GUID | 
00264                  <boolval>
00265 
00266     <boolval> ::= true | 
00267                   false
00268 
00269   The outputed binary grammer is thus:
00270     <depex> ::= sor <dep> | 
00271                 before <depinst> <dep> | 
00272                 after <depinst> <dep> | 
00273                 <bool>
00274 
00275     <dep> ::=   <bool> |
00276 
00277     <bool> ::=  <bool> and <term> | 
00278                 <bool> or <term> | <term>
00279 
00280     <term> ::=  not <factor> | 
00281                 <factor>
00282 
00283     <factor> ::= ( <bool> ) | 
00284                  <term> <term> | 
00285                  <boolval> | 
00286                  <depinst> | 
00287                  <termval>
00288 
00289     <boolval> ::= true | 
00290                   false
00291 
00292     <depinst> ::= push GUID
00293 
00294     <termval> ::= end
00295 
00296   BugBug: A correct grammer is parsed correctly. A file that violates the
00297           grammer may parse when it should generate an error. There is some
00298           error checking and it covers most of the case when it's an include
00299           of definition issue. An ill formed expresion may not be detected.
00300 
00301 Arguments:
00302 
00303   InFile -  Input pre-compiled text file of the dependency expression.
00304             This needs to be in ASCII.
00305             The file pointer can not be NULL.
00306 
00307   OutFile - Binary dependency file.
00308             The file pointer can not be NULL.
00309 
00310   Padding - OPTIONAL integer value to pad the output file to.
00311 
00312 
00313 Returns:
00314 
00315   EFI_SUCCESS             The function completed successfully.
00316   EFI_INVALID_PARAMETER   One of the parameters in the text file was invalid.
00317   EFI_OUT_OF_RESOURCES    Unable to allocate memory.
00318   EFI_ABORTED             An misc error occurred.
00319 
00320 --*/
00321 {
00322   INT8              *Ptrx;
00323   INT8              *Pend;
00324   INT8              *EvaluationStack;
00325   INT8              *StackPtr;
00326   INT8              *Buffer;
00327   INT8              Line[LINESIZE];
00328   UINTN             Index;
00329   UINTN             OutFileSize;
00330   UINTN             FileSize;
00331   UINTN             Results;
00332   BOOLEAN           NotDone;
00333   BOOLEAN           Before_Flag;
00334   BOOLEAN           After_Flag;
00335   BOOLEAN           Dep_Flag;
00336   BOOLEAN           SOR_Flag;
00337   EFI_GUID          Guid;
00338   UINTN             ArgCountParsed;
00339   DEPENDENCY_OPCODE Opcode;
00340 
00341   Before_Flag = FALSE;
00342   After_Flag  = FALSE;
00343   Dep_Flag    = FALSE;
00344   SOR_Flag    = FALSE;
00345 
00346   memset (Line, 0, LINESIZE);
00347 
00348   OutFileSize     = 0;
00349 
00350   EvaluationStack = (INT8 *) malloc (EVAL_STACK_SIZE);
00351 
00352   if (EvaluationStack != NULL) {
00353     StackPtr = EvaluationStack;
00354   } else {
00355     printf ("Unable to allocate memory to EvaluationStack - Out of resources\n");
00356     return EFI_OUT_OF_RESOURCES;
00357   }
00358 
00359   Results = (UINTN) fseek (InFile, 0, SEEK_END);
00360 
00361   if (Results != 0) {
00362     printf ("FSEEK failed - Aborted\n");
00363     return EFI_ABORTED;
00364   }
00365 
00366   FileSize = ftell (InFile);
00367 
00368   if (FileSize == -1L) {
00369     printf ("FTELL failed - Aborted\n");
00370     return EFI_ABORTED;
00371   }
00372 
00373   Buffer = (INT8 *) malloc (FileSize + BUFFER_SIZE);
00374 
00375   if (Buffer == NULL) {
00376     printf ("Unable to allocate memory to Buffer - Out of resources\n");
00377     free (EvaluationStack);
00378 
00379     Results = (UINTN) fclose (InFile);
00380     if (Results != 0) {
00381       printf ("FCLOSE failed\n");
00382     }
00383 
00384     Results = (UINTN) fclose (OutFile);
00385     if (Results != 0) {
00386       printf ("FCLOSE failed\n");
00387     }
00388 
00389     return EFI_OUT_OF_RESOURCES;
00390   }
00391 
00392   Results = (UINTN) fseek (InFile, 0, SEEK_SET);
00393 
00394   if (Results != 0) {
00395     printf ("FSEEK failed - Aborted\n");
00396     return EFI_ABORTED;
00397   }
00398 
00399   fread (Buffer, FileSize, 1, InFile);
00400 
00401   Ptrx    = Buffer;
00402   Pend    = Ptrx + FileSize - strlen (DEPENDENCY_END);
00403   Index   = FileSize;
00404 
00405   NotDone = TRUE;
00406   while ((Index--) && NotDone) {
00407 
00408     if (strncmp (Pend, DEPENDENCY_END, strlen (DEPENDENCY_END)) == 0) {
00409       NotDone = FALSE;
00410     } else {
00411       Pend--;
00412     }
00413   }
00414 
00415   if (NotDone) {
00416     printf ("Couldn't find end string %s\n", DEPENDENCY_END);
00417 
00418     Results = (UINTN) fclose (InFile);
00419     if (Results != 0) {
00420       printf ("FCLOSE failed\n");
00421     }
00422 
00423     Results = (UINTN) fclose (OutFile);
00424     if (Results != 0) {
00425       printf ("FCLOSE failed\n");
00426     }
00427 
00428     free (Buffer);
00429     free (EvaluationStack);
00430 
00431     return EFI_INVALID_PARAMETER;
00432   }
00433 
00434   Index   = FileSize;
00435 
00436   NotDone = TRUE;
00437   while ((Index--) && NotDone) {
00438 
00439     if (strncmp (Ptrx, DEPENDENCY_START, strlen (DEPENDENCY_START)) == 0) {
00440       Ptrx += strlen (DEPENDENCY_START);
00441       NotDone = FALSE;
00442       //
00443       // BUGBUG -- should Index be decremented by sizeof(DEPENDENCY_START)?
00444       //
00445     } else {
00446       Ptrx++;
00447     }
00448   }
00449 
00450   if (NotDone) {
00451     printf ("Couldn't find start string %s\n", DEPENDENCY_START);
00452 
00453     Results = (UINTN) fclose (InFile);
00454     if (Results != 0) {
00455       printf ("FCLOSE failed\n");
00456     }
00457 
00458     Results = (UINTN) fclose (OutFile);
00459     if (Results != 0) {
00460       printf ("FCLOSE failed\n");
00461     }
00462 
00463     free (Buffer);
00464     free (EvaluationStack);
00465 
00466     return EFI_INVALID_PARAMETER;
00467   }
00468   //
00469   //  validate the syntax of expression
00470   //
00471   if (!ParseDepex (Ptrx, Pend - Ptrx - 1)) {
00472     printf ("The syntax of expression is wrong\n");
00473 
00474     Results = (UINTN) fclose (InFile);
00475     if (Results != 0) {
00476       printf ("FCLOSE failed\n");
00477     }
00478 
00479     Results = (UINTN) fclose (OutFile);
00480     if (Results != 0) {
00481       printf ("FCLOSE failed\n");
00482     }
00483 
00484     free (Buffer);
00485     free (EvaluationStack);
00486 
00487     return EFI_INVALID_PARAMETER;
00488   }
00489 
00490   NotDone = TRUE;
00491 
00492   while ((Index--) && NotDone) {
00493 
00494     if (*Ptrx == ' ') {
00495       Ptrx++;
00496     } else if (*Ptrx == '\n' || *Ptrx == '\r') {
00497       Ptrx++;
00498     } else if (strncmp (Ptrx, OPERATOR_SOR, strlen (OPERATOR_SOR)) == 0) {
00499       //
00500       //  Checks for some invalid dependencies
00501       //
00502       if (Before_Flag) {
00503 
00504         printf ("A BEFORE operator was detected.\n");
00505         printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
00506         return EFI_INVALID_PARAMETER;
00507 
00508       } else if (After_Flag) {
00509 
00510         printf ("An AFTER operator was detected.\n");
00511         printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
00512         return EFI_INVALID_PARAMETER;
00513 
00514       } else if (SOR_Flag) {
00515 
00516         printf ("Another SOR operator was detected.\n");
00517         printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
00518         return EFI_INVALID_PARAMETER;
00519 
00520       } else if (Dep_Flag) {
00521 
00522         printf ("The Schedule On Request - SOR operator must be the first operator following DEPENDENCY_START\n");
00523         return EFI_INVALID_PARAMETER;
00524 
00525       } else {
00526         //
00527         //  BUGBUG - This was not in the spec but is in the CORE code
00528         //  An OPERATOR_SOR has to be first - following the DEPENDENCY_START
00529         //
00530         fputc (EFI_DEP_SOR, OutFile);
00531         OutFileSize++;
00532         Ptrx += strlen (OPERATOR_SOR);
00533         SOR_Flag = TRUE;
00534 
00535       }
00536     } else if (strncmp (Ptrx, OPERATOR_BEFORE, strlen (OPERATOR_BEFORE)) == 0) {
00537       //
00538       //  Checks for some invalid dependencies
00539       //
00540       if (Before_Flag) {
00541 
00542         printf ("Another BEFORE operator was detected.\n");
00543         printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
00544         return EFI_INVALID_PARAMETER;
00545 
00546       } else if (After_Flag) {
00547 
00548         printf ("An AFTER operator was detected.\n");
00549         printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
00550         return EFI_INVALID_PARAMETER;
00551 
00552       } else if (SOR_Flag) {
00553 
00554         printf ("A SOR operator was detected.\n");
00555         printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
00556         return EFI_INVALID_PARAMETER;
00557 
00558       } else if (Dep_Flag) {
00559 
00560         printf ("The BEFORE operator must be the first operator following DEPENDENCY_START\n");
00561         return EFI_INVALID_PARAMETER;
00562 
00563       } else {
00564         fputc (EFI_DEP_BEFORE, OutFile);
00565         OutFileSize++;
00566         Ptrx += strlen (OPERATOR_BEFORE);
00567         Before_Flag = TRUE;
00568       }
00569     } else if (strncmp (Ptrx, OPERATOR_AFTER, strlen (OPERATOR_AFTER)) == 0) {
00570       //
00571       //  Checks for some invalid dependencies
00572       //
00573       if (Before_Flag) {
00574 
00575         printf ("A BEFORE operator was detected.\n");
00576         printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
00577         return EFI_INVALID_PARAMETER;
00578 
00579       } else if (After_Flag) {
00580 
00581         printf ("Another AFTER operator was detected.\n");
00582         printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
00583         return EFI_INVALID_PARAMETER;
00584 
00585       } else if (SOR_Flag) {
00586 
00587         printf ("A SOR operator was detected.\n");
00588         printf ("There can only be one SOR or one AFTER or one BEFORE operator\n");
00589         return EFI_INVALID_PARAMETER;
00590 
00591       } else if (Dep_Flag) {
00592 
00593         printf ("The AFTER operator must be the first operator following DEPENDENCY_START\n");
00594         return EFI_INVALID_PARAMETER;
00595 
00596       } else {
00597         fputc (EFI_DEP_AFTER, OutFile);
00598         OutFileSize++;
00599         Ptrx += strlen (OPERATOR_AFTER);
00600         Dep_Flag    = TRUE;
00601         After_Flag  = TRUE;
00602       }
00603     } else if (strncmp (Ptrx, OPERATOR_AND, strlen (OPERATOR_AND)) == 0) {
00604       while (StackPtr != EvaluationStack) {
00605         Opcode = PopOpCode ((VOID **) &StackPtr);
00606         if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {
00607           fputc (Opcode, OutFile);
00608           OutFileSize++;
00609         } else {
00610           PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);
00611           break;
00612         }
00613       }
00614 
00615       PushOpCode ((VOID **) &StackPtr, EFI_DEP_AND);
00616       Ptrx += strlen (OPERATOR_AND);
00617       Dep_Flag = TRUE;
00618 
00619     } else if (strncmp (Ptrx, OPERATOR_OR, strlen (OPERATOR_OR)) == 0) {
00620       while (StackPtr != EvaluationStack) {
00621         Opcode = PopOpCode ((VOID **) &StackPtr);
00622         if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {
00623           fputc (Opcode, OutFile);
00624           OutFileSize++;
00625         } else {
00626           PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);
00627           break;
00628         }
00629       }
00630 
00631       PushOpCode ((VOID **) &StackPtr, EFI_DEP_OR);
00632       Ptrx += strlen (OPERATOR_OR);
00633       Dep_Flag = TRUE;
00634 
00635     } else if (strncmp (Ptrx, OPERATOR_NOT, strlen (OPERATOR_NOT)) == 0) {
00636       while (StackPtr != EvaluationStack) {
00637         Opcode = PopOpCode ((VOID **) &StackPtr);
00638         if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {
00639           fputc (Opcode, OutFile);
00640           OutFileSize++;
00641         } else {
00642           PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);
00643           break;
00644         }
00645       }
00646 
00647       PushOpCode ((VOID **) &StackPtr, EFI_DEP_NOT);
00648       Ptrx += strlen (OPERATOR_NOT);
00649       Dep_Flag = TRUE;
00650 
00651     } else if (*Ptrx == '\t') {
00652 
00653       printf ("File contains tabs. This violates the coding standard\n");
00654       return EFI_INVALID_PARAMETER;
00655 
00656     } else if (*Ptrx == '\n') {
00657       //
00658       // Skip the newline character in the file
00659       //
00660       Ptrx++;
00661 
00662     } else if (strncmp (Ptrx, OPERATOR_LEFT_PARENTHESIS, strlen (OPERATOR_LEFT_PARENTHESIS)) == 0) {
00663       PushOpCode ((VOID **) &StackPtr, DXE_DEP_LEFT_PARENTHESIS);
00664 
00665       Ptrx += strlen (OPERATOR_LEFT_PARENTHESIS);
00666       Dep_Flag = TRUE;
00667 
00668     } else if (strncmp (Ptrx, OPERATOR_RIGHT_PARENTHESIS, strlen (OPERATOR_RIGHT_PARENTHESIS)) == 0) {
00669       while (StackPtr != EvaluationStack) {
00670         Opcode = PopOpCode ((VOID **) &StackPtr);
00671         if (Opcode != DXE_DEP_LEFT_PARENTHESIS) {
00672           fputc (Opcode, OutFile);
00673           OutFileSize++;
00674         } else {
00675           break;
00676         }
00677       }
00678 
00679       Ptrx += strlen (OPERATOR_RIGHT_PARENTHESIS);
00680       Dep_Flag = TRUE;
00681 
00682     } else if (strncmp (Ptrx, OPERATOR_TRUE, strlen (OPERATOR_TRUE)) == 0) {
00683 
00684       fputc (EFI_DEP_TRUE, OutFile);
00685 
00686       OutFileSize++;
00687 
00688       //
00689       // OutFileSize += sizeof (EFI_DEP_TRUE);
00690       //
00691       Dep_Flag = TRUE;
00692 
00693       Ptrx += strlen (OPERATOR_TRUE);
00694 
00695     } else if (strncmp (Ptrx, OPERATOR_FALSE, strlen (OPERATOR_FALSE)) == 0) {
00696 
00697       fputc (EFI_DEP_FALSE, OutFile);
00698 
00699       OutFileSize++;
00700 
00701       //
00702       // OutFileSize += sizeof (EFI_DEP_FALSE);
00703       //
00704       Dep_Flag = TRUE;
00705 
00706       Ptrx += strlen (OPERATOR_FALSE);
00707 
00708     } else if (*Ptrx == '{') {
00709       Ptrx++;
00710 
00711       if (*Ptrx == ' ') {
00712         Ptrx++;
00713       }
00714 
00715       ArgCountParsed = sscanf (
00716                         Ptrx,
00717                         "%x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x",
00718                         &Guid.Data1,
00719                         &Guid.Data2,
00720                         &Guid.Data3,
00721                         &Guid.Data4[0],
00722                         &Guid.Data4[1],
00723                         &Guid.Data4[2],
00724                         &Guid.Data4[3],
00725                         &Guid.Data4[4],
00726                         &Guid.Data4[5],
00727                         &Guid.Data4[6],
00728                         &Guid.Data4[7]
00729                         );
00730 
00731       if (ArgCountParsed != 11) {
00732         printf ("We have found an illegal GUID\n");
00733         printf ("Fix your depex\n");
00734         exit (-1);
00735       }
00736 
00737       while (*Ptrx != '}') {
00738         Ptrx++;
00739       }
00740       //
00741       // Absorb the closing }
00742       //
00743       Ptrx++;
00744 
00745       //
00746       // Don't provide a PUSH Opcode for the Before and After case
00747       //
00748       if ((!Before_Flag) && (!After_Flag)) {
00749         fputc (EFI_DEP_PUSH, OutFile);
00750         OutFileSize++;
00751       }
00752 
00753       fwrite (&Guid, sizeof (EFI_GUID), 1, OutFile);
00754 
00755       OutFileSize += sizeof (EFI_GUID);
00756       Dep_Flag = TRUE;
00757 
00758     } else if (strncmp (Ptrx, DEPENDENCY_END, strlen (DEPENDENCY_END)) == 0) {
00759       NotDone = FALSE;
00760     } else {
00761       //
00762       // Not a valid construct. Null terminate somewhere out there and
00763       // print an error message.
00764       //
00765       *(Ptrx + 20) = 0;
00766       printf (UTILITY_NAME" ERROR: Unrecognized input at: \"%s\"...\n", Ptrx);
00767       return EFI_INVALID_PARAMETER;
00768     }
00769   }
00770   //
00771   //  DRAIN();
00772   //
00773   while (StackPtr != EvaluationStack) {
00774     fputc (PopOpCode ((VOID **) &StackPtr), OutFile);
00775     OutFileSize++;
00776   }
00777 
00778   if (OutFileSize == 0) {
00779     printf ("Grammer contains no operators or constants\n");
00780     return EFI_INVALID_PARAMETER;
00781   }
00782 
00783   fputc (EFI_DEP_END, OutFile);
00784 
00785   OutFileSize++;
00786 
00787   //
00788   //  Checks for invalid padding values
00789   //
00790   if (Padding < 0) {
00791 
00792     printf ("The inputted padding value was %d\n", Padding);
00793     printf ("The optional padding value can not be less than ZERO\n");
00794     return EFI_INVALID_PARAMETER;
00795 
00796   } else if (Padding > 0) {
00797 
00798     while ((OutFileSize % Padding) != 0) {
00799 
00800       fputc (' ', OutFile);
00801       OutFileSize++;
00802     }
00803   }
00804 
00805   Results = (UINTN) fclose (InFile);
00806   if (Results != 0) {
00807     printf ("FCLOSE failed\n");
00808   }
00809 
00810   Results = (UINTN) fclose (OutFile);
00811   if (Results != 0) {
00812     printf ("FCLOSE failed\n");
00813   }
00814 
00815   free (Buffer);
00816   free (EvaluationStack);
00817 
00818   return EFI_SUCCESS;
00819 } // End GenerateDependencyExpression function
00820 
00821 EFI_STATUS
00822 main (
00823   IN UINTN argc,
00824   IN CHAR8 *argv[]
00825   )
00826 /*++
00827 
00828 Routine Description:
00829 
00830   Parse user entries.  Print some rudimentary help
00831 
00832 Arguments:
00833 
00834   argc    The count of input arguments
00835   argv    The input arguments string array
00836 
00837 Returns:
00838 
00839   EFI_SUCCESS             The function completed successfully.
00840   EFI_INVALID_PARAMETER   One of the input parameters was invalid or one of the parameters in the text file was invalid.
00841   EFI_OUT_OF_RESOURCES    Unable to allocate memory.
00842   EFI_ABORTED             Unable to open/create a file or a misc error.
00843 
00844 --*/
00845 // TODO:    ] - add argument and description to function comment
00846 {
00847   FILE    *OutFile;
00848   FILE    *InFile;
00849   UINT8   Padding;
00850   UINTN   Index;
00851   BOOLEAN Input_Flag;
00852   BOOLEAN Output_Flag;
00853   BOOLEAN Pad_Flag;
00854 
00855   InFile      = NULL;
00856   OutFile     = NULL;
00857   Padding     = 0;
00858   Input_Flag  = FALSE;
00859   Output_Flag = FALSE;
00860   Pad_Flag    = FALSE;
00861 
00862   //
00863   //  Output the calling arguments
00864   //
00865   //printf ("\n\n");
00866   //for (Index = 0; Index < argc; Index++) {
00867   //  printf ("%s ", argv[Index]);
00868   //}
00869   //
00870   //printf ("\n\n");
00871 
00872   if (argc < 5) {
00873     printf ("Not enough arguments\n");
00874     PrintGenDepexUsageInfo ();
00875     return EFI_INVALID_PARAMETER;
00876   }
00877 
00878   for (Index = 1; Index < argc - 1; Index++) {
00879 
00880     if ((strcmp (argv[Index], "-I") == 0) || (strcmp (argv[Index], "-i") == 0)) {
00881 
00882       if (!Input_Flag) {
00883 
00884         InFile      = fopen (argv[Index + 1], "rb");
00885         Input_Flag  = TRUE;
00886 
00887       } else {
00888         printf ("GenDepex only allows one INPUT (-I) argument\n");
00889         return EFI_INVALID_PARAMETER;
00890       }
00891 
00892     } else if ((strcmp (argv[Index], "-O") == 0) || (strcmp (argv[Index], "-o") == 0)) {
00893 
00894       if (!Output_Flag) {
00895 
00896         OutFile     = fopen (argv[Index + 1], "wb");
00897         Output_Flag = TRUE;
00898 
00899       } else {
00900         printf ("GenDepex only allows one OUTPUT (-O) argument\n");
00901         return EFI_INVALID_PARAMETER;
00902       }
00903 
00904     } else if ((strcmp (argv[Index], "-P") == 0) || (strcmp (argv[Index], "-p") == 0)) {
00905 
00906       if (!Pad_Flag) {
00907 
00908         Padding   = (UINT8) atoi (argv[Index + 1]);
00909         Pad_Flag  = TRUE;
00910 
00911       } else {
00912         printf ("GenDepex only allows one PADDING (-P) argument\n");
00913         return EFI_INVALID_PARAMETER;
00914       }
00915     }
00916   }
00917 
00918   PrintGenDepexUtilityInfo ();
00919 
00920   if (InFile == NULL) {
00921     printf ("Can not open <INFILE> for reading.\n");
00922     PrintGenDepexUsageInfo ();
00923     return EFI_ABORTED;
00924   }
00925 
00926   if (OutFile == NULL) {
00927     printf ("Can not open <OUTFILE> for writting.\n");
00928     PrintGenDepexUsageInfo ();
00929     return EFI_ABORTED;
00930   }
00931 
00932   return GenerateDependencyExpression (InFile, OutFile, Padding);
00933 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Defines