Home | History | Annotate | Download | only in Common
      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