Add Mde String and PrintLibs. Port StrGather to the Mde Unicode implementation. Compi...
authorbbahnsen <bbahnsen@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 31 May 2006 21:02:55 +0000 (21:02 +0000)
committerbbahnsen <bbahnsen@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 31 May 2006 21:02:55 +0000 (21:02 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@358 6f19259b-4bc3-4df7-8a09-765794883524

Tools/Source/TianoTools/Common/CommonLib.h
Tools/Source/TianoTools/StrGather/StrGather.c
Tools/Source/TianoTools/StrGather/StringDB.c
Tools/Source/TianoTools/StrGather/build.xml
Tools/Source/TianoTools/String/PrintLib.c [new file with mode: 0644]
Tools/Source/TianoTools/String/PrintLibInternal.c [new file with mode: 0644]
Tools/Source/TianoTools/String/PrintLibInternal.h [new file with mode: 0644]
Tools/Source/TianoTools/String/String.c [new file with mode: 0644]
Tools/Source/TianoTools/String/build.xml [new file with mode: 0644]
Tools/Source/TianoTools/build.xml

index 63f77e4..80cd883 100644 (file)
@@ -127,6 +127,8 @@ PrintGuidToBuffer (
   )\r
 ;\r
 \r
+#define ASSERT(x) assert(x)\r
+\r
 #ifdef __GNUC__\r
 #define stricmp strcasecmp\r
 #define strnicmp strncasecmp\r
index 3ad7724..1fc204d 100644 (file)
@@ -1248,21 +1248,21 @@ ProcessTokenLanguage (
       // quoted strings, and concatenate them until we get a failure\r
       // back from the string parser.\r
       //\r
-      Len = wcslen (String) + 1;\r
+      Len = StrLen (String) + 1;\r
       ParserSetPosition (SourceFile->FileName, SourceFile->LineNum);\r
       do {\r
         SkipWhiteSpace (SourceFile);\r
         SecondString = GetQuotedString (SourceFile, TRUE);\r
         if (SecondString != NULL) {\r
-          Len += wcslen (SecondString);\r
+          Len += StrLen (SecondString);\r
           TempString = (WCHAR *) malloc (Len * sizeof (WCHAR));\r
           if (TempString == NULL) {\r
             Error (NULL, 0, 0, "application error", "failed to allocate memory");\r
             return ;\r
           }\r
 \r
-          wcscpy (TempString, String);\r
-          wcscat (TempString, SecondString);\r
+          StrCpy (TempString, String);\r
+          StrCat (TempString, SecondString);\r
           free (String);\r
           free (SecondString);\r
           String = TempString;\r
@@ -1973,14 +1973,14 @@ AddCommandLineLanguage (
     // long. If we find a comma, then we're done with this group, so\r
     // break out.\r
     //\r
-    swprintf (WNewList->Str, L"%S", Language);\r
+    UnicodeSPrint (WNewList->Str, (strlen (Language) + 1) * sizeof (WCHAR), L"%a", Language);\r
     From = To = WNewList->Str;\r
     while (*From) {\r
       if (*From == L',') {\r
         break;\r
       }\r
 \r
-      if ((wcslen (From) < LANGUAGE_IDENTIFIER_NAME_LEN) ||\r
+      if ((StrLen (From) < LANGUAGE_IDENTIFIER_NAME_LEN) ||\r
             (\r
               (From[LANGUAGE_IDENTIFIER_NAME_LEN] != 0) &&\r
               (From[LANGUAGE_IDENTIFIER_NAME_LEN] != UNICODE_PLUS_SIGN) &&\r
@@ -1993,7 +1993,7 @@ AddCommandLineLanguage (
         return STATUS_ERROR;\r
       }\r
 \r
-      wcsncpy (To, From, LANGUAGE_IDENTIFIER_NAME_LEN);\r
+      StrnCpy (To, From, LANGUAGE_IDENTIFIER_NAME_LEN);\r
       To += LANGUAGE_IDENTIFIER_NAME_LEN;\r
       From += LANGUAGE_IDENTIFIER_NAME_LEN;\r
       if (*From == L'+') {\r
@@ -2114,8 +2114,8 @@ ParseIndirectionFiles (
                 goto Done;\r
               }\r
 \r
-              swprintf (NewList->Str1, L"%S", StringName);\r
-              swprintf (NewList->Str2, L"%S", ScopeName);\r
+              UnicodeSPrint (NewList->Str1, strlen (StringName) + 1, L"%a", StringName);\r
+              UnicodeSPrint (NewList->Str2, strlen (ScopeName) + 1, L"%a", ScopeName);\r
               if (mGlobals.IndirectionList == NULL) {\r
                 mGlobals.IndirectionList = NewList;\r
               } else {\r
index f452bbc..353fabb 100644 (file)
@@ -26,6 +26,7 @@ Abstract:
 #include <Base.h>\r
 #include <UefiBaseTypes.h>\r
 #include <MultiPhase.h>\r
+#include <BaseLib.h>\r
 #include "EfiUtilityMsgs.h"\r
 #include "StrGather.h"\r
 #include "StringDB.h"\r
@@ -399,6 +400,7 @@ StringDBDumpCStrings (
   WCHAR                       *TempStringPtr;\r
   WCHAR                       *LangName;\r
   STRING_IDENTIFIER           *StringIdentifier;\r
+  WCHAR                       Line[200];\r
 \r
   if ((Fptr = fopen (FileName, "w")) == NULL) {\r
     Error (NULL, 0, 0, FileName, "failed to open output C string file");\r
@@ -434,7 +436,7 @@ StringDBDumpCStrings (
     if (LanguagesOfInterest != NULL) {\r
       LanguageOk = FALSE;\r
       for (LOIPtr = LanguagesOfInterest; LOIPtr != NULL; LOIPtr = LOIPtr->Next) {\r
-        if (wcsncmp (LOIPtr->Str, Lang->LanguageName, LANGUAGE_IDENTIFIER_NAME_LEN) == 0) {\r
+        if (StrnCmp (LOIPtr->Str, Lang->LanguageName, LANGUAGE_IDENTIFIER_NAME_LEN) == 0) {\r
           LangName    = LOIPtr->Str;\r
           LanguageOk  = TRUE;\r
           break;\r
@@ -460,13 +462,13 @@ StringDBDumpCStrings (
     //   Offset[]  -- an array of offsets to strings, of type RELOFST each\r
     //   String[]  -- the actual strings themselves\r
     //\r
-    fprintf (\r
-      Fptr,\r
+    AsciiSPrint ( Line, sizeof(Line),\r
       "\n//******************************************************************************"\r
-      "\n// Start of string definitions for %S/%S",\r
+      "\n// Start of string definitions for %s/%s",\r
       Lang->LanguageName,\r
       Lang->PrintableLanguageName\r
       );\r
+    fprintf (Fptr, "%s", Line);\r
     memset ((char *) &StringPack, 0, sizeof (EFI_HII_STRING_PACK));\r
     StringPack.Header.Type        = EFI_HII_STRING;\r
     StringPack.NumStringPointers  = (UINT16) mDBData.NumStringIdentifiersReferenced;\r
@@ -479,7 +481,7 @@ StringDBDumpCStrings (
     // entry for the printable language name as well.\r
     //\r
     StringPack.LanguageNameString = (STRING_OFFSET) (sizeof (EFI_HII_STRING_PACK) + (mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET)));\r
-    StringPack.PrintableLanguageName = (STRING_OFFSET) (StringPack.LanguageNameString + (wcslen (LangName) + 1) * sizeof (WCHAR));\r
+    StringPack.PrintableLanguageName = (STRING_OFFSET) (StringPack.LanguageNameString + (StrLen (LangName) + 1) * sizeof (WCHAR));\r
     //\r
     // Add up the size of all strings so we can fill in our header.\r
     //\r
@@ -490,7 +492,7 @@ StringDBDumpCStrings (
       // requested it. We set LangName to point to the proper language name string above.\r
       //\r
       if (StringIndex == STRING_ID_LANGUAGE_NAME) {\r
-        Len += (wcslen (LangName) + 1) * sizeof (WCHAR);\r
+        Len += (StrLen (LangName) + 1) * sizeof (WCHAR);\r
       } else {\r
         //\r
         // Find a string with this language.stringname\r
@@ -578,13 +580,14 @@ StringDBDumpCStrings (
         return STATUS_ERROR;\r
       }\r
 \r
-      fprintf (Fptr, " // offset to string %S (0x%04X)", StringIdentifier->StringName, StringIndex);\r
+      AsciiSPrint (Line, sizeof(Line) , " // offset to string %s (0x%04X)", StringIdentifier->StringName, StringIndex);\r
+      fprintf (Fptr, "%s", Line);\r
       //\r
       // For the first string (language name), we print out the "spacat" if they\r
       // requested it. We set LangName to point to the proper language name string above.\r
       //\r
       if (StringIndex == STRING_ID_LANGUAGE_NAME) {\r
-        Offset += (wcslen (LangName) + 1) * sizeof (WCHAR);\r
+        Offset += (StrLen (LangName) + 1) * sizeof (WCHAR);\r
         CurrString = StringDBFindString (\r
                       Lang->LanguageName,\r
                       StringIdentifier->StringName,\r
@@ -634,12 +637,13 @@ StringDBDumpCStrings (
 \r
       if (CurrString->Flags & STRING_FLAGS_UNDEFINED) {\r
         fprintf (Fptr, " - not defined for this language");\r
-      } else if (wcscmp (CurrString->LanguageName, Lang->LanguageName) != 0) {\r
-        fprintf (\r
-          Fptr,\r
-          " - not defined for this language -- using secondary language %S definition",\r
+      } else if (StrCmp (CurrString->LanguageName, Lang->LanguageName) != 0) {\r
+        AsciiSPrint (\r
+          Line, sizeof(Line),\r
+          " - not defined for this language -- using secondary language %s definition",\r
           CurrString->LanguageName\r
           );\r
+        fprintf ( Fptr, "%s", Line);\r
       }\r
 \r
       fprintf (Fptr, "\n");\r
@@ -650,7 +654,8 @@ StringDBDumpCStrings (
     while (StringIndex < mDBData.NumStringIdentifiers) {\r
       StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex);\r
       if (StringIdentifier != NULL) {\r
-        fprintf (Fptr, "  // %S not referenced\n", StringIdentifier->StringName);\r
+        AsciiSPrint (Line, sizeof(Line), "  // %s not referenced\n", StringIdentifier->StringName);\r
+        fprintf (Fptr, "%s", Line);\r
       }\r
 \r
       StringIndex++;\r
@@ -669,7 +674,8 @@ StringDBDumpCStrings (
         return STATUS_ERROR;\r
       }\r
 \r
-      fprintf (Fptr, "  // string %S offset 0x%08X\n  ", StringIdentifier->StringName, Offset);\r
+      AsciiSPrint (Line, sizeof(Line), "  // string %s offset 0x%08X\n  ", StringIdentifier->StringName, Offset);\r
+      fprintf (Fptr, "%s", Line);\r
       //\r
       // For the first string (language name), we print out the "spacat" if they\r
       // requested it. We set LangName to point to the proper language name string above.\r
@@ -795,6 +801,7 @@ StringDBDumpStringDefines (
   FILE              *Fptr;\r
   STRING_IDENTIFIER *Identifier;\r
   INT8              CopyBaseName[100];\r
+  WCHAR             Line[200];\r
   UINT32            Index;\r
   const INT8        *StrDefHeader[] = {\r
     "#ifndef _%s_STRINGS_DEFINE_H_\n",\r
@@ -844,9 +851,11 @@ StringDBDumpStringDefines (
     }\r
 \r
     if (Identifier->Flags & STRING_FLAGS_REFERENCED) {\r
-      fprintf (Fptr, "#define %-40S 0x%04X\n", Identifier->StringName, Identifier->Index);\r
+      AsciiSPrint (Line, sizeof(Line), "#define %-40s 0x%04X\n", Identifier->StringName, Identifier->Index);\r
+      fprintf (Fptr, "%s", Line);\r
     } else {\r
-      fprintf (Fptr, "//#define %-40S 0x%04X // not referenced\n", Identifier->StringName, Identifier->Index);\r
+      AsciiSPrint (Line, sizeof(Line), "//#define %-40s 0x%04X // not referenced\n", Identifier->StringName, Identifier->Index);\r
+      fprintf (Fptr, "%s", Line);\r
     }\r
 \r
     Identifier = Identifier->Next;\r
@@ -909,13 +918,13 @@ StringDBAddStringIdentifier (
   }\r
 \r
   memset ((char *) StringIdentifier, 0, sizeof (STRING_IDENTIFIER));\r
-  StringIdentifier->StringName = (WCHAR *) malloc ((wcslen (StringName) + 1) * sizeof (WCHAR));\r
+  StringIdentifier->StringName = (WCHAR *) malloc ((StrLen (StringName) + 1) * sizeof (WCHAR));\r
   if (StringIdentifier->StringName == NULL) {\r
     Error (NULL, 0, 0, NULL, "memory allocation error");\r
     return STATUS_ERROR;\r
   }\r
 \r
-  wcscpy (StringIdentifier->StringName, StringName);\r
+  StrCpy (StringIdentifier->StringName, StringName);\r
   if (*NewId != STRING_ID_INVALID) {\r
     StringIdentifier->Index = *NewId;\r
     StringIdentifier->Flags |= STRING_FLAGS_INDEX_ASSIGNED;\r
@@ -991,7 +1000,7 @@ StringDBAddString (
   // Truncate at 3 if it's longer, or make it 3 if it's shorter.\r
   //\r
   if (LanguageName != NULL) {\r
-    Size = wcslen (LanguageName);\r
+    Size = StrLen (LanguageName);\r
     if (Size != 3) {\r
       ParserError (0, "invalid length for language name", "%S", LanguageName);\r
       if (Size > 3) {\r
@@ -1002,7 +1011,7 @@ StringDBAddString (
         // 3 characters since we make assumptions elsewhere in this program\r
         // on the length.\r
         //\r
-        wcscpy (TempLangName, LanguageName);\r
+        StrCpy (TempLangName, LanguageName);\r
         for (; Size < 3; Size++) {\r
           TempLangName[Size] = L'?';\r
         }\r
@@ -1061,8 +1070,8 @@ StringDBAddString (
   // user does not specifically define them.\r
   //\r
   if (StringDBFindString (Lang->LanguageName, StringName, Scope, NULL, NULL) != NULL) {\r
-    if ((wcscmp (StringName, LANGUAGE_NAME_STRING_NAME) == 0) &&\r
-        (wcscmp (StringName, PRINTABLE_LANGUAGE_NAME_STRING_NAME) == 0)\r
+    if ((StrCmp (StringName, LANGUAGE_NAME_STRING_NAME) == 0) &&\r
+        (StrCmp (StringName, PRINTABLE_LANGUAGE_NAME_STRING_NAME) == 0)\r
         ) {\r
       ParserError (\r
         0,\r
@@ -1092,7 +1101,7 @@ StringDBAddString (
   }\r
 \r
   memset ((char *) Str, 0, sizeof (STRING_LIST));\r
-  Size              = (wcslen (String) + 1) * sizeof (WCHAR);\r
+  Size              = (StrLen (String) + 1) * sizeof (WCHAR);\r
   Str->Flags        = Flags;\r
   Str->Scope        = Scope;\r
   Str->StringName   = StringIdentifier->StringName;\r
@@ -1105,7 +1114,7 @@ StringDBAddString (
   //\r
   // If not formatting, just copy the string.\r
   //\r
-  wcscpy (Str->Str, String);\r
+  StrCpy (Str->Str, String);\r
   if (Format) {\r
     StringDBFormatString (Str->Str);\r
   }\r
@@ -1114,7 +1123,7 @@ StringDBAddString (
   // the actual size of the string, including the null for\r
   // easier processing later.\r
   //\r
-  Str->Size = (wcslen (Str->Str) + 1) * sizeof (WCHAR);\r
+  Str->Size = (StrLen (Str->Str) + 1) * sizeof (WCHAR);\r
   if (Lang->String == NULL) {\r
     Lang->String = Str;\r
   } else {\r
@@ -1152,7 +1161,7 @@ StringDBFindLanguageList (
 \r
   Lang = mDBData.LanguageList;\r
   while (Lang != NULL) {\r
-    if (wcscmp (LanguageName, Lang->LanguageName) == 0) {\r
+    if (StrCmp (LanguageName, Lang->LanguageName) == 0) {\r
       break;\r
     }\r
 \r
@@ -1196,7 +1205,7 @@ StringDBAddLanguage (
     //\r
     // Better be the same printable name\r
     //\r
-    if (wcscmp (PrintableLanguageName, Lang->PrintableLanguageName) != 0) {\r
+    if (StrCmp (PrintableLanguageName, Lang->PrintableLanguageName) != 0) {\r
       ParserError (\r
         0,\r
         "language redefinition",\r
@@ -1228,14 +1237,14 @@ StringDBAddLanguage (
     // Save the language name, then allocate memory to save the\r
     // printable language name\r
     //\r
-    wcscpy (Lang->LanguageName, LanguageName);\r
-    Lang->PrintableLanguageName = (WCHAR *) malloc ((wcslen (PrintableLanguageName) + 1) * sizeof (WCHAR));\r
+    StrCpy (Lang->LanguageName, LanguageName);\r
+    Lang->PrintableLanguageName = (WCHAR *) malloc ((StrLen (PrintableLanguageName) + 1) * sizeof (WCHAR));\r
     if (Lang->PrintableLanguageName == NULL) {\r
       Error (NULL, 0, 0, NULL, "memory allocation error");\r
       return STATUS_ERROR;\r
     }\r
 \r
-    wcscpy (Lang->PrintableLanguageName, PrintableLanguageName);\r
+    StrCpy (Lang->PrintableLanguageName, PrintableLanguageName);\r
 \r
     if (mDBData.LanguageList == NULL) {\r
       mDBData.LanguageList = Lang;\r
@@ -1284,7 +1293,7 @@ StringDBFindStringIdentifierByName (
 \r
   Identifier = mDBData.StringIdentifier;\r
   while (Identifier != NULL) {\r
-    if (wcscmp (StringName, Identifier->StringName) == 0) {\r
+    if (StrCmp (StringName, Identifier->StringName) == 0) {\r
       return Identifier;\r
     }\r
 \r
@@ -1366,22 +1375,22 @@ StringDBFormatString (
       // when you have "define STR L"ABC"", then sizeof(ABC) is 8 because the null char is\r
       // counted. Make adjustments for this. We advance From below, so subtract 2 each time.\r
       //\r
-      if (wcsncmp (From, UNICODE_WIDE_STRING, sizeof (UNICODE_WIDE_STRING) / sizeof (WCHAR) - 1) == 0) {\r
+      if (StrnCmp (From, UNICODE_WIDE_STRING, sizeof (UNICODE_WIDE_STRING) / sizeof (WCHAR) - 1) == 0) {\r
         *To = WIDE_CHAR;\r
         From += sizeof (UNICODE_WIDE_STRING) / sizeof (WCHAR) - 2;\r
-      } else if (wcsncmp (From, UNICODE_NARROW_STRING, sizeof (UNICODE_NARROW_STRING) / sizeof (WCHAR) - 1) == 0) {\r
+      } else if (StrnCmp (From, UNICODE_NARROW_STRING, sizeof (UNICODE_NARROW_STRING) / sizeof (WCHAR) - 1) == 0) {\r
         //\r
         // Found: \narrow\r
         //\r
         *To = NARROW_CHAR;\r
         From += sizeof (UNICODE_NARROW_STRING) / sizeof (WCHAR) - 2;\r
-      } else if (wcsncmp (From, UNICODE_NBR_STRING, sizeof (UNICODE_NBR_STRING) / sizeof (WCHAR) - 1) == 0) {\r
+      } else if (StrnCmp (From, UNICODE_NBR_STRING, sizeof (UNICODE_NBR_STRING) / sizeof (WCHAR) - 1) == 0) {\r
         //\r
         // Found: \nbr\r
         //\r
         *To = NON_BREAKING_CHAR;\r
         From += sizeof (UNICODE_NBR_STRING) / sizeof (WCHAR) - 2;\r
-      } else if (wcsncmp (From, UNICODE_BR_STRING, sizeof (UNICODE_BR_STRING) / sizeof (WCHAR) - 1) == 0) {\r
+      } else if (StrnCmp (From, UNICODE_BR_STRING, sizeof (UNICODE_BR_STRING) / sizeof (WCHAR) - 1) == 0) {\r
         //\r
         // Found: \br -- pass through untouched\r
         //\r
@@ -1594,7 +1603,7 @@ StringDBWriteDatabase (
 {\r
   STRING_DB_HEADER  DbHeader;\r
   UINT32            Counter;\r
-  UINT32            StrLen;\r
+  UINT32            StrLength;\r
   LANGUAGE_LIST     *Lang;\r
   STRING_IDENTIFIER *StringIdentifier;\r
   STRING_LIST       *StrList;\r
@@ -1629,8 +1638,8 @@ StringDBWriteDatabase (
   DbHeader.NumStringIdenfiers = mDBData.NumStringIdentifiers;\r
   StringIdentifier            = mDBData.StringIdentifier;\r
   for (Counter = 0; Counter < mDBData.NumStringIdentifiers; Counter++) {\r
-    StrLen = wcslen (StringIdentifier->StringName) + 1;\r
-    DbHeader.StringIdentifiersSize += StrLen * sizeof (WCHAR) + sizeof (StringIdentifier->Flags);\r
+    StrLength = StrLen (StringIdentifier->StringName) + 1;\r
+    DbHeader.StringIdentifiersSize += StrLength * sizeof (WCHAR) + sizeof (StringIdentifier->Flags);\r
     StringIdentifier = StringIdentifier->Next;\r
   }\r
 \r
@@ -1688,7 +1697,7 @@ StringDBSetStringReferenced (
   //\r
   Status  = STATUS_SUCCESS;\r
   WName   = (WCHAR *) malloc ((strlen (StringIdentifierName) + 1) * sizeof (WCHAR));\r
-  swprintf (WName, L"%S", StringIdentifierName);\r
+  UnicodeSPrint (WName, (strlen (StringIdentifierName) + 1) * sizeof (WCHAR), L"%a", StringIdentifierName);\r
   Id = StringDBFindStringIdentifierByName (WName);\r
   if (Id != NULL) {\r
     Id->Flags |= STRING_FLAGS_REFERENCED;\r
@@ -1765,8 +1774,8 @@ StringDBDumpDatabase (
   // The default control character is '/'. Make it '#' by writing\r
   // "/=#" to the output file.\r
   //\r
-  swprintf (Line, L"/=#");\r
-  fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr);\r
+  UnicodeSPrint (Line, sizeof(Line), L"/=#");\r
+  fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr);\r
   fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);\r
   fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);\r
   //\r
@@ -1778,24 +1787,24 @@ StringDBDumpDatabase (
     // Write the "#define " string\r
     //\r
     if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) {\r
-      swprintf (\r
+      UnicodeSPrint (\r
         Line,\r
-        L"%s %-60.60s 0x%04X",\r
+        sizeof(Line), L"%s %-60.60s 0x%04X",\r
         DEFINE_STR,\r
         StringIdentifier->StringName,\r
         StringIdentifier->Index\r
         );\r
     } else {\r
-      swprintf (\r
+      UnicodeSPrint (\r
         Line,\r
-        L"%s %-60.60s 0x%04X  // NOT REFERENCED",\r
+        sizeof(Line), L"%s %-60.60s 0x%04X  // NOT REFERENCED",\r
         DEFINE_STR,\r
         StringIdentifier->StringName,\r
         StringIdentifier->Index\r
         );\r
     }\r
 \r
-    fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr);\r
+    fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr);\r
     fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);\r
   }\r
 \r
@@ -1807,8 +1816,8 @@ StringDBDumpDatabase (
   Scope = NULL;\r
   for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) {\r
     fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);\r
-    swprintf (Line, L"#langdef %s \"%s\"", Lang->LanguageName, Lang->PrintableLanguageName);\r
-    fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr);\r
+    UnicodeSPrint (Line, sizeof(Line), L"#langdef %s \"%s\"", Lang->LanguageName, Lang->PrintableLanguageName);\r
+    fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr);\r
     fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);\r
     fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);\r
     //\r
@@ -1819,29 +1828,29 @@ StringDBDumpDatabase (
       //\r
       // Print the internal flags for debug\r
       //\r
-      swprintf (Line, L"// flags=0x%02X", (UINT32) StrList->Flags);\r
-      fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr);\r
+      UnicodeSPrint (Line, sizeof(Line), L"// flags=0x%02X", (UINT32) StrList->Flags);\r
+      fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr);\r
       fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);\r
       //\r
       // Print the scope if changed\r
       //\r
-      if ((Scope == NULL) || (wcscmp (Scope, StrList->Scope) != 0)) {\r
-        swprintf (Line, L"#scope %s", StrList->Scope);\r
-        fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr);\r
+      if ((Scope == NULL) || (StrCmp (Scope, StrList->Scope) != 0)) {\r
+        UnicodeSPrint (Line, sizeof(Line), L"#scope %s", StrList->Scope);\r
+        fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr);\r
         fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);\r
         Scope = StrList->Scope;\r
       }\r
 \r
-      swprintf (\r
+      UnicodeSPrint (\r
         Line,\r
-        L"#string %-50.50s #language %s \"",\r
+        sizeof(Line), L"#string %-50.50s #language %s \"",\r
         StrList->StringName,\r
         Lang->LanguageName\r
         );\r
-      fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr);\r
+      fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr);\r
       fwrite (StrList->Str, StrList->Size - sizeof (WCHAR), 1, OutFptr);\r
-      swprintf (Line, L"\"");\r
-      fwrite (Line, wcslen (Line) * sizeof (WCHAR), 1, OutFptr);\r
+      UnicodeSPrint (Line, sizeof(Line), L"\"");\r
+      fwrite (Line, StrLen (Line) * sizeof (WCHAR), 1, OutFptr);\r
       fwrite (&CrLf, sizeof (CrLf), 1, OutFptr);\r
     }\r
   }\r
@@ -2175,7 +2184,7 @@ StringDBWriteGenericString (
     Flags         = STRING_FLAGS_UNDEFINED;\r
   } else {\r
     Flags = 0;\r
-    Size  = (UINT16) ((wcslen (Str) + 1) * sizeof (WCHAR));\r
+    Size  = (UINT16) ((StrLen (Str) + 1) * sizeof (WCHAR));\r
   }\r
 \r
   if (fwrite (&Size, sizeof (UINT16), 1, DBFptr) != 1) {\r
@@ -2220,7 +2229,7 @@ StringDBFindString (
   //\r
   if (IndirectionList != NULL) {\r
     for (IndListPtr = IndirectionList; IndListPtr != NULL; IndListPtr = IndListPtr->Next) {\r
-      if (wcscmp (StringName, IndListPtr->Str1) == 0) {\r
+      if (StrCmp (StringName, IndListPtr->Str1) == 0) {\r
         CurrString = StringDBFindString (LanguageName, StringName, IndListPtr->Str2, LanguagesOfInterest, NULL);\r
         if (CurrString != NULL) {\r
           return CurrString;\r
@@ -2232,18 +2241,18 @@ StringDBFindString (
   // First look for exact match language.stringname\r
   //\r
   for (Lang = mDBData.LanguageList; Lang != NULL; Lang = Lang->Next) {\r
-    if (wcscmp (LanguageName, Lang->LanguageName) == 0) {\r
+    if (StrCmp (LanguageName, Lang->LanguageName) == 0) {\r
       //\r
       // Found language match. Try to find string name match\r
       //\r
       for (CurrString = Lang->String; CurrString != NULL; CurrString = CurrString->Next) {\r
-        if (wcscmp (StringName, CurrString->StringName) == 0) {\r
+        if (StrCmp (StringName, CurrString->StringName) == 0) {\r
           //\r
           // Found a string name match. See if we're supposed to find\r
           // a scope match.\r
           //\r
           if (Scope != NULL) {\r
-            if (wcscmp (CurrString->Scope, Scope) == 0) {\r
+            if (StrCmp (CurrString->Scope, Scope) == 0) {\r
               return CurrString;\r
             }\r
           } else {\r
@@ -2263,19 +2272,19 @@ StringDBFindString (
     // If this is the language we're looking for, then process the\r
     // languages of interest list for it.\r
     //\r
-    if (wcsncmp (LanguageName, LanguagesOfInterest->Str, LANGUAGE_IDENTIFIER_NAME_LEN) == 0) {\r
+    if (StrnCmp (LanguageName, LanguagesOfInterest->Str, LANGUAGE_IDENTIFIER_NAME_LEN) == 0) {\r
       WCharPtr = LanguagesOfInterest->Str + LANGUAGE_IDENTIFIER_NAME_LEN;\r
       while (*WCharPtr) {\r
         //\r
         // Double-check the length, though it should have been checked on the\r
         // command line.\r
         //\r
-        if (wcslen (WCharPtr) < LANGUAGE_IDENTIFIER_NAME_LEN) {\r
+        if (StrLen (WCharPtr) < LANGUAGE_IDENTIFIER_NAME_LEN) {\r
           Error (NULL, 0, 0, "malformed alternate language list", "%S", LanguagesOfInterest->Str);\r
           return NULL;\r
         }\r
 \r
-        wcsncpy (TempLangName, WCharPtr, LANGUAGE_IDENTIFIER_NAME_LEN);\r
+        StrnCpy (TempLangName, WCharPtr, LANGUAGE_IDENTIFIER_NAME_LEN);\r
         TempLangName[LANGUAGE_IDENTIFIER_NAME_LEN]  = 0;\r
         CurrString = StringDBFindString (TempLangName, StringName, NULL, NULL, IndirectionList);\r
         if (CurrString != NULL) {\r
@@ -2401,13 +2410,13 @@ DuplicateString (
     return NULL;\r
   }\r
 \r
-  NewStr = MALLOC ((wcslen (Str) + 1) * sizeof (WCHAR));\r
+  NewStr = MALLOC ((StrLen (Str) + 1) * sizeof (WCHAR));\r
   if (NewStr == NULL) {\r
     Error (NULL, 0, 0, "memory allocation failure", NULL);\r
     return NULL;\r
   }\r
 \r
-  wcscpy (NewStr, Str);\r
+  StrCpy (NewStr, Str);\r
   return NewStr;\r
 }\r
 \r
@@ -2515,7 +2524,7 @@ StringDBCreateHiiExportPack (
     // entry for the printable language name as well.\r
     //\r
     StringPack.LanguageNameString = (STRING_OFFSET) (sizeof (EFI_HII_STRING_PACK) + (mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET)));\r
-    StringPack.PrintableLanguageName = (STRING_OFFSET) (StringPack.LanguageNameString + (wcslen (LangName) + 1) * sizeof (WCHAR));\r
+    StringPack.PrintableLanguageName = (STRING_OFFSET) (StringPack.LanguageNameString + (StrLen (LangName) + 1) * sizeof (WCHAR));\r
     //\r
     // Add up the size of all strings so we can fill in our header.\r
     //\r
@@ -2526,7 +2535,7 @@ StringDBCreateHiiExportPack (
       // requested it. We set LangName to point to the proper language name string above.\r
       //\r
       if (StringIndex == STRING_ID_LANGUAGE_NAME) {\r
-        Len += (wcslen (LangName) + 1) * sizeof (WCHAR);\r
+        Len += (StrLen (LangName) + 1) * sizeof (WCHAR);\r
       } else {\r
         //\r
         // Find a string with this language.stringname\r
@@ -2611,7 +2620,7 @@ StringDBCreateHiiExportPack (
       // requested it. We set LangName to point to the proper language name string above.\r
       //\r
       if (StringIndex == STRING_ID_LANGUAGE_NAME) {\r
-        Offset += (wcslen (LangName) + 1) * sizeof (WCHAR);\r
+        Offset += (StrLen (LangName) + 1) * sizeof (WCHAR);\r
         CurrString = StringDBFindString (\r
                       Lang->LanguageName,\r
                       StringIdentifier->StringName,\r
index 0bee870..96658e8 100644 (file)
@@ -86,6 +86,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
         libtool="${haveLibtool}"\r
         debug="false">\r
 \r
+      <compilerarg value="-fshort-wchar" if="gcc"/>\r
+\r
       <fileset dir="${basedir}/${ToolName}" \r
         includes="${FileSet}" \r
         defaultexcludes="TRUE" \r
@@ -95,8 +97,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
       <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>\r
       <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>\r
       <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>\r
+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Library"/>\r
       <includepath path="${PACKAGE_DIR}/Common"/>\r
-      <libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress"/>\r
+      <libset dir="${LIB_DIR}" libs="CommonTools CustomizedCompress String"/>\r
     </cc>\r
   </target>\r
 \r
diff --git a/Tools/Source/TianoTools/String/PrintLib.c b/Tools/Source/TianoTools/String/PrintLib.c
new file mode 100644 (file)
index 0000000..868a73e
--- /dev/null
@@ -0,0 +1,667 @@
+/** @file\r
+  Print Library.\r
+\r
+  Copyright (c) 2006, Intel Corporation<BR>\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:  PrintLib.c\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include <UefiBaseTypes.h>\r
+#include <PrintLib.h>\r
+#include <CommonLib.h>\r
+#include "PrintLibInternal.h"\r
+\r
+typedef struct {\r
+  RETURN_STATUS  Status;\r
+  CHAR8          *String;\r
+} STATUS_LOOKUP_TABLE_ENTRY;\r
+\r
+static CONST STATUS_LOOKUP_TABLE_ENTRY  StatusString[] = {\r
+  { RETURN_SUCCESS,               "Success" },\r
+  { RETURN_LOAD_ERROR,            "Load Error" },\r
+  { RETURN_INVALID_PARAMETER,     "Invalid Parameter" },\r
+  { RETURN_UNSUPPORTED,           "Unsupported" },\r
+  { RETURN_BAD_BUFFER_SIZE,       "Bad Buffer Size" },\r
+  { RETURN_BUFFER_TOO_SMALL,      "Buffer Too Small" },\r
+  { RETURN_NOT_READY,             "Not Ready" },\r
+  { RETURN_DEVICE_ERROR,          "Device Error" },\r
+  { RETURN_WRITE_PROTECTED,       "Write Protected" },\r
+  { RETURN_OUT_OF_RESOURCES,      "Out of Resources" },\r
+  { RETURN_VOLUME_CORRUPTED,      "Volume Corrupt" },\r
+  { RETURN_VOLUME_FULL,           "Volume Full" },\r
+  { RETURN_NO_MEDIA,              "No Media" },\r
+  { RETURN_MEDIA_CHANGED,         "Media changed" },\r
+  { RETURN_NOT_FOUND,             "Not Found" },\r
+  { RETURN_ACCESS_DENIED,         "Access Denied" },\r
+  { RETURN_NO_RESPONSE,           "No Response" },\r
+  { RETURN_NO_MAPPING,            "No mapping" },\r
+  { RETURN_TIMEOUT,               "Time out" },\r
+  { RETURN_NOT_STARTED,           "Not started" },\r
+  { RETURN_ALREADY_STARTED,       "Already started" },\r
+  { RETURN_ABORTED,               "Aborted" },\r
+  { RETURN_ICMP_ERROR,            "ICMP Error" },\r
+  { RETURN_TFTP_ERROR,            "TFTP Error" },\r
+  { RETURN_PROTOCOL_ERROR,        "Protocol Error" },\r
+  { RETURN_WARN_UNKNOWN_GLYPH,    "Warning Unknown Glyph" },\r
+  { RETURN_WARN_DELETE_FAILURE,   "Warning Delete Failure" },\r
+  { RETURN_WARN_WRITE_FAILURE,    "Warning Write Failure" },\r
+  { RETURN_WARN_BUFFER_TOO_SMALL, "Warning Buffer Too Small" },\r
+  { 0,                              NULL                     }\r
+};\r
+\r
+\r
+/**\r
+  VSPrint function to process format and place the results in Buffer. Since a \r
+  VA_LIST is used this rountine allows the nesting of Vararg routines. Thus \r
+  this is the main print working routine\r
+\r
+  @param  StartOfBuffer Unicode buffer to print the results of the parsing of Format into.\r
+  \r
+  @param  BufferSize Maximum number of characters to put into buffer. Zero means\r
+  no limit.\r
+  \r
+  @param  Flags Intial flags value.  Can only have FORMAT_UNICODE and OUTPUT_UNICODE set\r
+  \r
+  @param  FormatString Unicode format string see file header for more details.\r
+  \r
+  @param  Marker Vararg list consumed by processing Format.\r
+\r
+  @return Number of characters printed.\r
+\r
+**/\r
+UINTN\r
+BasePrintLibVSPrint (\r
+  OUT CHAR8        *Buffer,\r
+  IN  UINTN        BufferSize,\r
+  IN  UINTN        Flags,\r
+  IN  CONST CHAR8  *Format,\r
+  IN  VA_LIST      Marker\r
+  )\r
+{\r
+  CHAR8           *OriginalBuffer;\r
+  CHAR8           ValueBuffer[MAXIMUM_VALUE_CHARACTERS];\r
+  UINTN           BytesPerOutputCharacter;\r
+  UINTN           BytesPerFormatCharacter;\r
+  UINTN           FormatMask;\r
+  UINTN           FormatCharacter;\r
+  UINTN           Width;\r
+  UINTN           Precision;\r
+  INT64           Value;\r
+  CHAR8           *ArgumentString;\r
+  UINTN           Character;\r
+  GUID            *TmpGuid;\r
+  TIME            *TmpTime;\r
+  UINTN           Count;\r
+  UINTN           ArgumentMask;\r
+  INTN            BytesPerArgumentCharacter;\r
+  UINTN           ArgumentCharacter;\r
+  BOOLEAN         Done;\r
+  UINTN           Index;\r
+  CHAR8           Prefix;\r
+  BOOLEAN         ZeroPad;\r
+  BOOLEAN         Comma;\r
+  UINTN           Digits;\r
+  UINTN           Radix;\r
+  RETURN_STATUS   Status;\r
+\r
+  OriginalBuffer = Buffer;\r
+\r
+  if ((Flags & OUTPUT_UNICODE) != 0) {\r
+    BytesPerOutputCharacter = 2;\r
+  } else {\r
+    BytesPerOutputCharacter = 1;\r
+  }\r
+  if ((Flags & FORMAT_UNICODE) != 0) {\r
+    BytesPerFormatCharacter = 2;\r
+    FormatMask = 0xffff;\r
+  } else {\r
+    BytesPerFormatCharacter = 1;\r
+    FormatMask = 0xff;\r
+  }\r
+\r
+  //\r
+  // Reserve space for the Null terminator.\r
+  // If BufferSize is 0, this will set BufferSize to the max unsigned value\r
+  //\r
+  BufferSize--;\r
+\r
+  //\r
+  // Get the first character from the format string\r
+  //\r
+  FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask;\r
+\r
+  //\r
+  // Loop until the end of the format string is reached or the output buffer is full\r
+  //\r
+  while (FormatCharacter != 0 && BufferSize > 0) {\r
+    //\r
+    // Clear all the flag bits except those that may have been passed in\r
+    //\r
+    Flags &= (OUTPUT_UNICODE | FORMAT_UNICODE);\r
+\r
+    //\r
+    // Set the default width to zero, and the default precision to 1\r
+    //\r
+    Width     = 0;\r
+    Precision = 1;\r
+    Prefix    = 0;\r
+    Comma     = FALSE;\r
+    ZeroPad   = FALSE;\r
+    Count     = 0;\r
+    Digits    = 0;\r
+\r
+    switch (FormatCharacter) {\r
+    case '%':\r
+      //\r
+      // Parse Flags and Width\r
+      //\r
+      for (Done = FALSE; !Done; ) {\r
+        Format += BytesPerFormatCharacter;\r
+        FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask;\r
+        switch (FormatCharacter) {\r
+        case '.': \r
+          Flags |= PRECISION; \r
+          break;\r
+        case '-': \r
+          Flags |= LEFT_JUSTIFY; \r
+          break;\r
+        case '+': \r
+          Flags |= PREFIX_SIGN;  \r
+          break;\r
+        case ' ': \r
+          Flags |= PREFIX_BLANK; \r
+          break;\r
+        case ',': \r
+          Flags |= COMMA_TYPE; \r
+          break;\r
+        case 'L':\r
+        case 'l': \r
+          Flags |= LONG_TYPE;    \r
+          break;\r
+        case '*':\r
+          if ((Flags & PRECISION) == 0) {\r
+            Flags |= PAD_TO_WIDTH;\r
+            Width = VA_ARG (Marker, UINTN);\r
+          } else {\r
+            Precision = VA_ARG (Marker, UINTN);\r
+          }\r
+          break;\r
+        case '0':\r
+          if ((Flags & PRECISION) == 0) {\r
+            Flags |= PREFIX_ZERO;\r
+          }\r
+        case '1':\r
+        case '2':\r
+        case '3':\r
+        case '4':\r
+        case '5':\r
+        case '6':\r
+        case '7':\r
+        case '8':\r
+        case '9':\r
+          for (Count = 0; ((FormatCharacter >= '0') &&  (FormatCharacter <= '9')); ){\r
+            Count = (Count * 10) + FormatCharacter - '0';\r
+            Format += BytesPerFormatCharacter;\r
+            FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask;\r
+          }\r
+          Format -= BytesPerFormatCharacter;\r
+          if ((Flags & PRECISION) == 0) {\r
+            Flags |= PAD_TO_WIDTH;\r
+            Width = Count;\r
+          } else {\r
+            Precision = Count;\r
+          }\r
+          break;\r
+        default:\r
+          Done = TRUE;\r
+          break;\r
+        }\r
+      } \r
+\r
+      //\r
+      // Limit the maximum field width to the remaining characters in the output buffer\r
+      //\r
+      if (Width > BufferSize) {\r
+        Width = BufferSize;\r
+      }\r
+\r
+      //\r
+      // Handle each argument type\r
+      //\r
+      switch (FormatCharacter) {\r
+      case 'X':\r
+        Flags |= PREFIX_ZERO;\r
+        //\r
+        // break skiped on purpose\r
+        //\r
+      case 'x':\r
+        Flags |= RADIX_HEX;\r
+        //\r
+        // break skiped on purpose\r
+        //\r
+      case 'd':\r
+        if ((Flags & LONG_TYPE) == 0) {\r
+          Value = (VA_ARG (Marker, INTN));\r
+        } else {\r
+          Value = VA_ARG (Marker, INT64);\r
+        }\r
+        if ((Flags & PREFIX_BLANK) != 0) {\r
+          Prefix = ' ';\r
+        }\r
+        if ((Flags & PREFIX_SIGN) != 0) {\r
+          Prefix = '+';\r
+        }\r
+        if ((Flags & COMMA_TYPE) != 0) {\r
+          Comma = TRUE;\r
+        }\r
+        if ((Flags & RADIX_HEX) == 0) {\r
+          Radix = 10;\r
+          if (Comma) {\r
+            Flags &= (~PREFIX_ZERO);\r
+            Precision = 1;\r
+          }\r
+          if (Value < 0) {\r
+            Flags |= PREFIX_SIGN;\r
+            Prefix = '-';\r
+            Value = -Value;\r
+          }\r
+        } else {\r
+          Radix = 16;\r
+          Comma = FALSE;\r
+          if ((Flags & LONG_TYPE) == 0 && Value < 0) {\r
+            Value = (UINTN)Value;\r
+          }\r
+        }\r
+        //\r
+        // Convert Value to a reversed string\r
+        //\r
+        Count = BasePrintLibValueToString (ValueBuffer, Value, Radix);\r
+        if (Value == 0 && Precision == 0) {\r
+          Count = 0;\r
+        }\r
+        ArgumentString = (CHAR8 *)ValueBuffer + Count;\r
+        Digits = 3 - (Count % 3);\r
+        if (Comma && Count != 0) {\r
+          Count += ((Count - 1) / 3);\r
+        }\r
+        if (Prefix != 0) {\r
+          Count++;\r
+        }\r
+        Flags |= ARGUMENT_REVERSED;\r
+        ZeroPad = TRUE;\r
+        if ((Flags & PREFIX_ZERO) != 0) {\r
+          if ((Flags & PAD_TO_WIDTH) != 0) {\r
+            if ((Flags & PRECISION) == 0) {\r
+              Precision = Width;\r
+            }\r
+          }\r
+        }\r
+        break;\r
+\r
+      case 's':\r
+      case 'S':\r
+        Flags |= ARGUMENT_UNICODE;\r
+        //\r
+        // break skipped on purpose\r
+        //\r
+      case 'a':\r
+        ArgumentString = (CHAR8 *)VA_ARG (Marker, CHAR8 *);\r
+        if (ArgumentString == NULL) {\r
+          Flags &= (~ARGUMENT_UNICODE);\r
+          ArgumentString = "<null string>";\r
+        }\r
+        break;\r
+\r
+      case 'c':\r
+        Character = VA_ARG (Marker, UINTN) & 0xffff;\r
+        ArgumentString = (CHAR8 *)&Character;\r
+        Flags |= ARGUMENT_UNICODE;\r
+        break;\r
+\r
+      case 'g':\r
+        TmpGuid = VA_ARG (Marker, GUID *);\r
+        if (TmpGuid == NULL) {\r
+          ArgumentString = "<null guid>";\r
+        } else {\r
+          BasePrintLibSPrint (\r
+            ValueBuffer,\r
+            0, \r
+            0,\r
+            "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",\r
+            TmpGuid->Data1,\r
+            TmpGuid->Data2,\r
+            TmpGuid->Data3,\r
+            TmpGuid->Data4[0],\r
+            TmpGuid->Data4[1],\r
+            TmpGuid->Data4[2],\r
+            TmpGuid->Data4[3],\r
+            TmpGuid->Data4[4],\r
+            TmpGuid->Data4[5],\r
+            TmpGuid->Data4[6],\r
+            TmpGuid->Data4[7]\r
+            );\r
+          ArgumentString = ValueBuffer;\r
+        }\r
+        break;\r
+\r
+      case 't':\r
+        TmpTime = VA_ARG (Marker, TIME *); \r
+        if (TmpTime == NULL) {\r
+          ArgumentString = "<null time>";\r
+        } else {\r
+          BasePrintLibSPrint (\r
+            ValueBuffer,\r
+            0,\r
+            0,\r
+            "%02d/%02d/%04d  %02d:%02d",\r
+            TmpTime->Month,\r
+            TmpTime->Day,\r
+            TmpTime->Year,\r
+            TmpTime->Hour,\r
+            TmpTime->Minute\r
+            );\r
+          ArgumentString = ValueBuffer;\r
+        }\r
+        break;\r
+\r
+      case 'r':\r
+        Status = VA_ARG (Marker, RETURN_STATUS);\r
+        ArgumentString = ValueBuffer;\r
+        for (Index = 0; StatusString[Index].String != NULL; Index++) {\r
+          if (Status == StatusString[Index].Status) {\r
+            ArgumentString = StatusString[Index].String;\r
+          }\r
+        }\r
+        if (ArgumentString == ValueBuffer) {\r
+          BasePrintLibSPrint ((CHAR8 *) ValueBuffer, 0, 0, "%08X", Status);\r
+        }\r
+        break;\r
+\r
+      case '%':\r
+      default:\r
+        //\r
+        // if the type is '%' or unknown, then print it to the screen\r
+        //\r
+        ArgumentString = (CHAR8 *)&FormatCharacter;\r
+        Flags |= ARGUMENT_UNICODE;\r
+        break;\r
+      }\r
+      break;\r
+    case '\n':\r
+      ArgumentString = "\r\n";\r
+      break;\r
+    default:\r
+      ArgumentString = (CHAR8 *)&FormatCharacter;\r
+      Flags |= ARGUMENT_UNICODE;\r
+      break;\r
+    }\r
+\r
+    //\r
+    // Retrieve the ArgumentString attriubutes\r
+    //\r
+    if ((Flags & ARGUMENT_UNICODE) != 0) {\r
+      ArgumentMask = 0xffff;\r
+      BytesPerArgumentCharacter = 2;\r
+    } else {\r
+      ArgumentMask = 0xff;\r
+      BytesPerArgumentCharacter = 1;\r
+    }\r
+    if ((Flags & ARGUMENT_REVERSED) != 0) {\r
+      BytesPerArgumentCharacter = -BytesPerArgumentCharacter;\r
+    } else {\r
+      //\r
+      // Compute the number of characters in ArgumentString and store it in Count\r
+      // ArgumentString is either null-terminated, or it contains Precision characters\r
+      //\r
+      for (Count = 0; Count < Precision || ((Flags & PRECISION) == 0); Count++) {\r
+        ArgumentCharacter = ((ArgumentString[Count * BytesPerArgumentCharacter] & 0xff) | ((ArgumentString[Count * BytesPerArgumentCharacter + 1]) << 8)) & ArgumentMask;\r
+        if (ArgumentCharacter == 0) {\r
+          break;\r
+        }\r
+      }\r
+    }\r
+\r
+    //\r
+    // Limit the length of the string to append to the remaining characters in the output buffer\r
+    //\r
+    if (Count > BufferSize) {\r
+      Count = BufferSize;\r
+    }\r
+    if (Precision < Count) {\r
+      Precision = Count;\r
+    }\r
+\r
+    //\r
+    // Pad before the string\r
+    //\r
+    if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH)) {\r
+      Buffer = BasePrintLibFillBuffer (Buffer, Width - Precision, ' ', BytesPerOutputCharacter);\r
+    }\r
+\r
+    if (ZeroPad) {\r
+      if (Prefix != 0) {\r
+        Buffer = BasePrintLibFillBuffer (Buffer, 1, Prefix, BytesPerOutputCharacter);\r
+      }\r
+      Buffer = BasePrintLibFillBuffer (Buffer, Precision - Count, '0', BytesPerOutputCharacter);\r
+    } else {\r
+      Buffer = BasePrintLibFillBuffer (Buffer, Precision - Count, ' ', BytesPerOutputCharacter);\r
+      if (Prefix != 0) {\r
+        Buffer = BasePrintLibFillBuffer (Buffer, 1, Prefix, BytesPerOutputCharacter);\r
+      }\r
+    }\r
+\r
+    //\r
+    // Output the Prefix character if it is present\r
+    //\r
+    Index = 0;\r
+    if (Prefix) {\r
+      Index++;\r
+    }\r
+\r
+    //\r
+    // Copy the string into the output buffer performing the required type conversions\r
+    //\r
+    while (Index < Count) {\r
+      ArgumentCharacter = ((*ArgumentString & 0xff) | (*(ArgumentString + 1) << 8)) & ArgumentMask;\r
+\r
+      Buffer = BasePrintLibFillBuffer (Buffer, 1, ArgumentCharacter, BytesPerOutputCharacter);\r
+      ArgumentString    += BytesPerArgumentCharacter;\r
+      Index++;\r
+      if (Comma) {\r
+        Digits++;\r
+        if (Digits == 3) {\r
+          Digits = 0;\r
+          Index++;\r
+          if (Index < Count) {\r
+            Buffer = BasePrintLibFillBuffer (Buffer, 1, ',', BytesPerOutputCharacter);\r
+          }\r
+        }\r
+      }\r
+    }\r
+\r
+    //\r
+    // Pad after the string\r
+    //\r
+    if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH | LEFT_JUSTIFY)) {\r
+      Buffer = BasePrintLibFillBuffer (Buffer, Width - Precision, ' ', BytesPerOutputCharacter);\r
+    }\r
+\r
+    //\r
+    // Reduce the number of characters\r
+    //\r
+    BufferSize -= Count;\r
+\r
+    //\r
+    // Get the next character from the format string\r
+    //\r
+    Format += BytesPerFormatCharacter;\r
+\r
+    //\r
+    // Get the next character from the format string\r
+    //\r
+    FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask;\r
+  }\r
+\r
+  //\r
+  // Null terminate the Unicode or ASCII string\r
+  //\r
+  Buffer = BasePrintLibFillBuffer (Buffer, 1, 0, BytesPerOutputCharacter);\r
+   \r
+  return ((Buffer - OriginalBuffer) / BytesPerOutputCharacter);\r
+}\r
+\r
+UINTN\r
+BasePrintLibSPrint (\r
+  OUT CHAR8        *StartOfBuffer,\r
+  IN  UINTN        BufferSize,\r
+  IN  UINTN        Flags,\r
+  IN  CONST CHAR8  *FormatString,\r
+  ...\r
+  )\r
+{\r
+  VA_LIST  Marker;\r
+\r
+  VA_START (Marker, FormatString);\r
+  return BasePrintLibVSPrint (StartOfBuffer, BufferSize, Flags, FormatString, Marker);\r
+}\r
+\r
+UINTN\r
+EFIAPI\r
+UnicodeVSPrint (\r
+  OUT CHAR16        *StartOfBuffer,\r
+  IN  UINTN         BufferSize,\r
+  IN  CONST CHAR16  *FormatString,\r
+  IN  VA_LIST       Marker\r
+  )\r
+{\r
+  return BasePrintLibVSPrint ((CHAR8 *)StartOfBuffer, BufferSize >> 1, FORMAT_UNICODE | OUTPUT_UNICODE, (CHAR8 *)FormatString, Marker);\r
+}\r
+\r
+UINTN\r
+EFIAPI\r
+UnicodeSPrint (\r
+  OUT CHAR16        *StartOfBuffer,\r
+  IN  UINTN         BufferSize,\r
+  IN  CONST CHAR16  *FormatString,\r
+  ...\r
+  )\r
+{\r
+  VA_LIST Marker;\r
+\r
+  VA_START (Marker, FormatString);\r
+  return UnicodeVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);\r
+}\r
+\r
+UINTN\r
+EFIAPI\r
+UnicodeVSPrintAsciiFormat (\r
+  OUT CHAR16       *StartOfBuffer,\r
+  IN  UINTN        BufferSize,\r
+  IN  CONST CHAR8  *FormatString,\r
+  IN  VA_LIST      Marker\r
+  )\r
+{\r
+  return BasePrintLibVSPrint ((CHAR8 *)StartOfBuffer, BufferSize >> 1, OUTPUT_UNICODE,FormatString, Marker);\r
+}\r
+\r
+UINTN\r
+EFIAPI\r
+UnicodeSPrintAsciiFormat (\r
+  OUT CHAR16       *StartOfBuffer,\r
+  IN  UINTN        BufferSize,\r
+  IN  CONST CHAR8  *FormatString,\r
+  ...\r
+  )\r
+{\r
+  VA_LIST Marker;\r
+\r
+  VA_START (Marker, FormatString);\r
+  return UnicodeVSPrintAsciiFormat (StartOfBuffer, BufferSize >> 1, FormatString, Marker);\r
+}\r
+\r
+UINTN\r
+EFIAPI\r
+AsciiVSPrint (\r
+  OUT CHAR8         *StartOfBuffer,\r
+  IN  UINTN         BufferSize,\r
+  IN  CONST CHAR8   *FormatString,\r
+  IN  VA_LIST       Marker\r
+  )\r
+{\r
+  return BasePrintLibVSPrint (StartOfBuffer, BufferSize, 0, FormatString, Marker);\r
+}\r
+\r
+UINTN\r
+EFIAPI\r
+AsciiSPrint (\r
+  OUT CHAR8        *StartOfBuffer,\r
+  IN  UINTN        BufferSize,\r
+  IN  CONST CHAR8  *FormatString,\r
+  ...\r
+  )\r
+{\r
+  VA_LIST Marker;\r
+\r
+  VA_START (Marker, FormatString);\r
+  return AsciiVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);\r
+}\r
+\r
+UINTN\r
+EFIAPI\r
+AsciiVSPrintUnicodeFormat (\r
+  OUT CHAR8         *StartOfBuffer,\r
+  IN  UINTN         BufferSize,\r
+  IN  CONST CHAR16  *FormatString,\r
+  IN  VA_LIST       Marker\r
+  )\r
+{\r
+  return BasePrintLibVSPrint (StartOfBuffer, BufferSize, FORMAT_UNICODE, (CHAR8 *)FormatString, Marker);\r
+}\r
+\r
+UINTN\r
+EFIAPI\r
+AsciiSPrintUnicodeFormat (\r
+  OUT CHAR8         *StartOfBuffer,\r
+  IN  UINTN         BufferSize,\r
+  IN  CONST CHAR16  *FormatString,\r
+  ...\r
+  )\r
+{\r
+  VA_LIST Marker;\r
+\r
+  VA_START (Marker, FormatString);\r
+  return AsciiVSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker);\r
+}\r
+\r
+UINTN\r
+EFIAPI\r
+UnicodeValueToString (\r
+  IN OUT CHAR16  *Buffer,\r
+  IN UINTN       Flags,\r
+  IN INT64       Value,\r
+  IN UINTN       Width\r
+  )\r
+{\r
+  return BasePrintLibConvertValueToString ((CHAR8 *)Buffer, Flags, Value, Width, 2);\r
+}\r
+\r
+UINTN\r
+EFIAPI\r
+AsciiValueToString (\r
+  IN OUT CHAR8  *Buffer,\r
+  IN UINTN      Flags,\r
+  IN INT64      Value,\r
+  IN UINTN      Width\r
+  )\r
+{\r
+  return BasePrintLibConvertValueToString ((CHAR8 *)Buffer, Flags, Value, Width, 1);\r
+}\r
diff --git a/Tools/Source/TianoTools/String/PrintLibInternal.c b/Tools/Source/TianoTools/String/PrintLibInternal.c
new file mode 100644 (file)
index 0000000..a475815
--- /dev/null
@@ -0,0 +1,137 @@
+/** @file\r
+  Print Library worker functions.\r
+\r
+  Copyright (c) 2006, Intel Corporation<BR>\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:  PrintLibInternal.c\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include <UefiBaseTypes.h>\r
+#include <PrintLib.h>\r
+#include <BaseLib.h>\r
+#include <CommonLib.h>\r
+#include "PrintLibInternal.h"\r
+\r
+static CONST CHAR8 mHexStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};\r
+\r
+CHAR8 *\r
+BasePrintLibFillBuffer (\r
+  CHAR8   *Buffer,\r
+  INTN    Length,\r
+  UINTN   Character,\r
+  INTN    Increment\r
+  )\r
+{\r
+  INTN  Index;\r
+\r
+  for (Index = 0; Index < Length; Index++) {\r
+    *Buffer       =  (CHAR8) Character;\r
+    *(Buffer + 1) =  (CHAR8) (Character >> 8);\r
+    Buffer        += Increment;\r
+  }\r
+  return Buffer;\r
+}\r
+\r
+/**\r
+  Print worker function that prints a Value as a decimal number in Buffer.\r
+\r
+  @param  Buffer Location to place the Unicode or ASCII string of Value.\r
+  \r
+  @param  Value Value to convert to a Decimal or Hexidecimal string in Buffer.\r
+  \r
+  @param  Flags Flags to use in printing string, see file header for details.\r
+  \r
+  @param  Precision Minimum number of digits to return in the ASCII string\r
+\r
+  @return Number of characters printed.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+BasePrintLibValueToString (\r
+  IN OUT CHAR8  *Buffer,\r
+  IN INT64      Value,\r
+  IN UINTN      Radix\r
+  )\r
+{\r
+  UINTN   Digits;\r
+  UINT32  Remainder;\r
+\r
+  //\r
+  // Loop to convert one digit at a time in reverse order\r
+  //\r
+  *(Buffer++) = 0;\r
+  Digits = 0;\r
+  do {\r
+    // Value = (INT64)DivU64x32Remainder ((UINT64)Value, (UINT32)Radix, &Remainder);\r
+    Remainder = (UINT64)Value % (UINT32)Radix;\r
+    Value = (UINT64)Value / (UINT32)Radix;\r
+    *(Buffer++) = mHexStr[Remainder];\r
+    Digits++;\r
+  } while (Value != 0);\r
+  return Digits;\r
+}\r
+\r
+UINTN\r
+BasePrintLibConvertValueToString (\r
+  IN OUT CHAR8   *Buffer,\r
+  IN UINTN       Flags,\r
+  IN INT64       Value,\r
+  IN UINTN       Width,\r
+  IN UINTN       Increment\r
+  )\r
+{\r
+  CHAR8  *OriginalBuffer;\r
+  CHAR8  ValueBuffer[MAXIMUM_VALUE_CHARACTERS];\r
+  UINTN  Count;\r
+  UINTN  Digits;\r
+  UINTN  Index;\r
+\r
+  OriginalBuffer = Buffer;\r
+\r
+  if (Width == 0 || (Flags & COMMA_TYPE) != 0) {\r
+    Flags &= (~PREFIX_ZERO);\r
+  }\r
+\r
+  if (Width == 0 || Width > (MAXIMUM_VALUE_CHARACTERS - 1)) {\r
+    Width = MAXIMUM_VALUE_CHARACTERS - 1;\r
+  }\r
+\r
+  if (Value < 0) {\r
+    Value = -Value;\r
+    Buffer = BasePrintLibFillBuffer (Buffer, 1, '-', Increment);\r
+  }\r
+\r
+  Count = BasePrintLibValueToString (ValueBuffer, Value, 10);\r
+\r
+  if ((Flags & PREFIX_ZERO) != 0) {\r
+    Buffer = BasePrintLibFillBuffer (Buffer, Width - Count, '0', Increment);\r
+  }\r
+\r
+  Digits = 3 - (Count % 3);\r
+  for (Index = 0; Index < Count; Index++) {\r
+    Buffer = BasePrintLibFillBuffer (Buffer, 1, ValueBuffer[Count - Index], Increment);\r
+    if ((Flags & COMMA_TYPE) != 0) {\r
+      Digits++;\r
+      if (Digits == 3) {\r
+        Digits = 0;\r
+        if ((Index + 1) < Count) {\r
+          Buffer = BasePrintLibFillBuffer (Buffer, 1, ',', Increment);\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  Buffer = BasePrintLibFillBuffer (Buffer, 1, 0, Increment);\r
+\r
+  return ((Buffer - OriginalBuffer) / Increment);\r
+}\r
diff --git a/Tools/Source/TianoTools/String/PrintLibInternal.h b/Tools/Source/TianoTools/String/PrintLibInternal.h
new file mode 100644 (file)
index 0000000..c7fecfd
--- /dev/null
@@ -0,0 +1,95 @@
+/** @file\r
+  Print Library.\r
+\r
+  Copyright (c) 2006, 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:  PrintLibInternal.h\r
+\r
+**/\r
+\r
+\r
+\r
+//\r
+// Print primitives\r
+//\r
+//#define LEFT_JUSTIFY      0x01\r
+#define PREFIX_SIGN       0x02\r
+#define PREFIX_BLANK      0x04\r
+//#define COMMA_TYPE        0x08\r
+#define LONG_TYPE         0x10\r
+//#define PREFIX_ZERO       0x20\r
+#define OUTPUT_UNICODE    0x40\r
+#define RADIX_HEX         0x80\r
+#define FORMAT_UNICODE    0x100\r
+#define PAD_TO_WIDTH      0x200\r
+#define ARGUMENT_UNICODE  0x400\r
+#define PRECISION         0x800\r
+#define ARGUMENT_REVERSED 0x1000\r
+\r
+///\r
+/// Define the maximum number of characters that are required to encode\r
+/// a decimal, hexidecimal, GUID, or TIME value with a Nll terminator.\r
+///   Maximum Length Decimal String     = 28    "-9,223,372,036,854,775,808"\r
+///   Maximum Length Hexidecimal String = 17    "FFFFFFFFFFFFFFFF"\r
+///   Maximum Length GUID               = 37    "00000000-0000-0000-0000-000000000000"\r
+///   Maximum Length TIME               = 18    "12/12/2006  12:12"\r
+///\r
+#define MAXIMUM_VALUE_CHARACTERS  38\r
+\r
+//\r
+//\r
+//\r
+typedef struct {\r
+  UINT16  Year;\r
+  UINT8   Month;\r
+  UINT8   Day;\r
+  UINT8   Hour;\r
+  UINT8   Minute;\r
+  UINT8   Second;\r
+  UINT8   Pad1;\r
+  UINT32  Nanosecond;\r
+  INT16   TimeZone;\r
+  UINT8   Daylight;\r
+  UINT8   Pad2;\r
+} TIME;\r
+\r
+UINTN\r
+BasePrintLibSPrint (\r
+  OUT CHAR8        *Buffer,\r
+  IN  UINTN        BufferSize,\r
+  IN  UINTN        Flags,\r
+  IN  CONST CHAR8  *FormatString,\r
+  ...\r
+  );\r
+\r
+CHAR8 *\r
+BasePrintLibFillBuffer (\r
+  CHAR8   *Buffer,\r
+  INTN    Length,\r
+  UINTN   Character,\r
+  INTN    Increment\r
+  );\r
+\r
+UINTN\r
+EFIAPI\r
+BasePrintLibValueToString (\r
+  IN OUT CHAR8  *Buffer, \r
+  IN INT64      Value, \r
+  IN UINTN      Radix\r
+  );\r
+\r
+UINTN\r
+BasePrintLibConvertValueToString (\r
+  IN OUT CHAR8   *Buffer,\r
+  IN UINTN       Flags,\r
+  IN INT64       Value,\r
+  IN UINTN       Width,\r
+  IN UINTN       Increment\r
+  );\r
diff --git a/Tools/Source/TianoTools/String/String.c b/Tools/Source/TianoTools/String/String.c
new file mode 100644 (file)
index 0000000..1005180
--- /dev/null
@@ -0,0 +1,809 @@
+/** @file\r
+  Unicode string primatives.\r
+\r
+  Copyright (c) 2006, Intel Corporation<BR>\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:  String.c\r
+\r
+**/\r
+\r
+#include <assert.h>\r
+#include <Base.h>\r
+#include <UefiBaseTypes.h>\r
+#include <BaseLib.h>\r
+#include <PcdLib.h>\r
+#include <CommonLib.h>\r
+#define _gPcd_FixedAtBuild_PcdMaximumUnicodeStringLength   0\r
+#define _gPcd_FixedAtBuild_PcdMaximumAsciiStringLength   0\r
+\r
+/**\r
+  Copies one Null-terminated Unicode string to another Null-terminated Unicode\r
+  string and returns the new Unicode string.\r
+\r
+  This function copies the contents of the Unicode string Source to the Unicode\r
+  string Destination, and returns Destination. If Source and Destination\r
+  overlap, then the results are undefined.\r
+\r
+  If Destination is NULL, then ASSERT().\r
+  If Source is NULL, then ASSERT().\r
+  If Source and Destination overlap, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and Source contains more than\r
+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
+\r
+  @param  Destination Pointer to a Null-terminated Unicode string.\r
+  @param  Source      Pointer to a Null-terminated Unicode string.\r
+\r
+  @return Destiantion\r
+\r
+**/\r
+CHAR16 *\r
+EFIAPI\r
+StrCpy (\r
+  OUT     CHAR16                    *Destination,\r
+  IN      CONST CHAR16              *Source\r
+  )\r
+{\r
+  CHAR16                            *ReturnValue;\r
+\r
+  //\r
+  // Destination cannot be NULL\r
+  //\r
+  ASSERT (Destination != NULL);\r
+\r
+  //\r
+  // Destination and source cannot overlap\r
+  //\r
+  ASSERT ((UINTN)(Destination - Source) > StrLen (Source));\r
+  ASSERT ((UINTN)(Source - Destination) > StrLen (Source));\r
+\r
+  ReturnValue = Destination;\r
+  while (*Source) {\r
+    *(Destination++) = *(Source++);\r
+  }\r
+  *Destination = 0;\r
+  return ReturnValue;\r
+}\r
+\r
+/**\r
+  Copies one Null-terminated Unicode string with a maximum length to another\r
+  Null-terminated Unicode string with a maximum length and returns the new\r
+  Unicode string.\r
+\r
+  This function copies the contents of the Unicode string Source to the Unicode\r
+  string Destination, and returns Destination. At most, Length Unicode\r
+  characters are copied from Source to Destination. If Length is 0, then\r
+  Destination is returned unmodified. If Length is greater that the number of\r
+  Unicode characters in Source, then Destination is padded with Null Unicode\r
+  characters. If Source and Destination overlap, then the results are\r
+  undefined.\r
+\r
+  If Destination is NULL, then ASSERT().\r
+  If Source is NULL, then ASSERT().\r
+  If Source and Destination overlap, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and Source contains more than\r
+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
+\r
+  @param  Destination Pointer to a Null-terminated Unicode string.\r
+  @param  Source      Pointer to a Null-terminated Unicode string.\r
+  @param  Length      Maximum number of Unicode characters to copy.\r
+\r
+  @return Destination\r
+\r
+**/\r
+CHAR16 *\r
+EFIAPI\r
+StrnCpy (\r
+  OUT     CHAR16                    *Destination,\r
+  IN      CONST CHAR16              *Source,\r
+  IN      UINTN                     Length\r
+  )\r
+{\r
+  CHAR16                            *ReturnValue;\r
+\r
+  if (Length == 0) {\r
+    return Destination;\r
+  }\r
+\r
+  //\r
+  // Destination cannot be NULL if Length is not zero\r
+  //\r
+  ASSERT (Destination != NULL);\r
+\r
+  //\r
+  // Destination and source cannot overlap\r
+  // Q: Does Source have to be NULL-terminated?\r
+  //\r
+  ASSERT ((UINTN)(Destination - Source) > StrLen (Source));\r
+  ASSERT ((UINTN)(Source - Destination) >= Length);\r
+\r
+  ReturnValue = Destination;\r
+\r
+  while ((*Source != L'\0') && (Length > 0)) {\r
+    *(Destination++) = *(Source++);\r
+    Length--;\r
+  }\r
+\r
+  // ZeroMem (Destination, Length * sizeof (*Destination));\r
+  memset (Destination, 0, Length * sizeof (*Destination));\r
+  return ReturnValue;\r
+}\r
+\r
+/**\r
+  Returns the length of a Null-terminated Unicode string.\r
+\r
+  This function returns the number of Unicode characters in the Null-terminated\r
+  Unicode string specified by String.\r
+\r
+  If String is NULL, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
+\r
+  @param  String  Pointer to a Null-terminated Unicode string.\r
+\r
+  @return The length of String.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+StrLen (\r
+  IN      CONST CHAR16              *String\r
+  )\r
+{\r
+  UINTN                             Length;\r
+\r
+  ASSERT (String != NULL);\r
+\r
+  for (Length = 0; *String != L'\0'; String++, Length++) {\r
+    //\r
+    // If PcdMaximumUnicodeStringLength is not zero,\r
+    // length should not more than PcdMaximumUnicodeStringLength\r
+    //\r
+    if (FixedPcdGet32 (PcdMaximumUnicodeStringLength) != 0) {\r
+      ASSERT (Length < FixedPcdGet32 (PcdMaximumUnicodeStringLength));\r
+    }\r
+  }\r
+  return Length;\r
+}\r
+\r
+/**\r
+  Returns the size of a Null-terminated Unicode string in bytes, including the\r
+  Null terminator.\r
+\r
+  This function returns the size, in bytes, of the Null-terminated Unicode\r
+  string specified by String.\r
+\r
+  If String is NULL, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
+\r
+  @param  String  Pointer to a Null-terminated Unicode string.\r
+\r
+  @return The size of String.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+StrSize (\r
+  IN      CONST CHAR16              *String\r
+  )\r
+{\r
+  return (StrLen (String) + 1) * sizeof (*String);\r
+}\r
+\r
+/**\r
+  Compares two Null-terminated Unicode strings, and returns the difference\r
+  between the first mismatched Unicode characters.\r
+\r
+  This function compares the Null-terminated Unicode string FirstString to the\r
+  Null-terminated Unicode string SecondString. If FirstString is identical to\r
+  SecondString, then 0 is returned. Otherwise, the value returned is the first\r
+  mismatched Unicode character in SecondString subtracted from the first\r
+  mismatched Unicode character in FirstString.\r
+\r
+  If FirstString is NULL, then ASSERT().\r
+  If SecondString is NULL, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more\r
+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more\r
+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
+\r
+  @param  FirstString   Pointer to a Null-terminated Unicode string.\r
+  @param  SecondString  Pointer to a Null-terminated Unicode string.\r
+\r
+  @retval 0   FirstString is identical to SecondString.\r
+  @retval !=0 FirstString is not identical to SecondString.\r
+\r
+**/\r
+INTN\r
+EFIAPI\r
+StrCmp (\r
+  IN      CONST CHAR16              *FirstString,\r
+  IN      CONST CHAR16              *SecondString\r
+  )\r
+{\r
+  //\r
+  // ASSERT both strings are less long than PcdMaximumUnicodeStringLength\r
+  //\r
+  ASSERT (StrSize (FirstString) != 0);\r
+  ASSERT (StrSize (SecondString) != 0);\r
+\r
+  while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {\r
+    FirstString++;\r
+    SecondString++;\r
+  }\r
+  return *FirstString - *SecondString;\r
+}\r
+\r
+/**\r
+  Compares two Null-terminated Unicode strings with maximum lengths, and\r
+  returns the difference between the first mismatched Unicode characters.\r
+\r
+  This function compares the Null-terminated Unicode string FirstString to the\r
+  Null-terminated Unicode string SecondString. At most, Length Unicode\r
+  characters will be compared. If Length is 0, then 0 is returned. If\r
+  FirstString is identical to SecondString, then 0 is returned. Otherwise, the\r
+  value returned is the first mismatched Unicode character in SecondString\r
+  subtracted from the first mismatched Unicode character in FirstString.\r
+\r
+  If FirstString is NULL, then ASSERT().\r
+  If SecondString is NULL, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more\r
+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more\r
+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
+\r
+  @param  FirstString   Pointer to a Null-terminated Unicode string.\r
+  @param  SecondString  Pointer to a Null-terminated Unicode string.\r
+  @param  Length        Maximum number of Unicode characters to compare.\r
+\r
+  @retval 0   FirstString is identical to SecondString.\r
+  @retval !=0 FirstString is not identical to SecondString.\r
+\r
+**/\r
+INTN\r
+EFIAPI\r
+StrnCmp (\r
+  IN      CONST CHAR16              *FirstString,\r
+  IN      CONST CHAR16              *SecondString,\r
+  IN      UINTN                     Length\r
+  )\r
+{\r
+  if (Length == 0) {\r
+    return 0;\r
+  }\r
+\r
+  //\r
+  // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.\r
+  // Length tests are performed inside StrLen().\r
+  //\r
+  ASSERT (StrSize (FirstString) != 0);\r
+  ASSERT (StrSize (SecondString) != 0);\r
+\r
+  while ((*FirstString != L'\0') &&\r
+         (*FirstString == *SecondString) &&\r
+         (Length > 1)) {\r
+    FirstString++;\r
+    SecondString++;\r
+    Length--;\r
+  }\r
+\r
+  return *FirstString - *SecondString;\r
+}\r
+\r
+/**\r
+  Concatenates one Null-terminated Unicode string to another Null-terminated\r
+  Unicode string, and returns the concatenated Unicode string.\r
+\r
+  This function concatenates two Null-terminated Unicode strings. The contents\r
+  of Null-terminated Unicode string Source are concatenated to the end of\r
+  Null-terminated Unicode string Destination. The Null-terminated concatenated\r
+  Unicode String is returned. If Source and Destination overlap, then the\r
+  results are undefined.\r
+\r
+  If Destination is NULL, then ASSERT().\r
+  If Source is NULL, then ASSERT().\r
+  If Source and Destination overlap, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and Destination contains more\r
+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and Source contains more than\r
+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination\r
+  and Source results in a Unicode string with more than\r
+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
+\r
+  @param  Destination Pointer to a Null-terminated Unicode string.\r
+  @param  Source      Pointer to a Null-terminated Unicode string.\r
+\r
+  @return Destination\r
+\r
+**/\r
+CHAR16 *\r
+EFIAPI\r
+StrCat (\r
+  IN OUT  CHAR16                    *Destination,\r
+  IN      CONST CHAR16              *Source\r
+  )\r
+{\r
+  StrCpy (Destination + StrLen (Destination), Source);\r
+\r
+  //\r
+  // Size of the resulting string should never be zero.\r
+  // PcdMaximumUnicodeStringLength is tested inside StrLen().\r
+  //\r
+  ASSERT (StrSize (Destination) != 0);\r
+  return Destination;\r
+}\r
+\r
+/**\r
+  Concatenates one Null-terminated Unicode string with a maximum length to the\r
+  end of another Null-terminated Unicode string, and returns the concatenated\r
+  Unicode string.\r
+\r
+  This function concatenates two Null-terminated Unicode strings. The contents\r
+  of Null-terminated Unicode string Source are concatenated to the end of\r
+  Null-terminated Unicode string Destination, and Destination is returned. At\r
+  most, Length Unicode characters are concatenated from Source to the end of\r
+  Destination, and Destination is always Null-terminated. If Length is 0, then\r
+  Destination is returned unmodified. If Source and Destination overlap, then\r
+  the results are undefined.\r
+\r
+  If Destination is NULL, then ASSERT().\r
+  If Source is NULL, then ASSERT().\r
+  If Source and Destination overlap, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and Destination contains more\r
+  than PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and Source contains more than\r
+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination\r
+  and Source results in a Unicode string with more than\r
+  PcdMaximumUnicodeStringLength Unicode characters, then ASSERT().\r
+\r
+  @param  Destination Pointer to a Null-terminated Unicode string.\r
+  @param  Source      Pointer to a Null-terminated Unicode string.\r
+  @param  Length      Maximum number of Unicode characters to concatenate from\r
+                      Source.\r
+\r
+  @return Destination\r
+\r
+**/\r
+CHAR16 *\r
+EFIAPI\r
+StrnCat (\r
+  IN OUT  CHAR16                    *Destination,\r
+  IN      CONST CHAR16              *Source,\r
+  IN      UINTN                     Length\r
+  )\r
+{\r
+  StrnCpy (Destination + StrLen (Destination), Source, Length);\r
+\r
+  //\r
+  // Size of the resulting string should never be zero.\r
+  // PcdMaximumUnicodeStringLength is tested inside StrLen().\r
+  //\r
+  ASSERT (StrSize (Destination) != 0);\r
+  return Destination;\r
+}\r
+\r
+/**\r
+  Copies one Null-terminated ASCII string to another Null-terminated ASCII\r
+  string and returns the new ASCII string.\r
+\r
+  This function copies the contents of the ASCII string Source to the ASCII\r
+  string Destination, and returns Destination. If Source and Destination\r
+  overlap, then the results are undefined.\r
+\r
+  If Destination is NULL, then ASSERT().\r
+  If Source is NULL, then ASSERT().\r
+  If Source and Destination overlap, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero and Source contains more than\r
+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().\r
+\r
+  @param  Destination Pointer to a Null-terminated ASCII string.\r
+  @param  Source      Pointer to a Null-terminated ASCII string.\r
+\r
+  @return Destination\r
+\r
+**/\r
+CHAR8 *\r
+EFIAPI\r
+AsciiStrCpy (\r
+  OUT     CHAR8                     *Destination,\r
+  IN      CONST CHAR8               *Source\r
+  )\r
+{\r
+  CHAR8                             *ReturnValue;\r
+\r
+  //\r
+  // Destination cannot be NULL\r
+  //\r
+  ASSERT (Destination != NULL);\r
+\r
+  //\r
+  // Destination and source cannot overlap\r
+  //\r
+  ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));\r
+  ASSERT ((UINTN)(Source - Destination) > AsciiStrLen (Source));\r
+\r
+  ReturnValue = Destination;\r
+  while (*Source) {\r
+    *(Destination++) = *(Source++);\r
+  }\r
+  *Destination = 0;\r
+  return ReturnValue;\r
+}\r
+\r
+/**\r
+  Copies one Null-terminated ASCII string with a maximum length to another\r
+  Null-terminated ASCII string with a maximum length and returns the new ASCII\r
+  string.\r
+\r
+  This function copies the contents of the ASCII string Source to the ASCII\r
+  string Destination, and returns Destination. At most, Length ASCII characters\r
+  are copied from Source to Destination. If Length is 0, then Destination is\r
+  returned unmodified. If Length is greater that the number of ASCII characters\r
+  in Source, then Destination is padded with Null ASCII characters. If Source\r
+  and Destination overlap, then the results are undefined.\r
+\r
+  If Destination is NULL, then ASSERT().\r
+  If Source is NULL, then ASSERT().\r
+  If Source and Destination overlap, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero, and Source contains more than\r
+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().\r
+\r
+  @param  Destination Pointer to a Null-terminated ASCII string.\r
+  @param  Source      Pointer to a Null-terminated ASCII string.\r
+  @param  Length      Maximum number of ASCII characters to copy.\r
+\r
+  @return Destination\r
+\r
+**/\r
+CHAR8 *\r
+EFIAPI\r
+AsciiStrnCpy (\r
+  OUT     CHAR8                     *Destination,\r
+  IN      CONST CHAR8               *Source,\r
+  IN      UINTN                     Length\r
+  )\r
+{\r
+  CHAR8                             *ReturnValue;\r
+\r
+  if (Length == 0) {\r
+    return Destination;\r
+  }\r
+\r
+  //\r
+  // Destination cannot be NULL\r
+  //\r
+  ASSERT (Destination != NULL);\r
+\r
+  //\r
+  // Destination and source cannot overlap\r
+  //\r
+  ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));\r
+  ASSERT ((UINTN)(Source - Destination) >= Length);\r
+\r
+  ReturnValue = Destination;\r
+\r
+  while (*Source && Length > 0) {\r
+    *(Destination++) = *(Source++);\r
+    Length--;\r
+  }\r
+\r
+  // ZeroMem (Destination, Length * sizeof (*Destination));\r
+  memset (Destination, 0, Length * sizeof (*Destination));\r
+  return ReturnValue;\r
+}\r
+\r
+/**\r
+  Returns the length of a Null-terminated ASCII string.\r
+\r
+  This function returns the number of ASCII characters in the Null-terminated\r
+  ASCII string specified by String.\r
+\r
+  If String is NULL, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero and String contains more than\r
+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().\r
+\r
+  @param  String  Pointer to a Null-terminated ASCII string.\r
+\r
+  @return The length of String.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsciiStrLen (\r
+  IN      CONST CHAR8               *String\r
+  )\r
+{\r
+  UINTN                             Length;\r
+\r
+  ASSERT (String != NULL);\r
+\r
+  for (Length = 0; *String != '\0'; String++, Length++) {\r
+    //\r
+    // If PcdMaximumUnicodeStringLength is not zero,\r
+    // length should not more than PcdMaximumUnicodeStringLength\r
+    //\r
+    if (FixedPcdGet32 (PcdMaximumAsciiStringLength) != 0) {\r
+      ASSERT (Length < FixedPcdGet32 (PcdMaximumAsciiStringLength));\r
+    }\r
+  }\r
+  return Length;\r
+}\r
+\r
+/**\r
+  Returns the size of a Null-terminated ASCII string in bytes, including the\r
+  Null terminator.\r
+\r
+  This function returns the size, in bytes, of the Null-terminated ASCII string\r
+  specified by String.\r
+\r
+  If String is NULL, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero and String contains more than\r
+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().\r
+\r
+  @param  String  Pointer to a Null-terminated ASCII string.\r
+\r
+  @return The size of String.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsciiStrSize (\r
+  IN      CONST CHAR8               *String\r
+  )\r
+{\r
+  return (AsciiStrLen (String) + 1) * sizeof (*String);\r
+}\r
+\r
+/**\r
+  Compares two Null-terminated ASCII strings, and returns the difference\r
+  between the first mismatched ASCII characters.\r
+\r
+  This function compares the Null-terminated ASCII string FirstString to the\r
+  Null-terminated ASCII string SecondString. If FirstString is identical to\r
+  SecondString, then 0 is returned. Otherwise, the value returned is the first\r
+  mismatched ASCII character in SecondString subtracted from the first\r
+  mismatched ASCII character in FirstString.\r
+\r
+  If FirstString is NULL, then ASSERT().\r
+  If SecondString is NULL, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero and FirstString contains more than\r
+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero and SecondString contains more\r
+  than PcdMaximumAsciiStringLength ASCII characters, then ASSERT().\r
+\r
+  @param  FirstString   Pointer to a Null-terminated ASCII string.\r
+  @param  SecondString  Pointer to a Null-terminated ASCII string.\r
+\r
+  @retval 0   FirstString is identical to SecondString.\r
+  @retval !=0 FirstString is not identical to SecondString.\r
+\r
+**/\r
+INTN\r
+EFIAPI\r
+AsciiStrCmp (\r
+  IN      CONST CHAR8               *FirstString,\r
+  IN      CONST CHAR8               *SecondString\r
+  )\r
+{\r
+  //\r
+  // ASSERT both strings are less long than PcdMaximumAsciiStringLength\r
+  //\r
+  ASSERT (AsciiStrSize (FirstString));\r
+  ASSERT (AsciiStrSize (SecondString));\r
+\r
+  while ((*FirstString != '\0') && (*FirstString == *SecondString)) {\r
+    FirstString++;\r
+    SecondString++;\r
+  }\r
+\r
+  return *FirstString - *SecondString;\r
+}\r
+\r
+STATIC\r
+CHAR8\r
+EFIAPI\r
+AsciiToUpper (\r
+  IN      CHAR8                     Chr\r
+  )\r
+{\r
+  return (Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr;\r
+}\r
+\r
+/**\r
+  Performs a case insensitive comparison of two Null-terminated ASCII strings,\r
+  and returns the difference between the first mismatched ASCII characters.\r
+\r
+  This function performs a case insensitive comparison of the Null-terminated\r
+  ASCII string FirstString to the Null-terminated ASCII string SecondString. If\r
+  FirstString is identical to SecondString, then 0 is returned. Otherwise, the\r
+  value returned is the first mismatched lower case ASCII character in\r
+  SecondString subtracted from the first mismatched lower case ASCII character\r
+  in FirstString.\r
+\r
+  If FirstString is NULL, then ASSERT().\r
+  If SecondString is NULL, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero and FirstString contains more than\r
+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero and SecondString contains more\r
+  than PcdMaximumAsciiStringLength ASCII characters, then ASSERT().\r
+\r
+  @param  FirstString   Pointer to a Null-terminated ASCII string.\r
+  @param  SecondString  Pointer to a Null-terminated ASCII string.\r
+\r
+  @retval 0   FirstString is identical to SecondString using case insensitive\r
+              comparisons.\r
+  @retval !=0 FirstString is not identical to SecondString using case\r
+              insensitive comparisons.\r
+\r
+**/\r
+INTN\r
+EFIAPI\r
+AsciiStriCmp (\r
+  IN      CONST CHAR8               *FirstString,\r
+  IN      CONST CHAR8               *SecondString\r
+  )\r
+{\r
+  //\r
+  // ASSERT both strings are less long than PcdMaximumAsciiStringLength\r
+  //\r
+  ASSERT (AsciiStrSize (FirstString));\r
+  ASSERT (AsciiStrSize (SecondString));\r
+\r
+  while ((*FirstString != '\0') &&\r
+         (AsciiToUpper (*FirstString) == AsciiToUpper (*SecondString))) {\r
+    FirstString++;\r
+    SecondString++;\r
+  }\r
+\r
+  return AsciiToUpper (*FirstString) - AsciiToUpper (*SecondString);\r
+}\r
+\r
+/**\r
+  Compares two Null-terminated ASCII strings with maximum lengths, and returns\r
+  the difference between the first mismatched ASCII characters.\r
+\r
+  This function compares the Null-terminated ASCII string FirstString to the\r
+  Null-terminated ASCII  string SecondString. At most, Length ASCII characters\r
+  will be compared. If Length is 0, then 0 is returned. If FirstString is\r
+  identical to SecondString, then 0 is returned. Otherwise, the value returned\r
+  is the first mismatched ASCII character in SecondString subtracted from the\r
+  first mismatched ASCII character in FirstString.\r
+\r
+  If FirstString is NULL, then ASSERT().\r
+  If SecondString is NULL, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero and FirstString contains more than\r
+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero and SecondString contains more\r
+  than PcdMaximumAsciiStringLength ASCII characters, then ASSERT().\r
+\r
+  @param  FirstString   Pointer to a Null-terminated ASCII string.\r
+  @param  SecondString  Pointer to a Null-terminated ASCII string.\r
+\r
+  @retval 0   FirstString is identical to SecondString.\r
+  @retval !=0 FirstString is not identical to SecondString.\r
+\r
+**/\r
+INTN\r
+EFIAPI\r
+AsciiStrnCmp (\r
+  IN      CONST CHAR8               *FirstString,\r
+  IN      CONST CHAR8               *SecondString,\r
+  IN      UINTN                     Length\r
+  )\r
+{\r
+  //\r
+  // ASSERT both strings are less long than PcdMaximumAsciiStringLength\r
+  //\r
+  ASSERT (AsciiStrSize (FirstString));\r
+  ASSERT (AsciiStrSize (SecondString));\r
+\r
+  while ((*FirstString != '\0') &&\r
+         (*FirstString == *SecondString) &&\r
+         (Length > 1)) {\r
+    FirstString++;\r
+    SecondString++;\r
+    Length--;\r
+  }\r
+  return *FirstString - *SecondString;\r
+}\r
+\r
+/**\r
+  Concatenates one Null-terminated ASCII string to another Null-terminated\r
+  ASCII string, and returns the concatenated ASCII string.\r
+\r
+  This function concatenates two Null-terminated ASCII strings. The contents of\r
+  Null-terminated ASCII string Source are concatenated to the end of Null-\r
+  terminated ASCII string Destination. The Null-terminated concatenated ASCII\r
+  String is returned.\r
+\r
+  If Destination is NULL, then ASSERT().\r
+  If Source is NULL, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero and Destination contains more than\r
+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero and Source contains more than\r
+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero and concatenating Destination and\r
+  Source results in a ASCII string with more than PcdMaximumAsciiStringLength\r
+  ASCII characters, then ASSERT().\r
+\r
+  @param  Destination Pointer to a Null-terminated ASCII string.\r
+  @param  Source      Pointer to a Null-terminated ASCII string.\r
+\r
+  @return Destination\r
+\r
+**/\r
+CHAR8 *\r
+EFIAPI\r
+AsciiStrCat (\r
+  IN OUT CHAR8    *Destination,\r
+  IN CONST CHAR8  *Source\r
+  )\r
+{\r
+  AsciiStrCpy (Destination + AsciiStrLen (Destination), Source);\r
+\r
+  //\r
+  // Size of the resulting string should never be zero.\r
+  // PcdMaximumUnicodeStringLength is tested inside StrLen().\r
+  //\r
+  ASSERT (AsciiStrSize (Destination) != 0);\r
+  return Destination;\r
+}\r
+\r
+/**\r
+  Concatenates one Null-terminated ASCII string with a maximum length to the\r
+  end of another Null-terminated ASCII string, and returns the concatenated\r
+  ASCII string.\r
+\r
+  This function concatenates two Null-terminated ASCII strings. The contents\r
+  of Null-terminated ASCII string Source are concatenated to the end of Null-\r
+  terminated ASCII string Destination, and Destination is returned. At most,\r
+  Length ASCII characters are concatenated from Source to the end of\r
+  Destination, and Destination is always Null-terminated. If Length is 0, then\r
+  Destination is returned unmodified. If Source and Destination overlap, then\r
+  the results are undefined.\r
+\r
+  If Destination is NULL, then ASSERT().\r
+  If Source is NULL, then ASSERT().\r
+  If Source and Destination overlap, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero, and Destination contains more\r
+  than PcdMaximumAsciiStringLength ASCII characters, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero, and Source contains more than\r
+  PcdMaximumAsciiStringLength ASCII characters, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero, and concatenating Destination and\r
+  Source results in a ASCII string with more than PcdMaximumAsciiStringLength\r
+  ASCII characters, then ASSERT().\r
+\r
+  @param  Destination Pointer to a Null-terminated ASCII string.\r
+  @param  Source      Pointer to a Null-terminated ASCII string.\r
+  @param  Length      Maximum number of ASCII characters to concatenate from\r
+                      Source.\r
+\r
+  @return Destination\r
+\r
+**/\r
+CHAR8 *\r
+EFIAPI\r
+AsciiStrnCat (\r
+  IN OUT  CHAR8                     *Destination,\r
+  IN      CONST CHAR8               *Source,\r
+  IN      UINTN                     Length\r
+  )\r
+{\r
+  AsciiStrnCpy (Destination + AsciiStrLen (Destination), Source, Length);\r
+\r
+  //\r
+  // Size of the resulting string should never be zero.\r
+  // PcdMaximumUnicodeStringLength is tested inside StrLen().\r
+  //\r
+  ASSERT (AsciiStrSize (Destination) != 0);\r
+  return Destination;\r
+}\r
diff --git a/Tools/Source/TianoTools/String/build.xml b/Tools/Source/TianoTools/String/build.xml
new file mode 100644 (file)
index 0000000..34f44eb
--- /dev/null
@@ -0,0 +1,142 @@
+<?xml version="1.0" ?>\r
+<!--\r
+Copyright (c) 2006, 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
+<project default="GenTool" basedir=".">\r
+<!--\r
+    EDK String\r
+  Copyright (c) 2006, Intel Corporation\r
+-->\r
+  <taskdef resource="cpptasks.tasks"/>\r
+  <typedef resource="cpptasks.types"/>\r
+  <taskdef resource="net/sf/antcontrib/antlib.xml"/>\r
+\r
+  <property name="LibName" value="String"/>\r
+  <property environment="env"/>\r
+\r
+  <property name="LINK_OUTPUT_TYPE" value="static"/>\r
+  <property name="BUILD_DIR" value="${PACKAGE_DIR}/${LibName}/tmp"/>\r
+\r
+  <target name="GenTool" depends="init, String">\r
+    <echo message="Building the EDK Tool: ${LibName}"/>\r
+  </target>\r
+\r
+  <target name="init">\r
+    <echo message="The EDK Library: ${LibName}"/>\r
+    <mkdir dir="${BUILD_DIR}"/>\r
+    <if>\r
+      <equals arg1="${GCC}" arg2="cygwin"/>\r
+      <then>\r
+        <echo message="Cygwin Family"/>\r
+        <property name="ToolChain" value="gcc"/>\r
+      </then>\r
+    <elseif>\r
+      <os family="dos"/>\r
+      <then>\r
+        <echo message="Windows Family"/>\r
+        <property name="ToolChain" value="msvc"/>\r
+      </then>\r
+    </elseif>\r
+    <elseif>\r
+      <os family="unix"/>\r
+      <then>\r
+        <echo message="UNIX Family"/>\r
+        <property name="ToolChain" value="gcc"/>\r
+      </then>\r
+    </elseif>\r
+\r
+    <else>\r
+      <echo>\r
+        Unsupported Operating System\r
+        Please Contact Intel Corporation\r
+      </echo>\r
+    </else>\r
+    </if>\r
+        <property name="ToolChain" value="gcc"/>\r
+    <if>\r
+      <equals arg1="${ToolChain}" arg2="msvc"/>\r
+      <then>\r
+        <property name="ext_static" value=".lib"/>\r
+        <property name="ext_dynamic" value=".dll"/>\r
+        <property name="ext_exe" value=".exe"/>\r
+      </then>\r
+      <elseif>\r
+        <equals arg1="${ToolChain}" arg2="gcc"/>\r
+        <then>\r
+          <property name="ext_static" value=".a"/>\r
+          <property name="ext_dynamic" value=".so"/>\r
+          <property name="ext_exe" value=""/>\r
+        </then>\r
+      </elseif>\r
+    </if>\r
+\r
+    <condition property="syslibdirs" value="">\r
+      <os family="mac"/>\r
+    </condition>\r
+    \r
+    <condition property="syslibs" value="">\r
+      <os family="mac"/>\r
+    </condition>\r
+    \r
+    <condition property="syslibdirs" value="${env.CYGWIN_HOME}/lib/e2fsprogs">\r
+      <os family="windows"/>\r
+    </condition>\r
+    \r
+    <condition property="syslibs" value="uuid">\r
+      <os family="windows"/>\r
+    </condition>\r
+    \r
+    <condition property="syslibdirs" value="/usr/lib">\r
+      <os name="Linux"/>\r
+    </condition>\r
+    \r
+    <condition property="syslibs" value="uuid">\r
+      <os name="Linux"/>\r
+    </condition>\r
+    \r
+  </target>\r
+\r
+  <target name="String" depends="init">\r
+    <cc name="${ToolChain}" objdir="${BUILD_DIR}" \r
+        outfile="${LIB_DIR}/${LibName}"\r
+        outtype="static"\r
+        optimize="speed">\r
+\r
+      <compilerarg value="-fshort-wchar" if="gcc"/>\r
+\r
+      <fileset dir="${basedir}/${LibName}" \r
+        includes="*.c" />\r
+\r
+      <includepath path="${PACKAGE_DIR}/${LibName}"/>\r
+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>\r
+      <includepath path="${env.WORKSPACE}/MdePkg/Include"/>\r
+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Ia32"/>\r
+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Common"/>\r
+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Protocol"/>\r
+      <includepath path="${env.WORKSPACE}/MdePkg/Include/Library"/>\r
+      <includepath path="${PACKAGE_DIR}/Common"/>\r
+    </cc>\r
+  </target>\r
+\r
+\r
+  <target name="clean" depends="init">\r
+    <echo message="Removing Intermediate Files Only"/>  \r
+    <delete>\r
+      <fileset dir="${BUILD_DIR}" includes="*.obj"/>\r
+    </delete>\r
+  </target>\r
+\r
+  <target name="cleanall" depends="init">\r
+    <echo message="Removing Object Files and the Executable: ${LibName}${ext_exe}"/>  \r
+    <delete dir="${PACKAGE_DIR}/${LibName}/tmp">\r
+    </delete>\r
+  </target>\r
+\r
+</project>\r
index 129e99f..64c8fb9 100644 (file)
@@ -23,7 +23,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
   <property name="BIN_DIR" value="${WORKSPACE}/Tools/bin" />\r
   <property name="BUILD_MODE" value="PACKAGE" />\r
   <property name="Libs" \r
-    value="Common/build.xml CustomizedCompress/build.xml PeCoffLoader/build.xml"/>\r
+    value="String/build.xml Common/build.xml CustomizedCompress/build.xml PeCoffLoader/build.xml"/>\r
 \r
   <import file="${WORKSPACE_DIR}/Tools/Conf/BuildMacro.xml" />\r
 \r