StringFuncs.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. /** @file
  2. Function prototypes and defines for string routines.
  3. Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include <string.h>
  7. #include <ctype.h>
  8. #include "StringFuncs.h"
  9. //
  10. // Functions implementations
  11. //
  12. CHAR8*
  13. CloneString (
  14. IN CHAR8 *String
  15. )
  16. /*++
  17. Routine Description:
  18. Allocates a new string and copies 'String' to clone it
  19. Arguments:
  20. String The string to clone
  21. Returns:
  22. CHAR8* - NULL if there are not enough resources
  23. --*/
  24. {
  25. CHAR8* NewString;
  26. NewString = malloc (strlen (String) + 1);
  27. if (NewString != NULL) {
  28. strcpy (NewString, String);
  29. }
  30. return NewString;
  31. }
  32. EFI_STATUS
  33. StripInfDscStringInPlace (
  34. IN CHAR8 *String
  35. )
  36. /*++
  37. Routine Description:
  38. Remove all comments, leading and trailing whitespace from the string.
  39. Arguments:
  40. String The string to 'strip'
  41. Returns:
  42. EFI_STATUS
  43. --*/
  44. {
  45. CHAR8 *Pos;
  46. if (String == NULL) {
  47. return EFI_INVALID_PARAMETER;
  48. }
  49. //
  50. // Remove leading whitespace
  51. //
  52. for (Pos = String; isspace ((int)*Pos); Pos++) {
  53. }
  54. if (Pos != String) {
  55. memmove (String, Pos, strlen (Pos) + 1);
  56. }
  57. //
  58. // Comment BUGBUGs!
  59. //
  60. // What about strings? Comment characters are okay in strings.
  61. // What about multiline comments?
  62. //
  63. Pos = (CHAR8 *) strstr (String, "//");
  64. if (Pos != NULL) {
  65. *Pos = '\0';
  66. }
  67. Pos = (CHAR8 *) strchr (String, '#');
  68. if (Pos != NULL) {
  69. *Pos = '\0';
  70. }
  71. //
  72. // Remove trailing whitespace
  73. //
  74. for (Pos = String + strlen (String);
  75. ((Pos - 1) >= String) && (isspace ((int)*(Pos - 1)));
  76. Pos--
  77. ) {
  78. }
  79. *Pos = '\0';
  80. return EFI_SUCCESS;
  81. }
  82. STRING_LIST*
  83. SplitStringByWhitespace (
  84. IN CHAR8 *String
  85. )
  86. /*++
  87. Routine Description:
  88. Creates and returns a 'split' STRING_LIST by splitting the string
  89. on whitespace boundaries.
  90. Arguments:
  91. String The string to 'split'
  92. Returns:
  93. EFI_STATUS
  94. --*/
  95. {
  96. CHAR8 *Pos;
  97. CHAR8 *EndOfSubString;
  98. CHAR8 *EndOfString;
  99. STRING_LIST *Output;
  100. UINTN Item;
  101. String = CloneString (String);
  102. if (String == NULL) {
  103. return NULL;
  104. }
  105. EndOfString = String + strlen (String);
  106. Output = NewStringList ();
  107. for (Pos = String, Item = 0; Pos < EndOfString; Item++) {
  108. while (isspace ((int)*Pos)) {
  109. Pos++;
  110. }
  111. for (EndOfSubString=Pos;
  112. (*EndOfSubString != '\0') && !isspace ((int)*EndOfSubString);
  113. EndOfSubString++
  114. ) {
  115. }
  116. if (EndOfSubString == Pos) {
  117. break;
  118. }
  119. *EndOfSubString = '\0';
  120. AppendCopyOfStringToList (&Output, Pos);
  121. Pos = EndOfSubString + 1;
  122. }
  123. free (String);
  124. return Output;
  125. }
  126. STRING_LIST*
  127. NewStringList (
  128. )
  129. /*++
  130. Routine Description:
  131. Creates a new STRING_LIST with 0 strings.
  132. Returns:
  133. STRING_LIST* - Null if there is not enough resources to create the object.
  134. --*/
  135. {
  136. STRING_LIST *NewList;
  137. NewList = AllocateStringListStruct (0);
  138. if (NewList != NULL) {
  139. NewList->Count = 0;
  140. }
  141. return NewList;
  142. }
  143. EFI_STATUS
  144. AppendCopyOfStringToList (
  145. IN OUT STRING_LIST **StringList,
  146. IN CHAR8 *String
  147. )
  148. /*++
  149. Routine Description:
  150. Adds String to StringList. A new copy of String is made before it is
  151. added to StringList.
  152. Returns:
  153. EFI_STATUS
  154. --*/
  155. {
  156. STRING_LIST *OldList;
  157. STRING_LIST *NewList;
  158. CHAR8 *NewString;
  159. OldList = *StringList;
  160. NewList = AllocateStringListStruct (OldList->Count + 1);
  161. if (NewList == NULL) {
  162. return EFI_OUT_OF_RESOURCES;
  163. }
  164. NewString = CloneString (String);
  165. if (NewString == NULL) {
  166. free (NewList);
  167. return EFI_OUT_OF_RESOURCES;
  168. }
  169. memcpy (
  170. NewList->Strings,
  171. OldList->Strings,
  172. sizeof (OldList->Strings[0]) * OldList->Count
  173. );
  174. NewList->Count = OldList->Count + 1;
  175. NewList->Strings[OldList->Count] = NewString;
  176. *StringList = NewList;
  177. free (OldList);
  178. return EFI_SUCCESS;
  179. }
  180. EFI_STATUS
  181. RemoveLastStringFromList (
  182. IN STRING_LIST *StringList
  183. )
  184. /*++
  185. Routine Description:
  186. Removes the last string from StringList and frees the memory associated
  187. with it.
  188. Arguments:
  189. StringList The string list to remove the string from
  190. Returns:
  191. EFI_STATUS
  192. --*/
  193. {
  194. if (StringList->Count == 0) {
  195. return EFI_INVALID_PARAMETER;
  196. }
  197. free (StringList->Strings[StringList->Count - 1]);
  198. StringList->Count--;
  199. return EFI_SUCCESS;
  200. }
  201. STRING_LIST*
  202. AllocateStringListStruct (
  203. IN UINTN StringCount
  204. )
  205. /*++
  206. Routine Description:
  207. Allocates a STRING_LIST structure that can store StringCount strings.
  208. Arguments:
  209. StringCount The number of strings that need to be stored
  210. Returns:
  211. EFI_STATUS
  212. --*/
  213. {
  214. return malloc (OFFSET_OF(STRING_LIST, Strings[StringCount + 1]));
  215. }
  216. VOID
  217. FreeStringList (
  218. IN STRING_LIST *StringList
  219. )
  220. /*++
  221. Routine Description:
  222. Frees all memory associated with StringList.
  223. Arguments:
  224. StringList The string list to free
  225. Returns:
  226. VOID
  227. --*/
  228. {
  229. while (StringList->Count > 0) {
  230. RemoveLastStringFromList (StringList);
  231. }
  232. free (StringList);
  233. }
  234. CHAR8*
  235. StringListToString (
  236. IN STRING_LIST *StringList
  237. )
  238. /*++
  239. Routine Description:
  240. Generates a string that represents the STRING_LIST
  241. Arguments:
  242. StringList The string list to convert to a string
  243. Returns:
  244. CHAR8* - The string list represented with a single string. The returned
  245. string must be freed by the caller.
  246. --*/
  247. {
  248. UINTN Count;
  249. UINTN Length;
  250. CHAR8 *NewString;
  251. Length = 2;
  252. for (Count = 0; Count < StringList->Count; Count++) {
  253. if (Count > 0) {
  254. Length += 2;
  255. }
  256. Length += strlen (StringList->Strings[Count]) + 2;
  257. }
  258. NewString = malloc (Length + 1);
  259. if (NewString == NULL) {
  260. return NewString;
  261. }
  262. NewString[0] = '\0';
  263. strcat (NewString, "[");
  264. for (Count = 0; Count < StringList->Count; Count++) {
  265. if (Count > 0) {
  266. strcat (NewString, ", ");
  267. }
  268. strcat (NewString, "\"");
  269. strcat (NewString, StringList->Strings[Count]);
  270. strcat (NewString, "\"");
  271. }
  272. strcat (NewString, "]");
  273. return NewString;
  274. }
  275. VOID
  276. PrintStringList (
  277. IN STRING_LIST *StringList
  278. )
  279. /*++
  280. Routine Description:
  281. Prints out the string list
  282. Arguments:
  283. StringList The string list to print
  284. Returns:
  285. EFI_STATUS
  286. --*/
  287. {
  288. CHAR8* String;
  289. String = StringListToString (StringList);
  290. if (String != NULL) {
  291. printf ("%s", String);
  292. free (String);
  293. }
  294. }