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