MdePkg: Support FDT library.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4392 Add FDT support in EDK2 by submodule 3rd party libfdt (https://github.com/devicetree-org/pylibfdt/tree/main/libfdt) and refer to LibcLib implementation by Pedro. Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Zhiguang Liu <zhiguang.liu@intel.com> Signed-off-by: Benny Lin <benny.lin@intel.com> Acked-by: Pedro Falcato <pedro.falcato@gmail.com> Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
This commit is contained in:
173
MdePkg/Library/BaseFdtLib/LibFdtWrapper.c
Normal file
173
MdePkg/Library/BaseFdtLib/LibFdtWrapper.c
Normal file
@@ -0,0 +1,173 @@
|
||||
/** @file
|
||||
ISO C implementations of strchr, strrchr and strtoul.
|
||||
|
||||
Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2023 Pedro Falcato All rights reserved.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include <Base.h>
|
||||
|
||||
#define ULONG_MAX 0xFFFFFFFF /* Maximum unsigned long value */
|
||||
|
||||
// Very quick notes:
|
||||
// We only go through the string once for both functions
|
||||
// They are minimal implementations (not speed optimized) of ISO C semantics
|
||||
// strchr and strrchr also include the null terminator as part of the string
|
||||
// so the code gets a bit clunky to handle that case specifically.
|
||||
|
||||
char *
|
||||
strchr (
|
||||
const char *Str,
|
||||
int Char
|
||||
)
|
||||
{
|
||||
char *S;
|
||||
|
||||
S = (char *)Str;
|
||||
|
||||
for ( ; ; S++) {
|
||||
if (*S == Char) {
|
||||
return S;
|
||||
}
|
||||
|
||||
if (*S == '\0') {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
strrchr (
|
||||
const char *Str,
|
||||
int Char
|
||||
)
|
||||
{
|
||||
char *S, *last;
|
||||
|
||||
S = (char *)Str;
|
||||
last = NULL;
|
||||
|
||||
for ( ; ; S++) {
|
||||
if (*S == Char) {
|
||||
last = S;
|
||||
}
|
||||
|
||||
if (*S == '\0') {
|
||||
return last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC
|
||||
int
|
||||
__isspace (
|
||||
int ch
|
||||
)
|
||||
{
|
||||
// basic ASCII ctype.h:isspace(). Not efficient
|
||||
return ch == '\r' || ch == '\n' || ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f';
|
||||
}
|
||||
|
||||
unsigned long
|
||||
strtoul (
|
||||
const char *Nptr,
|
||||
char **EndPtr,
|
||||
int Base
|
||||
)
|
||||
{
|
||||
BOOLEAN Negate;
|
||||
BOOLEAN Overflow;
|
||||
unsigned long Val;
|
||||
|
||||
Negate = FALSE;
|
||||
Overflow = FALSE;
|
||||
Val = 0;
|
||||
|
||||
// Reject bad numeric bases
|
||||
if ((Base < 0) || (Base == 1) || (Base > 36)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Skip whitespace
|
||||
while (__isspace (*Nptr)) {
|
||||
Nptr++;
|
||||
}
|
||||
|
||||
// Check for + or - prefixes
|
||||
if (*Nptr == '-') {
|
||||
Negate = TRUE;
|
||||
Nptr++;
|
||||
} else if (*Nptr == '+') {
|
||||
Nptr++;
|
||||
}
|
||||
|
||||
// Consume the start, autodetecting base if needed
|
||||
if ((Nptr[0] == '0') && ((Nptr[1] == 'x') || (Nptr[1] == 'X')) && ((Base == 0) || (Base == 16))) {
|
||||
// Hex
|
||||
Nptr += 2;
|
||||
Base = 16;
|
||||
} else if ((Nptr[0] == '0') && ((Nptr[1] == 'b') || (Nptr[1] == 'B')) && ((Base == 0) || (Base == 2))) {
|
||||
// Binary (standard pending C23)
|
||||
Nptr += 2;
|
||||
Base = 2;
|
||||
} else if ((Nptr[0] == '0') && ((Base == 0) || (Base == 8))) {
|
||||
// Octal
|
||||
Nptr++;
|
||||
Base = 8;
|
||||
} else {
|
||||
if (Base == 0) {
|
||||
// Assume decimal
|
||||
Base = 10;
|
||||
}
|
||||
}
|
||||
|
||||
while (TRUE) {
|
||||
int Digit;
|
||||
char C;
|
||||
unsigned long NewVal;
|
||||
|
||||
C = *Nptr;
|
||||
Digit = -1;
|
||||
|
||||
if ((C >= '0') && (C <= '9')) {
|
||||
Digit = C - '0';
|
||||
} else if ((C >= 'a') && (C <= 'z')) {
|
||||
Digit = C - 'a' + 10;
|
||||
} else if ((C >= 'A') && (C <= 'Z')) {
|
||||
Digit = C - 'A' + 10;
|
||||
}
|
||||
|
||||
if ((Digit == -1) || (Digit >= Base)) {
|
||||
// Note that this case also handles the \0
|
||||
if (EndPtr) {
|
||||
*EndPtr = (char *)Nptr;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
NewVal = Val * Base + Digit;
|
||||
|
||||
if (NewVal < Val) {
|
||||
// Overflow
|
||||
Overflow = TRUE;
|
||||
}
|
||||
|
||||
Val = NewVal;
|
||||
|
||||
Nptr++;
|
||||
}
|
||||
|
||||
if (Negate) {
|
||||
Val = -Val;
|
||||
}
|
||||
|
||||
if (Overflow) {
|
||||
Val = ULONG_MAX;
|
||||
}
|
||||
|
||||
// TODO: We're lacking errno here.
|
||||
return Val;
|
||||
}
|
Reference in New Issue
Block a user