1/** @file 2Function prototypes and defines for string routines. 3 4Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR> 5This program and the accompanying materials 6are licensed and made available under the terms and conditions of the BSD License 7which accompanies this distribution. The full text of the license may be found at 8http://opensource.org/licenses/bsd-license.php 9 10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13**/ 14 15#include <string.h> 16#include <ctype.h> 17#include "StringFuncs.h" 18 19// 20// Functions implementations 21// 22 23CHAR8* 24CloneString ( 25 IN CHAR8 *String 26 ) 27/*++ 28 29Routine Description: 30 31 Allocates a new string and copies 'String' to clone it 32 33Arguments: 34 35 String The string to clone 36 37Returns: 38 39 CHAR8* - NULL if there are not enough resources 40 41--*/ 42{ 43 CHAR8* NewString; 44 45 NewString = malloc (strlen (String) + 1); 46 if (NewString != NULL) { 47 strcpy (NewString, String); 48 } 49 50 return NewString; 51} 52 53 54EFI_STATUS 55StripInfDscStringInPlace ( 56 IN CHAR8 *String 57 ) 58/*++ 59 60Routine Description: 61 62 Remove all comments, leading and trailing whitespace from the string. 63 64Arguments: 65 66 String The string to 'strip' 67 68Returns: 69 70 EFI_STATUS 71 72--*/ 73{ 74 CHAR8 *Pos; 75 76 if (String == NULL) { 77 return EFI_INVALID_PARAMETER; 78 } 79 80 // 81 // Remove leading whitespace 82 // 83 for (Pos = String; isspace ((int)*Pos); Pos++) { 84 } 85 if (Pos != String) { 86 memmove (String, Pos, strlen (Pos) + 1); 87 } 88 89 // 90 // Comment BUGBUGs! 91 // 92 // What about strings? Comment characters are okay in strings. 93 // What about multiline comments? 94 // 95 96 Pos = (CHAR8 *) strstr (String, "//"); 97 if (Pos != NULL) { 98 *Pos = '\0'; 99 } 100 101 Pos = (CHAR8 *) strchr (String, '#'); 102 if (Pos != NULL) { 103 *Pos = '\0'; 104 } 105 106 // 107 // Remove trailing whitespace 108 // 109 for (Pos = String + strlen (String); 110 ((Pos - 1) >= String) && (isspace ((int)*(Pos - 1))); 111 Pos-- 112 ) { 113 } 114 *Pos = '\0'; 115 116 return EFI_SUCCESS; 117} 118 119 120STRING_LIST* 121SplitStringByWhitespace ( 122 IN CHAR8 *String 123 ) 124/*++ 125 126Routine Description: 127 128 Creates and returns a 'split' STRING_LIST by splitting the string 129 on whitespace boundaries. 130 131Arguments: 132 133 String The string to 'split' 134 135Returns: 136 137 EFI_STATUS 138 139--*/ 140{ 141 CHAR8 *Pos; 142 CHAR8 *EndOfSubString; 143 CHAR8 *EndOfString; 144 STRING_LIST *Output; 145 UINTN Item; 146 147 String = CloneString (String); 148 if (String == NULL) { 149 return NULL; 150 } 151 EndOfString = String + strlen (String); 152 153 Output = NewStringList (); 154 155 for (Pos = String, Item = 0; Pos < EndOfString; Item++) { 156 while (isspace ((int)*Pos)) { 157 Pos++; 158 } 159 160 for (EndOfSubString=Pos; 161 (*EndOfSubString != '\0') && !isspace ((int)*EndOfSubString); 162 EndOfSubString++ 163 ) { 164 } 165 166 if (EndOfSubString == Pos) { 167 break; 168 } 169 170 *EndOfSubString = '\0'; 171 172 AppendCopyOfStringToList (&Output, Pos); 173 174 Pos = EndOfSubString + 1; 175 } 176 177 free (String); 178 return Output; 179} 180 181 182STRING_LIST* 183NewStringList ( 184 ) 185/*++ 186 187Routine Description: 188 189 Creates a new STRING_LIST with 0 strings. 190 191Returns: 192 193 STRING_LIST* - Null if there is not enough resources to create the object. 194 195--*/ 196{ 197 STRING_LIST *NewList; 198 NewList = AllocateStringListStruct (0); 199 if (NewList != NULL) { 200 NewList->Count = 0; 201 } 202 return NewList; 203} 204 205 206EFI_STATUS 207AppendCopyOfStringToList ( 208 IN OUT STRING_LIST **StringList, 209 IN CHAR8 *String 210 ) 211/*++ 212 213Routine Description: 214 215 Adds String to StringList. A new copy of String is made before it is 216 added to StringList. 217 218Returns: 219 220 EFI_STATUS 221 222--*/ 223{ 224 STRING_LIST *OldList; 225 STRING_LIST *NewList; 226 CHAR8 *NewString; 227 228 OldList = *StringList; 229 NewList = AllocateStringListStruct (OldList->Count + 1); 230 if (NewList == NULL) { 231 return EFI_OUT_OF_RESOURCES; 232 } 233 234 NewString = CloneString (String); 235 if (NewString == NULL) { 236 free (NewList); 237 return EFI_OUT_OF_RESOURCES; 238 } 239 240 memcpy ( 241 NewList->Strings, 242 OldList->Strings, 243 sizeof (OldList->Strings[0]) * OldList->Count 244 ); 245 NewList->Count = OldList->Count + 1; 246 NewList->Strings[OldList->Count] = NewString; 247 248 *StringList = NewList; 249 free (OldList); 250 251 return EFI_SUCCESS; 252} 253 254 255EFI_STATUS 256RemoveLastStringFromList ( 257 IN STRING_LIST *StringList 258 ) 259/*++ 260 261Routine Description: 262 263 Removes the last string from StringList and frees the memory associated 264 with it. 265 266Arguments: 267 268 StringList The string list to remove the string from 269 270Returns: 271 272 EFI_STATUS 273 274--*/ 275{ 276 if (StringList->Count == 0) { 277 return EFI_INVALID_PARAMETER; 278 } 279 280 free (StringList->Strings[StringList->Count - 1]); 281 StringList->Count--; 282 return EFI_SUCCESS; 283} 284 285 286STRING_LIST* 287AllocateStringListStruct ( 288 IN UINTN StringCount 289 ) 290/*++ 291 292Routine Description: 293 294 Allocates a STRING_LIST structure that can store StringCount strings. 295 296Arguments: 297 298 StringCount The number of strings that need to be stored 299 300Returns: 301 302 EFI_STATUS 303 304--*/ 305{ 306 return malloc (OFFSET_OF(STRING_LIST, Strings[StringCount + 1])); 307} 308 309 310VOID 311FreeStringList ( 312 IN STRING_LIST *StringList 313 ) 314/*++ 315 316Routine Description: 317 318 Frees all memory associated with StringList. 319 320Arguments: 321 322 StringList The string list to free 323 324Returns: 325 326 VOID 327--*/ 328{ 329 while (StringList->Count > 0) { 330 RemoveLastStringFromList (StringList); 331 } 332 333 free (StringList); 334} 335 336 337CHAR8* 338StringListToString ( 339 IN STRING_LIST *StringList 340 ) 341/*++ 342 343Routine Description: 344 345 Generates a string that represents the STRING_LIST 346 347Arguments: 348 349 StringList The string list to convert to a string 350 351Returns: 352 353 CHAR8* - The string list represented with a single string. The returned 354 string must be freed by the caller. 355 356--*/ 357{ 358 UINTN Count; 359 UINTN Length; 360 CHAR8 *NewString; 361 362 Length = 2; 363 for (Count = 0; Count < StringList->Count; Count++) { 364 if (Count > 0) { 365 Length += 2; 366 } 367 Length += strlen (StringList->Strings[Count]) + 2; 368 } 369 370 NewString = malloc (Length + 1); 371 if (NewString == NULL) { 372 return NewString; 373 } 374 NewString[0] = '\0'; 375 376 strcat (NewString, "["); 377 for (Count = 0; Count < StringList->Count; Count++) { 378 if (Count > 0) { 379 strcat (NewString, ", "); 380 } 381 strcat (NewString, "\""); 382 strcat (NewString, StringList->Strings[Count]); 383 strcat (NewString, "\""); 384 } 385 strcat (NewString, "]"); 386 387 return NewString; 388} 389 390 391VOID 392PrintStringList ( 393 IN STRING_LIST *StringList 394 ) 395/*++ 396 397Routine Description: 398 399 Prints out the string list 400 401Arguments: 402 403 StringList The string list to print 404 405Returns: 406 407 EFI_STATUS 408 409--*/ 410{ 411 CHAR8* String; 412 String = StringListToString (StringList); 413 if (String != NULL) { 414 printf ("%s", String); 415 free (String); 416 } 417} 418 419 420