1 /** @file 2 Function prototypes and defines for string routines. 3 4 Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR> 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions of the BSD License 7 which accompanies this distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT 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 23 CHAR8* 24 CloneString ( 25 IN CHAR8 *String 26 ) 27 /*++ 28 29 Routine Description: 30 31 Allocates a new string and copies 'String' to clone it 32 33 Arguments: 34 35 String The string to clone 36 37 Returns: 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 54 EFI_STATUS 55 StripInfDscStringInPlace ( 56 IN CHAR8 *String 57 ) 58 /*++ 59 60 Routine Description: 61 62 Remove all comments, leading and trailing whitespace from the string. 63 64 Arguments: 65 66 String The string to 'strip' 67 68 Returns: 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 120 STRING_LIST* 121 SplitStringByWhitespace ( 122 IN CHAR8 *String 123 ) 124 /*++ 125 126 Routine Description: 127 128 Creates and returns a 'split' STRING_LIST by splitting the string 129 on whitespace boundaries. 130 131 Arguments: 132 133 String The string to 'split' 134 135 Returns: 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 182 STRING_LIST* 183 NewStringList ( 184 ) 185 /*++ 186 187 Routine Description: 188 189 Creates a new STRING_LIST with 0 strings. 190 191 Returns: 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 206 EFI_STATUS 207 AppendCopyOfStringToList ( 208 IN OUT STRING_LIST **StringList, 209 IN CHAR8 *String 210 ) 211 /*++ 212 213 Routine Description: 214 215 Adds String to StringList. A new copy of String is made before it is 216 added to StringList. 217 218 Returns: 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 255 EFI_STATUS 256 RemoveLastStringFromList ( 257 IN STRING_LIST *StringList 258 ) 259 /*++ 260 261 Routine Description: 262 263 Removes the last string from StringList and frees the memory associated 264 with it. 265 266 Arguments: 267 268 StringList The string list to remove the string from 269 270 Returns: 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 286 STRING_LIST* 287 AllocateStringListStruct ( 288 IN UINTN StringCount 289 ) 290 /*++ 291 292 Routine Description: 293 294 Allocates a STRING_LIST structure that can store StringCount strings. 295 296 Arguments: 297 298 StringCount The number of strings that need to be stored 299 300 Returns: 301 302 EFI_STATUS 303 304 --*/ 305 { 306 return malloc (OFFSET_OF(STRING_LIST, Strings[StringCount + 1])); 307 } 308 309 310 VOID 311 FreeStringList ( 312 IN STRING_LIST *StringList 313 ) 314 /*++ 315 316 Routine Description: 317 318 Frees all memory associated with StringList. 319 320 Arguments: 321 322 StringList The string list to free 323 324 Returns: 325 326 VOID 327 --*/ 328 { 329 while (StringList->Count > 0) { 330 RemoveLastStringFromList (StringList); 331 } 332 333 free (StringList); 334 } 335 336 337 CHAR8* 338 StringListToString ( 339 IN STRING_LIST *StringList 340 ) 341 /*++ 342 343 Routine Description: 344 345 Generates a string that represents the STRING_LIST 346 347 Arguments: 348 349 StringList The string list to convert to a string 350 351 Returns: 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 391 VOID 392 PrintStringList ( 393 IN STRING_LIST *StringList 394 ) 395 /*++ 396 397 Routine Description: 398 399 Prints out the string list 400 401 Arguments: 402 403 StringList The string list to print 404 405 Returns: 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