]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportString.c
MdeModulePkg/EbcDebugger: Compare ASCII char with '\0'
[mirror_edk2.git] / MdeModulePkg / Universal / EbcDxe / EbcDebugger / EdbSupportString.c
1 /*++
2
3 Copyright (c) 2007 - 2016, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 EdbSupportString.c
15
16 Abstract:
17
18
19 --*/
20
21 #include "Edb.h"
22
23 UINTN
24 EFIAPI
25 Xtoi (
26 CHAR16 *str
27 )
28 /*++
29
30 Routine Description:
31
32 Convert hex string to uint
33
34 Arguments:
35
36 Str - The string
37
38 Returns:
39
40 --*/
41 {
42 UINTN u;
43 CHAR16 c;
44 UINTN m;
45
46 ASSERT (str != NULL);
47
48 m = (UINTN) -1 >> 4;
49 //
50 // skip preceeding white space
51 //
52 while (*str && *str == ' ') {
53 str += 1;
54 }
55 //
56 // skip preceeding zeros
57 //
58 while (*str && *str == '0') {
59 str += 1;
60 }
61 //
62 // skip preceeding white space
63 //
64 if (*str && (*str == 'x' || *str == 'X')) {
65 str += 1;
66 }
67 //
68 // convert hex digits
69 //
70 u = 0;
71 c = *(str++);
72 while (c) {
73 if (c >= 'a' && c <= 'f') {
74 c -= 'a' - 'A';
75 }
76
77 if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) {
78 if (u > m) {
79 return (UINTN) -1;
80 }
81
82 u = (u << 4) | (c - (c >= 'A' ? 'A' - 10 : '0'));
83 } else {
84 break;
85 }
86
87 c = *(str++);
88 }
89
90 return u;
91 }
92
93 UINT64
94 EFIAPI
95 LXtoi (
96 CHAR16 *str
97 )
98 /*++
99
100 Routine Description:
101
102 Convert hex string to uint
103
104 Arguments:
105
106 Str - The string
107
108 Returns:
109
110 --*/
111 {
112 UINT64 u;
113 CHAR16 c;
114 UINT64 m;
115
116 ASSERT (str != NULL);
117
118 m = RShiftU64 ((UINT64) -1, 4);
119 //
120 // skip preceeding white space
121 //
122 while (*str && *str == ' ') {
123 str += 1;
124 }
125 //
126 // skip preceeding zeros
127 //
128 while (*str && *str == '0') {
129 str += 1;
130 }
131 //
132 // skip preceeding white space
133 //
134 if (*str && (*str == 'x' || *str == 'X')) {
135 str += 1;
136 }
137 //
138 // convert hex digits
139 //
140 u = 0;
141 c = *(str++);
142 while (c) {
143 if (c >= 'a' && c <= 'f') {
144 c -= 'a' - 'A';
145 }
146
147 if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) {
148 if (u > m) {
149 return (UINT64) -1;
150 }
151
152 u = LShiftU64 (u, 4);
153 u = u + (c - (c >= 'A' ? 'A' - 10 : '0'));
154 } else {
155 break;
156 }
157
158 c = *(str++);
159 }
160
161 return u;
162 }
163
164 UINTN
165 EFIAPI
166 Atoi (
167 CHAR16 *str
168 )
169 /*++
170
171 Routine Description:
172
173 Convert hex string to uint
174
175 Arguments:
176
177 Str - The string
178
179 Returns:
180
181 --*/
182 {
183 UINTN u;
184 CHAR16 c;
185 UINTN m;
186 UINTN n;
187
188 ASSERT (str != NULL);
189
190 m = (UINTN) -1 / 10;
191 n = (UINTN) -1 % 10;
192 //
193 // skip preceeding white space
194 //
195 while (*str && *str == ' ') {
196 str += 1;
197 }
198 //
199 // convert digits
200 //
201 u = 0;
202 c = *(str++);
203 while (c) {
204 if (c >= '0' && c <= '9') {
205 if (u > m || (u == m && c - '0' > (INTN) n)) {
206 return (UINTN) -1;
207 }
208
209 u = (u * 10) + c - '0';
210 } else {
211 break;
212 }
213
214 c = *(str++);
215 }
216
217 return u;
218 }
219
220 UINTN
221 EFIAPI
222 AsciiXtoi (
223 CHAR8 *str
224 )
225 /*++
226
227 Routine Description:
228
229 Convert hex string to uint
230
231 Arguments:
232
233 Str - The string
234
235 Returns:
236
237 --*/
238 {
239 UINTN u;
240 CHAR8 c;
241 UINTN m;
242
243 ASSERT (str != NULL);
244
245 m = (UINTN) -1 >> 4;
246 //
247 // skip preceeding white space
248 //
249 while (*str && *str == ' ') {
250 str += 1;
251 }
252 //
253 // skip preceeding zeros
254 //
255 while (*str && *str == '0') {
256 str += 1;
257 }
258 //
259 // skip preceeding white space
260 //
261 if (*str && (*str == 'x' || *str == 'X')) {
262 str += 1;
263 }
264 //
265 // convert hex digits
266 //
267 u = 0;
268 c = *(str++);
269 while (c) {
270 if (c >= 'a' && c <= 'f') {
271 c -= 'a' - 'A';
272 }
273
274 if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) {
275 if (u > m) {
276 return (UINTN) -1;
277 }
278
279 u = (u << 4) | (c - (c >= 'A' ? 'A' - 10 : '0'));
280 } else {
281 break;
282 }
283
284 c = *(str++);
285 }
286
287 return u;
288 }
289
290 UINTN
291 EFIAPI
292 AsciiAtoi (
293 CHAR8 *str
294 )
295 /*++
296
297 Routine Description:
298
299 Convert hex string to uint
300
301 Arguments:
302
303 Str - The string
304
305 Returns:
306
307 --*/
308 {
309 UINTN u;
310 CHAR8 c;
311 UINTN m;
312 UINTN n;
313
314 ASSERT (str != NULL);
315
316 m = (UINTN) -1 / 10;
317 n = (UINTN) -1 % 10;
318 //
319 // skip preceeding white space
320 //
321 while (*str && *str == ' ') {
322 str += 1;
323 }
324 //
325 // convert digits
326 //
327 u = 0;
328 c = *(str++);
329 while (c) {
330 if (c >= '0' && c <= '9') {
331 if (u > m || (u == m && c - '0' > (INTN) n)) {
332 return (UINTN) -1;
333 }
334
335 u = (u * 10) + c - '0';
336 } else {
337 break;
338 }
339
340 c = *(str++);
341 }
342
343 return u;
344 }
345
346 STATIC
347 CHAR16
348 UnicodeToUpper (
349 IN CHAR16 Chr
350 )
351 {
352 return (Chr >= L'a' && Chr <= L'z') ? Chr - (L'a' - L'A') : Chr;
353 }
354
355 STATIC
356 CHAR8
357 AsciiToUpper (
358 IN CHAR8 Chr
359 )
360 {
361 return (Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr;
362 }
363
364 INTN
365 EFIAPI
366 StrCmpUnicodeAndAscii (
367 IN CHAR16 *String,
368 IN CHAR8 *String2
369 )
370 /*++
371
372 Routine Description:
373 Compare the Unicode and Ascii string pointed by String to the string pointed by String2.
374
375 Arguments:
376 String - Unicode String to process
377
378 String2 - Ascii string to process
379
380 Returns:
381 Return a positive integer if String is lexicall greater than String2; Zero if
382 the two strings are identical; and a negative interger if String is lexically
383 less than String2.
384
385 --*/
386 {
387 while (*String) {
388 if (*String != (CHAR16)*String2) {
389 break;
390 }
391
392 String += 1;
393 String2 += 1;
394 }
395
396 return (*String - (CHAR16)*String2);
397 }
398
399 INTN
400 EFIAPI
401 StriCmp (
402 IN CHAR16 *String,
403 IN CHAR16 *String2
404 )
405 /*++
406
407 Routine Description:
408 Compare the Unicode string pointed by String to the string pointed by String2.
409
410 Arguments:
411 String - Unicode String to process
412 String2 - Unicode string to process
413
414 Returns:
415 Return a positive integer if String is lexically greater than String2; Zero if
416 the two strings are identical; and a negative integer if String is lexically
417 less than String2.
418
419 --*/
420 {
421 while ((*String != L'\0') &&
422 (UnicodeToUpper (*String) == UnicodeToUpper (*String2))) {
423 String++;
424 String2++;
425 }
426
427 return UnicodeToUpper (*String) - UnicodeToUpper (*String2);
428 }
429
430 INTN
431 EFIAPI
432 StriCmpUnicodeAndAscii (
433 IN CHAR16 *String,
434 IN CHAR8 *String2
435 )
436 /*++
437
438 Routine Description:
439 Compare the Unicode and Ascii string pointed by String to the string pointed by String2.
440
441 Arguments:
442 String - Unicode String to process
443
444 String2 - Ascii string to process
445
446 Returns:
447 Return a positive integer if String is lexically greater than String2; Zero if
448 the two strings are identical; and a negative integer if String is lexically
449 less than String2.
450
451 --*/
452 {
453 while ((*String != L'\0') &&
454 (UnicodeToUpper (*String) == (CHAR16)AsciiToUpper (*String2))) {
455 String++;
456 String2++;
457 }
458
459 return UnicodeToUpper (*String) - (CHAR16)AsciiToUpper (*String2);
460 }
461
462 BOOLEAN
463 EFIAPI
464 StrEndWith (
465 IN CHAR16 *Str,
466 IN CHAR16 *SubStr
467 )
468 /*++
469
470 Routine Description:
471
472 Verify if the string is end with the sub string.
473
474 --*/
475 {
476 CHAR16 *Temp;
477
478 if ((Str == NULL) || (SubStr == NULL) || (StrLen(Str) < StrLen(SubStr))) {
479 return FALSE;
480 }
481
482 Temp = Str + StrLen(Str) - StrLen(SubStr);
483
484 //
485 // Compare
486 //
487 if (StriCmp (Temp, SubStr) == 0) {
488 return TRUE;
489 } else {
490 return FALSE;
491 }
492 }
493
494 CHAR16 *
495 EFIAPI
496 StrDuplicate (
497 IN CHAR16 *Src
498 )
499 // duplicate a string
500 {
501 CHAR16 *Dest;
502 UINTN Size;
503
504 Size = (StrLen(Src) + 1) * sizeof(CHAR16);
505 Dest = AllocateZeroPool (Size);
506 if (Dest) {
507 CopyMem (Dest, Src, Size);
508 }
509 return Dest;
510 }
511
512
513 CHAR16 *mLineBuffer = NULL;
514 CHAR16 *mFieldBuffer = NULL;
515
516 UINTN
517 EFIAPI
518 StrSpn (
519 IN CHAR16 *String,
520 IN CHAR16 *CharSet
521 )
522 /*++
523
524 Routine Description:
525
526 Find the first substring.
527
528 --*/
529 {
530 UINTN Count;
531 CHAR16 *Str1;
532 CHAR16 *Str2;
533
534 Count = 0;
535
536 for (Str1 = String; *Str1 != L'\0'; Str1 ++) {
537 for (Str2 = CharSet; *Str2 != L'\0'; Str2 ++) {
538 if (*Str1 == *Str2) {
539 break;
540 }
541 }
542
543 if (*Str2 == L'\0') {
544 return Count;
545 }
546
547 Count ++;
548 }
549
550 return Count;
551 }
552
553
554 CHAR16 *
555 EFIAPI
556 StrBrk (
557 IN CHAR16 *String,
558 IN CHAR16 *CharSet
559 )
560 /*++
561
562 Routine Description:
563
564 Searches a string for the first occurrence of a character contained in a
565 specified buffer.
566
567 --*/
568 {
569 CHAR16 *Str1;
570 CHAR16 *Str2;
571
572 for (Str1 = String; *Str1 != L'\0'; Str1 ++) {
573 for (Str2 = CharSet; *Str2 != L'\0'; Str2 ++) {
574 if (*Str1 == *Str2) {
575 return (CHAR16 *) Str1;
576 }
577 }
578 }
579
580 return NULL;
581 }
582
583 CHAR16 *
584 EFIAPI
585 StrTokenLine (
586 IN CHAR16 *String OPTIONAL,
587 IN CHAR16 *CharSet
588 )
589 /*++
590
591 Routine Description:
592
593 Find the next token after one or more specified characters.
594
595 --*/
596 {
597 CHAR16 *Begin;
598 CHAR16 *End;
599
600 Begin = (String == NULL) ? mLineBuffer : String;
601 if (Begin == NULL) {
602 return NULL;
603 }
604
605 Begin += StrSpn (Begin, CharSet);
606 if (*Begin == L'\0') {
607 mLineBuffer = NULL;
608 return NULL;
609 }
610
611 End = StrBrk (Begin, CharSet);
612 if ((End != NULL) && (*End != L'\0')) {
613 *End = L'\0';
614 End ++;
615 }
616
617 mLineBuffer = End;
618 return Begin;
619 }
620
621
622 CHAR16 *
623 EFIAPI
624 StrTokenField (
625 IN CHAR16 *String OPTIONAL,
626 IN CHAR16 *CharSet
627 )
628 /*++
629
630 Routine Description:
631
632 Find the next token after one specificed characters.
633
634 --*/
635 {
636 CHAR16 *Begin;
637 CHAR16 *End;
638
639
640 Begin = (String == NULL) ? mFieldBuffer : String;
641 if (Begin == NULL) {
642 return NULL;
643 }
644
645 if (*Begin == L'\0') {
646 mFieldBuffer = NULL;
647 return NULL;
648 }
649
650 End = StrBrk (Begin, CharSet);
651 if ((End != NULL) && (*End != L'\0')) {
652 *End = L'\0';
653 End ++;
654 }
655
656 mFieldBuffer = End;
657 return Begin;
658 }
659
660 CHAR16 *
661 EFIAPI
662 StrGetNewTokenLine (
663 IN CHAR16 *String,
664 IN CHAR16 *CharSet
665 )
666 {
667 return StrTokenLine (String, CharSet);
668 }
669
670 CHAR16 *
671 EFIAPI
672 StrGetNextTokenLine (
673 IN CHAR16 *CharSet
674 )
675 {
676 return StrTokenLine (NULL, CharSet);
677 }
678
679 CHAR16 *
680 EFIAPI
681 StrGetNewTokenField (
682 IN CHAR16 *String,
683 IN CHAR16 *CharSet
684 )
685 {
686 return StrTokenField (String, CharSet);
687 }
688
689 CHAR16 *
690 EFIAPI
691 StrGetNextTokenField (
692 IN CHAR16 *CharSet
693 )
694 {
695 return StrTokenField (NULL, CharSet);
696 }
697
698 VOID
699 EFIAPI
700 PatchForStrTokenAfter (
701 IN CHAR16 *Buffer,
702 IN CHAR16 Patch
703 )
704 {
705 CHAR16 *Str;
706
707 if (Buffer == NULL) {
708 return ;
709 }
710
711 Str = Buffer;
712 while (*Str != 0) {
713 Str ++;
714 }
715 *Str = Patch;
716
717 while (*(Str ++)) {
718 if (*Str == 0) {
719 *Str = Patch;
720 } else {
721 break;
722 }
723 }
724
725 return ;
726 }
727
728 VOID
729 EFIAPI
730 PatchForStrTokenBefore (
731 IN CHAR16 *Buffer,
732 IN CHAR16 Patch
733 )
734 {
735 CHAR16 *Str;
736
737 if (Buffer == NULL) {
738 return ;
739 }
740
741 Str = Buffer;
742 while (*(Str --)) {
743 if ((*Str == 0) || (*Str == Patch)) {
744 *Str = Patch;
745 } else {
746 break;
747 }
748 }
749
750 return ;
751 }
752
753 CHAR8 *mAsciiLineBuffer = NULL;
754 CHAR8 *mAsciiFieldBuffer = NULL;
755
756 UINTN
757 EFIAPI
758 AsciiStrSpn (
759 IN CHAR8 *String,
760 IN CHAR8 *CharSet
761 )
762 /*++
763
764 Routine Description:
765
766 Find the first substring.
767
768 --*/
769 {
770 UINTN Count;
771 CHAR8 *Str1;
772 CHAR8 *Str2;
773
774 Count = 0;
775
776 for (Str1 = String; *Str1 != '\0'; Str1 ++) {
777 for (Str2 = CharSet; *Str2 != '\0'; Str2 ++) {
778 if (*Str1 == *Str2) {
779 break;
780 }
781 }
782
783 if (*Str2 == '\0') {
784 return Count;
785 }
786
787 Count ++;
788 }
789
790 return Count;
791 }
792
793
794 CHAR8 *
795 EFIAPI
796 AsciiStrBrk (
797 IN CHAR8 *String,
798 IN CHAR8 *CharSet
799 )
800 /*++
801
802 Routine Description:
803
804 Searches a string for the first occurrence of a character contained in a
805 specified buffer.
806
807 --*/
808 {
809 CHAR8 *Str1;
810 CHAR8 *Str2;
811
812 for (Str1 = String; *Str1 != '\0'; Str1 ++) {
813 for (Str2 = CharSet; *Str2 != '\0'; Str2 ++) {
814 if (*Str1 == *Str2) {
815 return (CHAR8 *) Str1;
816 }
817 }
818 }
819
820 return NULL;
821 }
822
823 CHAR8 *
824 EFIAPI
825 AsciiStrTokenLine (
826 IN CHAR8 *String OPTIONAL,
827 IN CHAR8 *CharSet
828 )
829 /*++
830
831 Routine Description:
832
833 Find the next token after one or more specified characters.
834
835 --*/
836 {
837 CHAR8 *Begin;
838 CHAR8 *End;
839
840 Begin = (String == NULL) ? mAsciiLineBuffer : String;
841 if (Begin == NULL) {
842 return NULL;
843 }
844
845 Begin += AsciiStrSpn (Begin, CharSet);
846 if (*Begin == '\0') {
847 mAsciiLineBuffer = NULL;
848 return NULL;
849 }
850
851 End = AsciiStrBrk (Begin, CharSet);
852 if ((End != NULL) && (*End != '\0')) {
853 *End = '\0';
854 End ++;
855 }
856
857 mAsciiLineBuffer = End;
858 return Begin;
859 }
860
861
862 CHAR8 *
863 EFIAPI
864 AsciiStrTokenField (
865 IN CHAR8 *String OPTIONAL,
866 IN CHAR8 *CharSet
867 )
868 /*++
869
870 Routine Description:
871
872 Find the next token after one specificed characters.
873
874 --*/
875 {
876 CHAR8 *Begin;
877 CHAR8 *End;
878
879
880 Begin = (String == NULL) ? mAsciiFieldBuffer : String;
881 if (Begin == NULL) {
882 return NULL;
883 }
884
885 if (*Begin == '\0') {
886 mAsciiFieldBuffer = NULL;
887 return NULL;
888 }
889
890 End = AsciiStrBrk (Begin, CharSet);
891 if ((End != NULL) && (*End != '\0')) {
892 *End = '\0';
893 End ++;
894 }
895
896 mAsciiFieldBuffer = End;
897 return Begin;
898 }
899
900 CHAR8 *
901 EFIAPI
902 AsciiStrGetNewTokenLine (
903 IN CHAR8 *String,
904 IN CHAR8 *CharSet
905 )
906 {
907 return AsciiStrTokenLine (String, CharSet);
908 }
909
910 CHAR8 *
911 EFIAPI
912 AsciiStrGetNextTokenLine (
913 IN CHAR8 *CharSet
914 )
915 {
916 return AsciiStrTokenLine (NULL, CharSet);
917 }
918
919 CHAR8 *
920 EFIAPI
921 AsciiStrGetNewTokenField (
922 IN CHAR8 *String,
923 IN CHAR8 *CharSet
924 )
925 {
926 return AsciiStrTokenField (String, CharSet);
927 }
928
929 CHAR8 *
930 EFIAPI
931 AsciiStrGetNextTokenField (
932 IN CHAR8 *CharSet
933 )
934 {
935 return AsciiStrTokenField (NULL, CharSet);
936 }
937
938 VOID
939 EFIAPI
940 PatchForAsciiStrTokenAfter (
941 IN CHAR8 *Buffer,
942 IN CHAR8 Patch
943 )
944 {
945 CHAR8 *Str;
946
947 if (Buffer == NULL) {
948 return ;
949 }
950
951 Str = Buffer;
952 while (*Str != 0) {
953 Str ++;
954 }
955 *Str = Patch;
956
957 while (*(Str ++)) {
958 if (*Str == 0) {
959 *Str = Patch;
960 } else {
961 break;
962 }
963 }
964
965 return ;
966 }
967
968 VOID
969 EFIAPI
970 PatchForAsciiStrTokenBefore (
971 IN CHAR8 *Buffer,
972 IN CHAR8 Patch
973 )
974 {
975 CHAR8 *Str;
976
977 if (Buffer == NULL) {
978 return ;
979 }
980
981 Str = Buffer;
982 while (*(Str --)) {
983 if ((*Str == 0) || (*Str == Patch)) {
984 *Str = Patch;
985 } else {
986 break;
987 }
988 }
989
990 return ;
991 }