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*
CloneString(IN CHAR8 * String)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
StripInfDscStringInPlace(IN CHAR8 * String)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*
SplitStringByWhitespace(IN CHAR8 * String)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*
NewStringList()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
AppendCopyOfStringToList(IN OUT STRING_LIST ** StringList,IN CHAR8 * String)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
RemoveLastStringFromList(IN STRING_LIST * StringList)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*
AllocateStringListStruct(IN UINTN StringCount)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
FreeStringList(IN STRING_LIST * StringList)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*
StringListToString(IN STRING_LIST * StringList)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
PrintStringList(IN STRING_LIST * StringList)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