stringdb.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,280 行 · 第 1/5 页

C
2,280
字号
    //   Offset[]  -- an array of offsets to strings, of type RELOFST each
    //   String[]  -- the actual strings themselves
    //
    fprintf (
      Fptr,
      "\n//******************************************************************************"
      "\n// Start of string definitions for %S/%S",
      Lang->LanguageName,
      Lang->PrintableLanguageName
      );
    memset ((char *) &StringPack, 0, sizeof (EFI_HII_STRING_PACK_HEADER));
    StringPack.Header.Type        = EFI_HII_STRING;
    StringPack.NumStringPointers  = (UINT16) mDBData.NumStringIdentifiersReferenced;
    //
    // First string is the language name. If we're printing all languages, then
    // it's just the "spa". If we were given a list of languages to print, then it's
    // the "spacat" string. Compute its offset and fill in
    // the info in the header. Since we know the language name string's length,
    // and the printable language name follows it, use that info to fill in the
    // entry for the printable language name as well.
    //
    StringPack.LanguageNameString = (STRING_OFFSET) (sizeof (EFI_HII_STRING_PACK_HEADER) + (mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET)));
    StringPack.PrintableLanguageName = (STRING_OFFSET) (StringPack.LanguageNameString + (wcslen (LangName) + 1) * sizeof (WCHAR));
    //
    // Add up the size of all strings so we can fill in our header.
    //
    Len = 0;
    for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) {
      //
      // For the first string (language name), we print out the "spacat" if they
      // requested it. We set LangName to point to the proper language name string above.
      //
      if (StringIndex == STRING_ID_LANGUAGE_NAME) {
        Len += (wcslen (LangName) + 1) * sizeof (WCHAR);
      } else {
        //
        // Find a string with this language.stringname
        //
        StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex);
        if (StringIdentifier == NULL) {
          Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex);
          return STATUS_ERROR;
        }
        //
        // Find a matching string if this string identifier was referenced
        //
        EmptyString.Flags = STRING_FLAGS_UNDEFINED;
        CurrString        = NULL;
        if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) {
          CurrString = StringDBFindString (
                        Lang->LanguageName,
                        StringIdentifier->StringName,
                        NULL,
                        LanguagesOfInterest,
                        IndirectionList
                        );
          if (NULL == CurrString) {
            //
            // If string for Lang->LanguageName is not found, try to get an English version
            //
            CurrString = StringDBFindString (
                          L"eng",
                          StringIdentifier->StringName,
                          NULL,
                          LanguagesOfInterest,
                          IndirectionList
                          );
          }
        }

        if (CurrString == NULL) {
          CurrString = &EmptyString;
          EmptyString.Flags |= StringIdentifier->Flags;
        }

        Len += CurrString->Size;
      }
    }
    StringPack.Header.Length =    sizeof (EFI_HII_STRING_PACK_HEADER) 
                                + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET) 
                                + Len;
    //
    // Write out the header one byte at a time
    //
    Ptr = (UINT8 *) &StringPack;
    for (TempIndex = 0; TempIndex < sizeof (EFI_HII_STRING_PACK_HEADER); TempIndex++, Ptr++) {
      if ((TempIndex & 0x07) == 0) {
        fprintf (Fptr, "\n  ");
      }

      fprintf (Fptr, "0x%02X, ", (UINT32) *Ptr);
    }

    fprintf (Fptr, "\n  // offset 0x%X\n", sizeof (StringPack));
    //
    // PASS2 : write the offsets
    //
    // Traverse the list of strings again and write the array of offsets. The
    // offset to the first string is the size of the string pack header
    // plus the size of the offsets array. The other strings follow it.
    //
    StringIndex = 0;
    Offset      = sizeof (StringPack) + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET);
    for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) {
      //
      // Write the offset, followed by a useful comment
      //
      fprintf (Fptr, "  ");
      Ptr = (UINT8 *) &Offset;
      for (TempIndex = 0; TempIndex < sizeof (STRING_OFFSET); TempIndex++) {
        fprintf (Fptr, "0x%02X, ", (UINT32) Ptr[TempIndex]);
      }
      //
      // Find the string name
      //
      StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex);
      if (StringIdentifier == NULL) {
        Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex);
        return STATUS_ERROR;
      }

      fprintf (Fptr, " // offset to string %S (0x%04X)", StringIdentifier->StringName, StringIndex);
      //
      // For the first string (language name), we print out the "spacat" if they
      // requested it. We set LangName to point to the proper language name string above.
      //
      if (StringIndex == STRING_ID_LANGUAGE_NAME) {
        Offset += (wcslen (LangName) + 1) * sizeof (WCHAR);
        CurrString = StringDBFindString (
                      Lang->LanguageName,
                      StringIdentifier->StringName,
                      NULL, // scope
                      NULL,
                      NULL
                      );
      } else {
        //
        // Find a matching string
        //
        CurrString = StringDBFindString (
                      Lang->LanguageName,
                      StringIdentifier->StringName,
                      NULL,   // scope
                      LanguagesOfInterest,
                      IndirectionList
                      );

        if (NULL == CurrString) {
          CurrString = StringDBFindString (
                        L"eng",
                        StringIdentifier->StringName,
                        NULL, // scope
                        LanguagesOfInterest,
                        IndirectionList
                        );
        }

        EmptyString.LanguageName = Lang->LanguageName;
        if (CurrString == NULL) {
          CurrString        = &EmptyString;
          EmptyString.Flags = STRING_FLAGS_UNDEFINED;
        } else if ((StringIdentifier->Flags & STRING_FLAGS_REFERENCED) == 0) {
          CurrString        = &EmptyString;
          EmptyString.Flags = 0;
        }

        Offset += CurrString->Size;
      }
      //
      // Print useful info about this string
      //
      if ((StringIdentifier->Flags & STRING_FLAGS_REFERENCED) == 0) {
        fprintf (Fptr, " - not referenced");
      }

      if (CurrString->Flags & STRING_FLAGS_UNDEFINED) {
        fprintf (Fptr, " - not defined for this language");
      } else if (wcscmp (CurrString->LanguageName, Lang->LanguageName) != 0) {
        fprintf (
          Fptr,
          " - not defined for this language -- using secondary language %S definition",
          CurrString->LanguageName
          );
      }

      fprintf (Fptr, "\n");
    }
    //
    // For unreferenced string identifiers, print a message that they are not referenced anywhere
    //
    while (StringIndex < mDBData.NumStringIdentifiers) {
      StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex);
      if (StringIdentifier != NULL) {
        fprintf (Fptr, "  // %S not referenced\n", StringIdentifier->StringName);
      }

      StringIndex++;
    }

    //
    // PASS 3: write the strings themselves.
    // Keep track of how many bytes we write per line because some editors
    // (Visual Studio for instance) can't handle too long of lines.
    //
    Offset = sizeof (StringPack) + mDBData.NumStringIdentifiersReferenced * sizeof (STRING_OFFSET);
    for (StringIndex = 0; StringIndex < mDBData.NumStringIdentifiersReferenced; StringIndex++) {
      StringIdentifier = StringDBFindStringIdentifierByIndex (StringIndex);
      if (StringIdentifier == NULL) {
        Error (NULL, 0, 0, "internal error", "invalid string index 0x%X", StringIndex);
        return STATUS_ERROR;
      }

      fprintf (Fptr, "  // string %S offset 0x%08X\n  ", StringIdentifier->StringName, Offset);
      //
      // For the first string (language name), we print out the "spacat" if they
      // requested it. We set LangName to point to the proper language name string above.
      //
      if (StringIndex == STRING_ID_LANGUAGE_NAME) {
        TempStringPtr = LangName;
      } else {
        //
        // Find a matching string if this string identifier was referenced
        //
        CurrString = NULL;
        if (StringIdentifier->Flags & STRING_FLAGS_REFERENCED) {
          CurrString = StringDBFindString (
                        Lang->LanguageName,
                        StringIdentifier->StringName,
                        NULL,   // scope
                        LanguagesOfInterest,
                        IndirectionList
                        );
          if (NULL == CurrString) {
            CurrString = StringDBFindString (
                          L"eng",
                          StringIdentifier->StringName,
                          NULL, // scope
                          LanguagesOfInterest,
                          IndirectionList
                          );
          }
        }

        if (CurrString == NULL) {
          CurrString = &EmptyString;
        }

        TempStringPtr = CurrString->Str;
      }

      BytesThisLine = 0;
      for (TempIndex = 0; TempStringPtr[TempIndex] != 0; TempIndex++) {
        fprintf (
          Fptr,
          "0x%02X, 0x%02X, ",
          (UINT32) TempStringPtr[TempIndex] & 0xFF,
          (UINT32) ((TempStringPtr[TempIndex] >> 8) & 0xFF)
          );
        BytesThisLine += 2;
        Offset += 2;
        //
        // Let's say we only allow 14 per line
        //
        if (BytesThisLine > 14) {
          fprintf (Fptr, "\n  ");
          BytesThisLine = 0;
        }
      }
      //
      // Print NULL WCHAR at the end of this string.
      //
      fprintf (Fptr, "0x00, 0x00,\n");
      Offset += 2;
    }
    //
    // Sanity check the offset. Make sure our running offset is what we put in the
    // string pack header.
    //
    if (StringPack.Header.Length != Offset) {
      Error (
        __FILE__,
        __LINE__,
        0,
        "application error",
        "stringpack size 0x%X does not match final size 0x%X",
        StringPack.Header.Length,
        Offset
        );
    }
  }
  //
  // Print terminator string pack, closing brace and close the file.
  // The size of 0 triggers to the consumer that this is the end.
  //
  memset ((char *) &StringPack, 0, sizeof (EFI_HII_STRING_PACK_HEADER));
  StringPack.Header.Type  = EFI_HII_STRING;
  Ptr                     = (UINT8 *) &StringPack;
  fprintf (Fptr, "\n  // strings terminator pack");
  for (TempIndex = 0; TempIndex < sizeof (StringPack); TempIndex++, Ptr++) {
    if ((TempIndex & 0x0F) == 0) {
      fprintf (Fptr, "\n  ");
    }

    fprintf (Fptr, "0x%02X, ", (UINT32) *Ptr);
  }

  fprintf (Fptr, "\n};\n");
  fclose (Fptr);
  return STATUS_SUCCESS;
}

/*****************************************************************************/

/*++

Routine Description:

  Dump the #define string names

Arguments:

  FileName        - name of the output file to write 
  BaseName        - used for the protection #ifndef/#endif 

Returns:

  STATUS

--*/
STATUS
StringDBDumpStringDefines (
  INT8 *FileName,
  INT8 *BaseName
  )
{
  FILE              *Fptr;
  STRING_IDENTIFIER *Identifier;
  INT8              CopyBaseName[100];
  UINT32            Index;
  const INT8        *StrDefHeader[] = {
    "#ifndef _%s_STRINGS_DEFINE_H_\n",
    "#define _%s_STRINGS_DEFINE_H_\n\n",
    NULL
  };

  if ((Fptr = fopen (FileName, "w")) == NULL) {
    Error (NULL, 0, 0, FileName, "failed to open output string defines file");
    return STATUS_ERROR;
  }
  //
  // Get the base source filename and convert to uppercase.
  //
  if (sizeof (CopyBaseName) <= strlen (BaseName) + 1) {
    Error (NULL, 0, 0, "application error", "StringDBDumpStringDefines() string length insufficient");
    return STATUS_ERROR;
  }

  strcpy (CopyBaseName, BaseName);
  for (Index = 0; CopyBaseName[Index] != 0; Index++) {
    if (islower (CopyBaseName[Index])) {
      CopyBaseName[Index] = (INT8) toupper (CopyBaseName[Index]);
    }
  }
  //
  // Assign index values to the string identifiers
  //
  StringDBAssignStringIndexes ();
  //
  // Write the standard header to the output file, and then the
  // protective #ifndef.
  //
  StringDBWriteStandardFileHeader (Fptr);
  for (Index = 0; StrDefHeader[Index] != NULL; Index++) {
    fprintf (Fptr, StrDefHeader[Index], CopyBaseName);
  }
  //
  // Print all the #defines for the string identifiers. Print identifiers
  // whose names start with '$' as comments. Add comments for string
  // identifiers not used as well.
  //
  Identifier = mDBData.StringIdentifier;
  while (Identifier != NULL) {
    if (Identifier->StringName[0] == L'$') {
      fprintf (Fptr, "// ");
    }

    if (Identifier->Flags & STRING_FLAGS_REFERENCED) {
      fprintf (Fptr, "#define %-40S 0x%04X\n", Identifier->StringName, Identifier->Index);
    } else {
      fprintf (Fptr, "//#define %-40S 0x%04X // not referenced\n", Identifier->StringName, Identifier->Index);
    }

    Identifier = Identifier->Next;
  }

  fprintf (Fptr, "\n#endif\n");
  fclose (Fptr);
  return STATUS_SUCCESS;
}

/*****************************************************************************/

/*++

Routine Description:

  Add a string identifier to the database.

Arguments:

  StringName      - name of the string identifier. For example "STR_MY_STRING"
  NewId           - if an ID has been assigned
  Flags           - characteristics for the identifier

Returns:

  STATUS

--*/
STATUS
StringDBAddStringIdentifier (
  WCHAR     *StringName,
  UINT16    *NewId,
  UINT16    Flags
  )
{
  STRING_IDENTIFIER *StringIdentifier;
  STATUS            Status;
  //
  // If it was already used for some other language, then we don't
  // need to add it. But set it to the current string identifier.
  // The referenced bit is sticky.
  //
  Status            = STATUS_SUCCESS;
  StringIdentifier  = StringDBFindStringIdentifierByName (StringName);
  if (StringIdentifier != NULL) {
    if (Flags & STRING_FLAGS_REFERENCED) {
      StringIdentifier->Flags |= STRING_FLAGS_REFERENCED;
    }

    mDBData.CurrentStringIdentifier = StringIdentifier;
    *NewId                          = (UINT16) StringIdentifier->Index;
    return Status;
  }

  StringIdentifier = (STRING_IDENTIFIER *) MALLOC (sizeof (STRING_IDENTIFIER));
  if (StringIdentifier == NULL) {
    Error (NULL, 0, 0, NULL, "memory allocation error");
    return STATUS_ERROR;
  }

  memset ((char *) StringIdentifier, 0, sizeof (STRING_IDENTIFIER));
  StringIdentifier->StringName = (WCHAR *) malloc ((wcslen (StringName) + 1) * sizeof (WCHAR));
  if (StringIdentifier->StringName == NULL) {
    Error (NULL, 0, 0, NULL, "memory allocation error");
    return STATUS_ERROR;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?