]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Sample/Tools/Source/UefiHiiPack/HiiPack.c
Sync all bug fixes between EDK1.04 and EDK1.06 into EdkCompatibilityPkg.
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / Source / UefiHiiPack / HiiPack.c
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/UefiHiiPack/HiiPack.c b/EdkCompatibilityPkg/Sample/Tools/Source/UefiHiiPack/HiiPack.c
new file mode 100644 (file)
index 0000000..c1a4c33
--- /dev/null
@@ -0,0 +1,740 @@
+/*++\r
+\r
+Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>\r
+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
+  HiiPack.c\r
+\r
+Abstract:\r
+\r
+  Process HII package files to generate HII package list binary file or PE/COFF\r
+  resource script file (i.e. .rc file).\r
+\r
+--*/\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#include "Tiano.h"\r
+#include "EfiHii.h"\r
+\r
+#include "EfiUtilityMsgs.h"\r
+#include "ParseInf.h"\r
+\r
+#define UTILITY_VERSION "v1.0"\r
+#define UTILITY_NAME    "HiiPack"\r
+#define MAX_PATH        260\r
+\r
+//\r
+// Define HII resource section type and name\r
+//\r
+#define HII_RESOURCE_TYPE   "HII"\r
+#define HII_RESOURCE_NAME   1\r
+\r
+//\r
+// We'll store lists of file names from the command line in\r
+// a linked list of these\r
+//\r
+typedef struct _FILE_NAME_LIST {\r
+  struct _FILE_NAME_LIST  *Next;\r
+  UINT8                   FileName[MAX_PATH];\r
+  UINT32                  PackageType;\r
+  UINT32                  Length;\r
+  UINT8                   *Data;\r
+} FILE_NAME_LIST;\r
+\r
+//\r
+// Create some defines for the different operation modes supported by this utility\r
+//\r
+#define MODE_CREATE_HII_RESOURCE_FILE   0x0001\r
+#define MODE_CREATE_HII_PACKAGE_LIST    0x0002\r
+\r
+//\r
+// Here's all our globals.\r
+//\r
+static struct {\r
+  FILE_NAME_LIST  *PackageFile;                  // all include paths to search\r
+  FILE_NAME_LIST  *LastPackageFile;\r
+  UINT8           PackageListFileName[MAX_PATH]; // Output package list file name\r
+  UINT8           ResourceFileName[MAX_PATH];    // Output HII resource file name\r
+  EFI_GUID        Guid;                          // Guid specified on command line\r
+  BOOLEAN         GuidSpecified;\r
+  BOOLEAN         Verbose;\r
+  UINT32          Mode;                          // Mode this utility is operating in\r
+} mGlobals;\r
+\r
+static\r
+void\r
+Usage (\r
+  VOID\r
+  );\r
+\r
+static\r
+STATUS\r
+ProcessArgs (\r
+  int   Argc,\r
+  char  *Argv[]\r
+  );\r
+\r
+static\r
+void\r
+FreeGlobals (\r
+  VOID\r
+  );\r
+\r
+static\r
+void\r
+DumpRawBytes (\r
+  FILE                  *OutFptr,\r
+  UINT8                 *Buffer,\r
+  int                   Count,\r
+  int                   Indent\r
+  );\r
+\r
+static\r
+STATUS\r
+CreateResourceScript (\r
+  char              *OutputFileName,\r
+  EFI_GUID          *PackageListGuid,\r
+  FILE_NAME_LIST    *PackageFiles\r
+  );\r
+\r
+static\r
+STATUS\r
+CreatePackageList (\r
+  char              *OutputFileName,\r
+  EFI_GUID          *PackageListGuid,\r
+  FILE_NAME_LIST    *PackageFiles\r
+  );\r
+\r
+int\r
+main (\r
+  int   Argc,\r
+  char  *Argv[]\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Call the routine to parse the command-line options, then process the file.\r
+\r
+Arguments:\r
+\r
+  Standard C main() argc and argv.\r
+\r
+Returns:\r
+\r
+  0       if successful\r
+  nonzero otherwise\r
+\r
+--*/\r
+{\r
+  STATUS  Status;\r
+\r
+  //\r
+  // Set the utility name for error reporting purposes\r
+  //\r
+  SetUtilityName (UTILITY_NAME);\r
+\r
+  //\r
+  // Process the command-line arguments\r
+  //\r
+  Status = ProcessArgs (Argc, Argv);\r
+  if (Status != STATUS_SUCCESS) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Switch based on args\r
+  //\r
+  if (mGlobals.Mode & MODE_CREATE_HII_RESOURCE_FILE) {\r
+    CreateResourceScript (mGlobals.ResourceFileName, &mGlobals.Guid, mGlobals.PackageFile);\r
+  }\r
+\r
+  if (mGlobals.Mode & MODE_CREATE_HII_PACKAGE_LIST) {\r
+    CreatePackageList (mGlobals.PackageListFileName, &mGlobals.Guid, mGlobals.PackageFile);\r
+  }\r
+\r
+  FreeGlobals ();\r
+\r
+  return GetUtilityStatus ();\r
+}\r
+\r
+/******************************************************************************/\r
+static const char *gRcFileHeader[] = {\r
+  "//",\r
+  "//  DO NOT EDIT -- auto-generated file",\r
+  "//",\r
+  "//  This file is generated by the hiipack utility",\r
+  "//",\r
+  NULL\r
+};\r
+\r
+static\r
+STATUS\r
+CreateResourceScript (\r
+  char              *OutputFileName,\r
+  EFI_GUID          *PackageListGuid,\r
+  FILE_NAME_LIST    *PackageFiles\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Given a linked list of HII package files, walk the list to\r
+  process them and create a single HII resource script file.\r
+\r
+Arguments:\r
+\r
+  OutputFileName    - name of output HII resource script file to create\r
+  PackageListGuid   - the specified package list GUID\r
+  PackageFiles      - linked list of HII package files to process\r
+\r
+Returns:\r
+\r
+  STATUS_SUCCESS    - if successful\r
+  STATUS_ERROR      - otherwise\r
+\r
+--*/\r
+{\r
+  STATUS            Status;\r
+  UINT8             *PackageList;\r
+  UINT8             *Buffer;\r
+  UINT32            PackageListLen;\r
+  FILE              *OutFptr;\r
+  UINTN             Index;\r
+  FILE_NAME_LIST    *Package;\r
+\r
+  //\r
+  // If no input HII pack files, then why are we here? Should have been caught when\r
+  // args were processed though.\r
+  //\r
+  if (PackageFiles == NULL) {\r
+    Error (NULL, 0, 0, "no input package file(s) specified", NULL);\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  OutFptr = NULL;\r
+  Status  = STATUS_ERROR;\r
+\r
+  //\r
+  // Open the output file for writing\r
+  //\r
+  if ((OutFptr = fopen (OutputFileName, "w")) == NULL) {\r
+    Error (NULL, 0, 0, OutputFileName, "failed to open output file for writing");\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Write file header\r
+  //\r
+  for (Index = 0; gRcFileHeader[Index] != NULL; Index++) {\r
+    fprintf (OutFptr, "%s\n", gRcFileHeader[Index]);\r
+  }\r
+\r
+  //\r
+  // Write nameID and typeID\r
+  //\r
+  fprintf (OutFptr, "\n");\r
+  fprintf (OutFptr, "%d %s\n", HII_RESOURCE_NAME, HII_RESOURCE_TYPE);\r
+  fprintf (OutFptr, "{\n");\r
+\r
+  //\r
+  // Prepare package list\r
+  //\r
+  PackageListLen = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
+  Package = PackageFiles;\r
+  while (Package != NULL) {\r
+    PackageListLen += Package->Length;\r
+    Package = Package->Next;\r
+  }\r
+  //\r
+  // Inlucde the length of EFI_HII_PACKAGE_END\r
+  //\r
+  PackageListLen += sizeof (EFI_HII_PACKAGE_HEADER);\r
+\r
+  Buffer = (UINT8 *) malloc (PackageListLen);\r
+  if (Buffer == NULL) {\r
+    Error (NULL, 0, 0, "memory allocation failure", NULL);\r
+    goto Done;\r
+  }\r
+  PackageList = Buffer;\r
+\r
+  memcpy (Buffer, PackageListGuid, sizeof (EFI_GUID));\r
+  Buffer += sizeof (EFI_GUID);\r
+  memcpy (Buffer, &PackageListLen, sizeof (UINT32));\r
+  Buffer += sizeof (UINT32);\r
+\r
+  Package = PackageFiles;\r
+  while (Package != NULL) {\r
+    memcpy (Buffer, Package->Data, Package->Length);\r
+    Buffer += Package->Length;\r
+    Package = Package->Next;\r
+  }\r
+  //\r
+  // Append EFI_HII_PACKAGE_END\r
+  //\r
+  ((EFI_HII_PACKAGE_HEADER *) Buffer)->Type = EFI_HII_PACKAGE_END;\r
+  ((EFI_HII_PACKAGE_HEADER *) Buffer)->Length = sizeof (EFI_HII_PACKAGE_HEADER);\r
+\r
+  //\r
+  // Dump package list\r
+  //\r
+  DumpRawBytes (OutFptr, PackageList, PackageListLen, 2);\r
+\r
+  //\r
+  // Write file tail\r
+  //\r
+  fprintf (OutFptr, "}\n");\r
+\r
+  Status = STATUS_SUCCESS;\r
+\r
+Done:\r
+  if (OutFptr != NULL) {\r
+    fclose (OutFptr);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+static\r
+STATUS\r
+CreatePackageList (\r
+  char              *OutputFileName,\r
+  EFI_GUID          *PackageListGuid,\r
+  FILE_NAME_LIST    *PackageFiles\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Given a linked list of HII package files, walk the list to\r
+  process them and create a binary HII package list file.\r
+\r
+Arguments:\r
+\r
+  OutputFileName    - name of output HII package list file to create\r
+  PackageListGuid   - the specified package list GUID\r
+  PackageFiles      - linked list of HII package files to process\r
+\r
+Returns:\r
+\r
+  STATUS_SUCCESS    - if successful\r
+  STATUS_ERROR      - otherwise\r
+\r
+--*/\r
+{\r
+  FILE            *OutFptr;\r
+  UINT32          PackageListLen;\r
+  FILE_NAME_LIST  *Package;\r
+\r
+  if (OutputFileName == NULL || PackageListGuid == NULL || PackageFiles == NULL) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  //\r
+  // Open the output file for writing\r
+  //\r
+  if ((OutFptr = fopen (OutputFileName, "wb")) == NULL) {\r
+    Error (NULL, 0, 0, OutputFileName, "failed to open output file for writing");\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Write package list header\r
+  //\r
+  PackageListLen = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
+  Package = PackageFiles;\r
+  while (Package != NULL) {\r
+    PackageListLen += Package->Length;\r
+    Package = Package->Next;\r
+  }\r
+  fwrite (PackageListGuid, sizeof (UINT8), sizeof (EFI_GUID), OutFptr);\r
+  fwrite (&PackageListLen, sizeof (UINT8), sizeof (UINT32), OutFptr);\r
+\r
+  //\r
+  // Write packages\r
+  //\r
+  Package = PackageFiles;\r
+  while (Package != NULL) {\r
+    fwrite (Package->Data, sizeof (UINT8), Package->Length, OutFptr);\r
+    Package = Package->Next;\r
+  }\r
+\r
+Done:\r
+  if (OutFptr != NULL) {\r
+    fclose (OutFptr);\r
+  }\r
+\r
+  return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+void\r
+FreeGlobals (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Free up an memory we allocated so we can exit cleanly\r
+\r
+Arguments:\r
+\r
+Returns: NA\r
+\r
+--*/\r
+{\r
+  FILE_NAME_LIST  *Next;\r
+\r
+  //\r
+  // Free up input package file names\r
+  //\r
+  while (mGlobals.PackageFile != NULL) {\r
+    Next = mGlobals.PackageFile->Next;\r
+    if (mGlobals.PackageFile->Data != NULL) {\r
+      free (mGlobals.PackageFile->Data);\r
+    }\r
+    free (mGlobals.PackageFile);\r
+    mGlobals.PackageFile = Next;\r
+  }\r
+}\r
+\r
+static\r
+void\r
+DumpRawBytes (\r
+  FILE                  *OutFptr,\r
+  UINT8                 *Buffer,\r
+  int                   Count,\r
+  int                   Indent\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Dump buffer data into output file.\r
+\r
+Arguments:\r
+\r
+  OutFptr     - FILE pointer to output file.\r
+  Buffer      - the buffer to dump\r
+  Count       - number of bytes to dump\r
+  Indent      - indent at each line start\r
+\r
+Returns:\r
+\r
+  Nothing.\r
+\r
+--*/\r
+{\r
+  int    Counter;\r
+  int    Count2;\r
+  UINT16 *Ptr16;\r
+\r
+  Ptr16 = (UINT16 *) Buffer;\r
+  Count2 = Count - (Count & 0x1);\r
+\r
+  for (Counter = 0; Counter < Count2; Counter += 2) {\r
+    if ((Counter & 0xF) == 0) {\r
+      if (Counter == 0) {\r
+        fprintf (OutFptr, "%*c", Indent, ' ');\r
+      } else {\r
+        fprintf (OutFptr, "\n%*c", Indent, ' ');\r
+      }\r
+    }\r
+\r
+    fprintf (OutFptr, "0x%04X, ", (unsigned int) *Ptr16);\r
+    Ptr16++;\r
+  }\r
+\r
+  //\r
+  // Handle the last byte\r
+  //\r
+  if ((Count & 0x1) != 0) {\r
+    if ((Counter & 0xF) == 0) {\r
+      if (Counter == 0) {\r
+        fprintf (OutFptr, "%*c", Indent, ' ');\r
+      } else {\r
+        fprintf (OutFptr, "\n%*c", Indent, ' ');\r
+      }\r
+    }\r
+\r
+    fprintf (OutFptr, "0x%04X, ", (unsigned int) (*Ptr16 & 0xff));\r
+  }\r
+\r
+  fprintf (OutFptr, "\n");\r
+}\r
+\r
+static\r
+STATUS\r
+LoadPackage (\r
+  FILE_NAME_LIST      *NameList\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Process the command line arguments\r
+\r
+Arguments:\r
+\r
+  NameList    - the FILE_NAME_LIST linked list node\r
+\r
+Returns:\r
+\r
+  STATUS_SUCCESS    - if successful\r
+  STATUS_ERROR      - otherwise\r
+\r
+--*/\r
+{\r
+  STATUS                  Status;\r
+  FILE                    *InFptr;\r
+  UINT32                  BufferSize;\r
+  UINT8                   *Buffer;\r
+  EFI_HII_PACKAGE_HEADER  *PackageHeader;\r
+  EFI_IFR_FORM_SET        *FormSet;\r
+\r
+  Status = STATUS_SUCCESS;\r
+  if (NameList == NULL) {\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  //\r
+  // Try to open the package file\r
+  //\r
+  if ((InFptr = fopen (NameList->FileName, "rb")) == NULL) {\r
+    Error (NULL, 0, 0, NameList->FileName, "failed to open input file for read");\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  //\r
+  // Get the file size, then allocate a buffer and read in the file contents.\r
+  //\r
+  fseek (InFptr, 0, SEEK_END);\r
+  BufferSize = (UINT32) ftell (InFptr);\r
+  fseek (InFptr, 0, SEEK_SET);\r
+  Buffer = (UINT8 *) malloc (BufferSize);\r
+  if (Buffer == NULL) {\r
+    Error (NULL, 0, 0, "memory allocation failure", NULL);\r
+    goto Done;\r
+  }\r
+\r
+  if (fread (Buffer, sizeof (UINT8), BufferSize, InFptr) != BufferSize) {\r
+    Error (NULL, 0, 0, NameList->FileName, "error reading file contents");\r
+    Status = STATUS_ERROR;\r
+    goto Done;\r
+  }\r
+\r
+  NameList->Length = BufferSize;\r
+  NameList->Data = Buffer;\r
+\r
+  PackageHeader = (EFI_HII_PACKAGE_HEADER *) Buffer;\r
+  NameList->PackageType = PackageHeader->Type;\r
+\r
+  if (!mGlobals.GuidSpecified && NameList->PackageType == EFI_HII_PACKAGE_FORMS) {\r
+    FormSet = (EFI_IFR_FORM_SET *) (Buffer + sizeof (EFI_HII_PACKAGE_HEADER));\r
+    memcpy (&mGlobals.Guid, &FormSet->Guid, sizeof (EFI_GUID));\r
+    mGlobals.GuidSpecified = TRUE;\r
+  }\r
+\r
+Done:\r
+  fclose (InFptr);\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+static\r
+STATUS\r
+ProcessArgs (\r
+  int   Argc,\r
+  char  *Argv[]\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Process the command line arguments\r
+\r
+Arguments:\r
+\r
+  As per standard C main()\r
+\r
+Returns:\r
+\r
+  STATUS_SUCCESS    - if successful\r
+  STATUS_ERROR      - otherwise\r
+\r
+--*/\r
+{\r
+  FILE_NAME_LIST  *NewList;\r
+  STATUS          Status;\r
+\r
+  Status = STATUS_SUCCESS;\r
+  memset ((void *) &mGlobals, 0, sizeof (mGlobals));\r
+\r
+  //\r
+  // Skip program name\r
+  //\r
+  Argc--;\r
+  Argv++;\r
+\r
+  if (Argc == 0) {\r
+    Usage ();\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  if (_stricmp (Argv[0], "-h") == 0 || _stricmp (Argv[0], "-?") == 0) {\r
+    Usage ();\r
+    return STATUS_ERROR;\r
+  }\r
+\r
+  //\r
+  // Process until no more args.\r
+  //\r
+  while (Argc > 0) {\r
+    if (_stricmp (Argv[0], "-rc") == 0) {\r
+      Argc--;\r
+      Argv++;\r
+\r
+      if (Argc == 0) {\r
+        Error (UTILITY_NAME, 0, 0, "mising HII resource file name", NULL);\r
+        Status = STATUS_ERROR;\r
+        goto Done;\r
+      }\r
+\r
+      strcpy (mGlobals.ResourceFileName, Argv[0]);\r
+      mGlobals.Mode |= MODE_CREATE_HII_RESOURCE_FILE;\r
+\r
+    } else if (_stricmp (Argv[0], "-hii") == 0) {\r
+      Argc--;\r
+      Argv++;\r
+\r
+      if (Argc == 0) {\r
+        Error (UTILITY_NAME, 0, 0, "mising HII package list file name", NULL);\r
+        Status = STATUS_ERROR;\r
+        goto Done;\r
+      }\r
+\r
+      strcpy (mGlobals.PackageListFileName, Argv[0]);\r
+      mGlobals.Mode |= MODE_CREATE_HII_PACKAGE_LIST;\r
+\r
+    } else if (_stricmp (Argv[0], "-g") == 0) {\r
+      Argc--;\r
+      Argv++;\r
+\r
+      if (Argc == 0) {\r
+        Error (UTILITY_NAME, 0, 0, "mising package list GUID", NULL);\r
+        Status = STATUS_ERROR;\r
+        goto Done;\r
+      }\r
+\r
+      Status = StringToGuid (Argv[0], &mGlobals.Guid);\r
+      if (Status != STATUS_SUCCESS) {\r
+        goto Done;\r
+      }\r
+      mGlobals.GuidSpecified = TRUE;\r
+\r
+    } else {\r
+      //\r
+      // This is a package file\r
+      //\r
+      NewList = malloc (sizeof (FILE_NAME_LIST));\r
+      if (NewList == NULL) {\r
+        Error (UTILITY_NAME, 0, 0, "memory allocation failure", NULL);\r
+        Status = STATUS_ERROR;\r
+        goto Done;\r
+      }\r
+\r
+      memset (NewList, 0, sizeof (FILE_NAME_LIST));\r
+      strcpy (NewList->FileName, Argv[0]);\r
+\r
+      if (mGlobals.PackageFile == NULL) {\r
+        mGlobals.PackageFile = NewList;\r
+      } else {\r
+        mGlobals.LastPackageFile->Next = NewList;\r
+      }\r
+      mGlobals.LastPackageFile = NewList;\r
+\r
+      Status = LoadPackage (NewList);\r
+      if (Status != STATUS_SUCCESS) {\r
+        goto Done;\r
+      }\r
+    }\r
+\r
+    Argc--;\r
+    Argv++;\r
+  }\r
+\r
+  if (!mGlobals.GuidSpecified) {\r
+    Error (UTILITY_NAME, 0, 0, "please specify HII pakcage list GUID", NULL);\r
+    Status = STATUS_ERROR;\r
+  }\r
+\r
+Done:\r
+  if (Status != STATUS_SUCCESS) {\r
+    FreeGlobals ();\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+static\r
+void\r
+Usage (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Print usage information for this utility.\r
+\r
+Arguments:\r
+\r
+  None.\r
+\r
+Returns:\r
+\r
+  Nothing.\r
+\r
+--*/\r
+{\r
+  int        i;\r
+  const char *Str[] = {\r
+    UTILITY_NAME" "UTILITY_VERSION" - UEFI HII Package List Utility",\r
+    "  Copyright (C), 2008 Intel Corporation",\r
+    \r
+#if ( defined(UTILITY_BUILD) && defined(UTILITY_VENDOR) )\r
+    "  Built from "UTILITY_BUILD", project of "UTILITY_VENDOR,\r
+#endif\r
+    "",\r
+    "Usage:",\r
+    "  "UTILITY_NAME" [OPTION] PACKAGE [PACKAGE [...]]",\r
+    "Description:",\r
+    "  Merge HII package files into a single HII Package List.",\r
+    "Options:",\r
+    "  -rc  FileName               write output to PE/COFF Resource Script file",\r
+    "  -hii FileName               write output to binary Package List file",\r
+    "  -g   GUID                   use GUID for the HII Package List Guid",\r
+    "",\r
+    "PACKAGE is the raw binary HII package file generated by StrGather or",\r
+    "VfrCompiler which named as *.hpk. For example, merge a Form package and",\r
+    "a String package into one HII package list:",\r
+    "  \""UTILITY_NAME" -rc Sample.rc -hii Sample.hii \\",\r
+    "           -g 12345678-1234-1234-1234-123456789abc Vfr.hpk Strings.hpk\"",\r
+    NULL\r
+  };\r
+  for (i = 0; Str[i] != NULL; i++) {\r
+    fprintf (stdout, "%s\n", Str[i]);\r
+  }\r
+}\r