TianoCore EDK2 master
Loading...
Searching...
No Matches
LibFdtWrapper.c
Go to the documentation of this file.
1
10#include <Base.h>
11
12#define ULONG_MAX 0xFFFFFFFF /* Maximum unsigned long value */
13
14// Very quick notes:
15// We only go through the string once for both functions
16// They are minimal implementations (not speed optimized) of ISO C semantics
17// strchr and strrchr also include the null terminator as part of the string
18// so the code gets a bit clunky to handle that case specifically.
19
20char *
21fdt_strrchr (
22 const char *Str,
23 int Char
24 )
25{
26 char *S, *last;
27
28 S = (char *)Str;
29 last = NULL;
30
31 for ( ; ; S++) {
32 if (*S == Char) {
33 last = S;
34 }
35
36 if (*S == '\0') {
37 return last;
38 }
39 }
40}
41
43int
44__isspace (
45 int ch
46 )
47{
48 // basic ASCII ctype.h:isspace(). Not efficient
49 return ch == '\r' || ch == '\n' || ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f';
50}
51
52unsigned long
53fdt_strtoul (
54 const char *Nptr,
55 char **EndPtr,
56 int Base
57 )
58{
59 BOOLEAN Negate;
60 BOOLEAN Overflow;
61 unsigned long Val;
62
63 Negate = FALSE;
64 Overflow = FALSE;
65 Val = 0;
66
67 // Reject bad numeric bases
68 if ((Base < 0) || (Base == 1) || (Base > 36)) {
69 return 0;
70 }
71
72 // Skip whitespace
73 while (__isspace (*Nptr)) {
74 Nptr++;
75 }
76
77 // Check for + or - prefixes
78 if (*Nptr == '-') {
79 Negate = TRUE;
80 Nptr++;
81 } else if (*Nptr == '+') {
82 Nptr++;
83 }
84
85 // Consume the start, autodetecting base if needed
86 if ((Nptr[0] == '0') && ((Nptr[1] == 'x') || (Nptr[1] == 'X')) && ((Base == 0) || (Base == 16))) {
87 // Hex
88 Nptr += 2;
89 Base = 16;
90 } else if ((Nptr[0] == '0') && ((Nptr[1] == 'b') || (Nptr[1] == 'B')) && ((Base == 0) || (Base == 2))) {
91 // Binary (standard pending C23)
92 Nptr += 2;
93 Base = 2;
94 } else if ((Nptr[0] == '0') && ((Base == 0) || (Base == 8))) {
95 // Octal
96 Nptr++;
97 Base = 8;
98 } else {
99 if (Base == 0) {
100 // Assume decimal
101 Base = 10;
102 }
103 }
104
105 while (TRUE) {
106 int Digit;
107 char C;
108 unsigned long NewVal;
109
110 C = *Nptr;
111 Digit = -1;
112
113 if ((C >= '0') && (C <= '9')) {
114 Digit = C - '0';
115 } else if ((C >= 'a') && (C <= 'z')) {
116 Digit = C - 'a' + 10;
117 } else if ((C >= 'A') && (C <= 'Z')) {
118 Digit = C - 'A' + 10;
119 }
120
121 if ((Digit == -1) || (Digit >= Base)) {
122 // Note that this case also handles the \0
123 if (EndPtr) {
124 *EndPtr = (char *)Nptr;
125 }
126
127 break;
128 }
129
130 NewVal = Val * Base + Digit;
131
132 if (NewVal < Val) {
133 // Overflow
134 Overflow = TRUE;
135 }
136
137 Val = NewVal;
138
139 Nptr++;
140 }
141
142 if (Negate) {
143 Val = -Val;
144 }
145
146 if (Overflow) {
147 Val = ULONG_MAX;
148 }
149
150 // TODO: We're lacking errno here.
151 return Val;
152}
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307