audk/BaseTools/Source/C/Common/StringFuncs.c

414 lines
6.7 KiB
C

/** @file
Function prototypes and defines for string routines.
Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <string.h>
#include <ctype.h>
#include "StringFuncs.h"
//
// Functions implementations
//
CHAR8*
CloneString (
IN CHAR8 *String
)
/*++
Routine Description:
Allocates a new string and copies 'String' to clone it
Arguments:
String The string to clone
Returns:
CHAR8* - NULL if there are not enough resources
--*/
{
CHAR8* NewString;
NewString = malloc (strlen (String) + 1);
if (NewString != NULL) {
strcpy (NewString, String);
}
return NewString;
}
EFI_STATUS
StripInfDscStringInPlace (
IN CHAR8 *String
)
/*++
Routine Description:
Remove all comments, leading and trailing whitespace from the string.
Arguments:
String The string to 'strip'
Returns:
EFI_STATUS
--*/
{
CHAR8 *Pos;
if (String == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Remove leading whitespace
//
for (Pos = String; isspace ((int)*Pos); Pos++) {
}
if (Pos != String) {
memmove (String, Pos, strlen (Pos) + 1);
}
//
// Comment BUGBUGs!
//
// What about strings? Comment characters are okay in strings.
// What about multiline comments?
//
Pos = (CHAR8 *) strstr (String, "//");
if (Pos != NULL) {
*Pos = '\0';
}
Pos = (CHAR8 *) strchr (String, '#');
if (Pos != NULL) {
*Pos = '\0';
}
//
// Remove trailing whitespace
//
for (Pos = String + strlen (String);
((Pos - 1) >= String) && (isspace ((int)*(Pos - 1)));
Pos--
) {
}
*Pos = '\0';
return EFI_SUCCESS;
}
STRING_LIST*
SplitStringByWhitespace (
IN CHAR8 *String
)
/*++
Routine Description:
Creates and returns a 'split' STRING_LIST by splitting the string
on whitespace boundaries.
Arguments:
String The string to 'split'
Returns:
EFI_STATUS
--*/
{
CHAR8 *Pos;
CHAR8 *EndOfSubString;
CHAR8 *EndOfString;
STRING_LIST *Output;
UINTN Item;
String = CloneString (String);
if (String == NULL) {
return NULL;
}
EndOfString = String + strlen (String);
Output = NewStringList ();
for (Pos = String, Item = 0; Pos < EndOfString; Item++) {
while (isspace ((int)*Pos)) {
Pos++;
}
for (EndOfSubString=Pos;
(*EndOfSubString != '\0') && !isspace ((int)*EndOfSubString);
EndOfSubString++
) {
}
if (EndOfSubString == Pos) {
break;
}
*EndOfSubString = '\0';
AppendCopyOfStringToList (&Output, Pos);
Pos = EndOfSubString + 1;
}
free (String);
return Output;
}
STRING_LIST*
NewStringList (
)
/*++
Routine Description:
Creates a new STRING_LIST with 0 strings.
Returns:
STRING_LIST* - Null if there is not enough resources to create the object.
--*/
{
STRING_LIST *NewList;
NewList = AllocateStringListStruct (0);
if (NewList != NULL) {
NewList->Count = 0;
}
return NewList;
}
EFI_STATUS
AppendCopyOfStringToList (
IN OUT STRING_LIST **StringList,
IN CHAR8 *String
)
/*++
Routine Description:
Adds String to StringList. A new copy of String is made before it is
added to StringList.
Returns:
EFI_STATUS
--*/
{
STRING_LIST *OldList;
STRING_LIST *NewList;
CHAR8 *NewString;
OldList = *StringList;
NewList = AllocateStringListStruct (OldList->Count + 1);
if (NewList == NULL) {
return EFI_OUT_OF_RESOURCES;
}
NewString = CloneString (String);
if (NewString == NULL) {
free (NewList);
return EFI_OUT_OF_RESOURCES;
}
memcpy (
NewList->Strings,
OldList->Strings,
sizeof (OldList->Strings[0]) * OldList->Count
);
NewList->Count = OldList->Count + 1;
NewList->Strings[OldList->Count] = NewString;
*StringList = NewList;
free (OldList);
return EFI_SUCCESS;
}
EFI_STATUS
RemoveLastStringFromList (
IN STRING_LIST *StringList
)
/*++
Routine Description:
Removes the last string from StringList and frees the memory associated
with it.
Arguments:
StringList The string list to remove the string from
Returns:
EFI_STATUS
--*/
{
if (StringList->Count == 0) {
return EFI_INVALID_PARAMETER;
}
free (StringList->Strings[StringList->Count - 1]);
StringList->Count--;
return EFI_SUCCESS;
}
STRING_LIST*
AllocateStringListStruct (
IN UINTN StringCount
)
/*++
Routine Description:
Allocates a STRING_LIST structure that can store StringCount strings.
Arguments:
StringCount The number of strings that need to be stored
Returns:
EFI_STATUS
--*/
{
return malloc (OFFSET_OF(STRING_LIST, Strings[StringCount + 1]));
}
VOID
FreeStringList (
IN STRING_LIST *StringList
)
/*++
Routine Description:
Frees all memory associated with StringList.
Arguments:
StringList The string list to free
Returns:
VOID
--*/
{
while (StringList->Count > 0) {
RemoveLastStringFromList (StringList);
}
free (StringList);
}
CHAR8*
StringListToString (
IN STRING_LIST *StringList
)
/*++
Routine Description:
Generates a string that represents the STRING_LIST
Arguments:
StringList The string list to convert to a string
Returns:
CHAR8* - The string list represented with a single string. The returned
string must be freed by the caller.
--*/
{
UINTN Count;
UINTN Length;
CHAR8 *NewString;
Length = 2;
for (Count = 0; Count < StringList->Count; Count++) {
if (Count > 0) {
Length += 2;
}
Length += strlen (StringList->Strings[Count]) + 2;
}
NewString = malloc (Length + 1);
if (NewString == NULL) {
return NewString;
}
NewString[0] = '\0';
strcat (NewString, "[");
for (Count = 0; Count < StringList->Count; Count++) {
if (Count > 0) {
strcat (NewString, ", ");
}
strcat (NewString, "\"");
strcat (NewString, StringList->Strings[Count]);
strcat (NewString, "\"");
}
strcat (NewString, "]");
return NewString;
}
VOID
PrintStringList (
IN STRING_LIST *StringList
)
/*++
Routine Description:
Prints out the string list
Arguments:
StringList The string list to print
Returns:
EFI_STATUS
--*/
{
CHAR8* String;
String = StringListToString (StringList);
if (String != NULL) {
printf ("%s", String);
free (String);
}
}