* Re: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime library
2020-12-14 3:53 ` [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime library Abner Chang
@ 2020-12-14 17:06 ` Michael D Kinney
2020-12-16 6:52 ` Abner Chang
[not found] ` <16511FD303DAB3AC.18439@groups.io>
2020-12-14 23:30 ` Michael D Kinney
2020-12-15 0:19 ` Michael D Kinney
2 siblings, 2 replies; 15+ messages in thread
From: Michael D Kinney @ 2020-12-14 17:06 UTC (permalink / raw)
To: devel@edk2.groups.io, abner.chang@hpe.com, Kinney, Michael D
Cc: Leif Lindholm, Nickle Wang, Peter O'Hanley
If CrtLib is a custom library to support use of jansson, then it should go into
a private include directory in RedFishPkg, not the public include directory.
The only include files that should go into the public include directory of
a package are include files that are available to modules/libs implemented
outside the RedFishPkg. Please review all the include files in RedFishPkg
with this in mind.
Mike
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Abner Chang
> Sent: Sunday, December 13, 2020 7:53 PM
> To: devel@edk2.groups.io
> Cc: Leif Lindholm <leif@nuviainc.com>; Nickle Wang <nickle.wang@hpe.com>; Peter O'Hanley <peter.ohanley@hpe.com>
> Subject: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime library
>
> CRT library is currently used by edk2 JsonLib (open source
> jansson project) and edk2 RedfishLib (libredfish open source
> project). CrtLib library provides the necessary C runtime
> equivalent edk2 functions for open source projects.
>
> Signed-off-by: Abner Chang <abner.chang@hpe.com>
>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Nickle Wang <nickle.wang@hpe.com>
> Cc: Peter O'Hanley <peter.ohanley@hpe.com>
> ---
> RedfishPkg/Include/Crt/assert.h | 16 +
> RedfishPkg/Include/Crt/errno.h | 16 +
> RedfishPkg/Include/Crt/limits.h | 16 +
> RedfishPkg/Include/Crt/math.h | 16 +
> RedfishPkg/Include/Crt/stdarg.h | 15 +
> RedfishPkg/Include/Crt/stddef.h | 16 +
> RedfishPkg/Include/Crt/stdio.h | 15 +
> RedfishPkg/Include/Crt/stdlib.h | 16 +
> RedfishPkg/Include/Crt/string.h | 16 +
> RedfishPkg/Include/Crt/sys/time.h | 15 +
> RedfishPkg/Include/Crt/sys/types.h | 15 +
> RedfishPkg/Include/Crt/time.h | 15 +
> RedfishPkg/Include/Library/CrtLib.h | 195 ++++++++
> RedfishPkg/Library/CrtLib/CrtLib.c | 705 +++++++++++++++++++++++++++
> RedfishPkg/Library/CrtLib/CrtLib.inf | 37 ++
> RedfishPkg/RedfishLibs.dsc.inc | 1 +
> RedfishPkg/RedfishPkg.ci.yaml | 19 +
> RedfishPkg/RedfishPkg.dec | 8 +
> RedfishPkg/RedfishPkg.dsc | 1 +
> 19 files changed, 1153 insertions(+)
> create mode 100644 RedfishPkg/Include/Crt/assert.h
> create mode 100644 RedfishPkg/Include/Crt/errno.h
> create mode 100644 RedfishPkg/Include/Crt/limits.h
> create mode 100644 RedfishPkg/Include/Crt/math.h
> create mode 100644 RedfishPkg/Include/Crt/stdarg.h
> create mode 100644 RedfishPkg/Include/Crt/stddef.h
> create mode 100644 RedfishPkg/Include/Crt/stdio.h
> create mode 100644 RedfishPkg/Include/Crt/stdlib.h
> create mode 100644 RedfishPkg/Include/Crt/string.h
> create mode 100644 RedfishPkg/Include/Crt/sys/time.h
> create mode 100644 RedfishPkg/Include/Crt/sys/types.h
> create mode 100644 RedfishPkg/Include/Crt/time.h
> create mode 100644 RedfishPkg/Include/Library/CrtLib.h
> create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.c
> create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.inf
>
> diff --git a/RedfishPkg/Include/Crt/assert.h b/RedfishPkg/Include/Crt/assert.h
> new file mode 100644
> index 0000000000..f9ab7ef9ca
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/assert.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_ASSERT_H_
> +#define CRT_ASSERT_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/errno.h b/RedfishPkg/Include/Crt/errno.h
> new file mode 100644
> index 0000000000..d30aee14de
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/errno.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_ERRNO_H_
> +#define CRT_ERRNO_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/limits.h b/RedfishPkg/Include/Crt/limits.h
> new file mode 100644
> index 0000000000..f3bdd33f2a
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/limits.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_LIMITS_H_
> +#define CRT_LIMITS_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/math.h b/RedfishPkg/Include/Crt/math.h
> new file mode 100644
> index 0000000000..984c0ccc21
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/math.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_MATH_H_
> +#define CRT_MATH_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/stdarg.h b/RedfishPkg/Include/Crt/stdarg.h
> new file mode 100644
> index 0000000000..d5a314ad3b
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/stdarg.h
> @@ -0,0 +1,15 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef CRT_STDARG_H_
> +#define CRT_STDARG_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/stddef.h b/RedfishPkg/Include/Crt/stddef.h
> new file mode 100644
> index 0000000000..15a37bf50e
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/stddef.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_STDDEF_H_
> +#define CRT_STDDEF_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/stdio.h b/RedfishPkg/Include/Crt/stdio.h
> new file mode 100644
> index 0000000000..25e610be10
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/stdio.h
> @@ -0,0 +1,15 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef CRT_STDIO_H_
> +#define CRT_STDIO_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/stdlib.h b/RedfishPkg/Include/Crt/stdlib.h
> new file mode 100644
> index 0000000000..5b3dd273c8
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/stdlib.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_STDLIB_H_
> +#define CRT_STDLIB_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/string.h b/RedfishPkg/Include/Crt/string.h
> new file mode 100644
> index 0000000000..f60b87ccd2
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/string.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_STRING_H_
> +#define CRT_STRING_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/sys/time.h b/RedfishPkg/Include/Crt/sys/time.h
> new file mode 100644
> index 0000000000..4ced176cda
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/sys/time.h
> @@ -0,0 +1,15 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef CRT_SYS_TIME_H_
> +#define CRT_SYS_TIME_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/sys/types.h b/RedfishPkg/Include/Crt/sys/types.h
> new file mode 100644
> index 0000000000..c4f807214c
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/sys/types.h
> @@ -0,0 +1,15 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef CRT_SYS_TYPES_H_
> +#define CRT_SYS_TYPES_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/time.h b/RedfishPkg/Include/Crt/time.h
> new file mode 100644
> index 0000000000..ca04ac8730
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/time.h
> @@ -0,0 +1,15 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef CRT_TIME_H_
> +#define CRT_TIME_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Library/CrtLib.h b/RedfishPkg/Include/Library/CrtLib.h
> new file mode 100644
> index 0000000000..8c7484e75b
> --- /dev/null
> +++ b/RedfishPkg/Include/Library/CrtLib.h
> @@ -0,0 +1,195 @@
> +/** @file
> + CRT wrapper head functions for jansson system call.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_LIB_H_
> +#define CRT_LIB_H_
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PrintLib.h>
> +
> +#define MAX_STRING_SIZE 0x10000000
> +
> +// Minimum value for an object of type long long int.
> +#define LLONG_MIN MIN_INT64
> +
> +// Maximum value for an object of type long long int.
> +#define LLONG_MAX MAX_INT64
> +
> +// We dont support double on edk2
> +#define HUGE_VAL 0
> +
> +#if defined(MDE_CPU_X64) || defined(MDE_CPU_AARCH64) || defined(MDE_CPU_IA64) || defined(MDE_CPU_RISCV64)
> +//
> +// With GCC we would normally use SIXTY_FOUR_BIT_LONG, but MSVC needs
> +// SIXTY_FOUR_BIT, because 'long' is 32-bit and only 'long long' is
> +// 64-bit. Since using 'long long' works fine on GCC too, just do that.
> +//
> +#define SIXTY_FOUR_BIT
> +#elif defined(MDE_CPU_IA32) || defined(MDE_CPU_ARM) || defined(MDE_CPU_EBC)
> +#define THIRTY_TWO_BIT
> +#endif
> +
> +//
> +// Map all va_xxxx elements to VA_xxx defined in MdePkg/Include/Base.h
> +//
> +#if !defined(__CC_ARM) // if va_list is not already defined
> +#define va_list VA_LIST
> +#define va_arg VA_ARG
> +#define va_start VA_START
> +#define va_end VA_END
> +#else // __CC_ARM
> +#define va_start(Marker, Parameter) __va_start(Marker, Parameter)
> +#define va_arg(Marker, TYPE) __va_arg(Marker, TYPE)
> +#define va_end(Marker) ((void)0)
> +#endif
> +
> +//
> +// Definitions for global constants used by CRT library routines
> +//
> +#define INT_MAX MAX_INT32 /* Maximum (signed) int value */
> +#define LONG_MAX 0X7FFFFFFFL /* max value for a long */
> +#define LONG_MIN (-LONG_MAX-1) /* min value for a long */
> +#define ULONG_MAX 0xFFFFFFFF /* Maximum unsigned long value */
> +#define CHAR_BIT 8 /* Number of bits in a char */
> +
> +// Maximum value for an object of type unsigned long long int.
> +#define ULLONG_MAX 0xFFFFFFFFFFFFFFFFULL // 2^64 - 1
> +// Maximum value for an object of type unsigned char.
> +#define UCHAR_MAX 255 // 2^8 - 1
> +
> +//
> +// Basic types mapping
> +//
> +typedef UINTN size_t;
> +typedef INTN ssize_t;
> +typedef INT32 time_t;
> +typedef UINT8 __uint8_t;
> +typedef UINT8 sa_family_t;
> +typedef UINT32 uid_t;
> +typedef UINT32 gid_t;
> +typedef INT32 int32_t;
> +typedef UINT32 uint32_t;
> +typedef UINT16 uint16_t;
> +typedef UINT8 uint8_t;
> +typedef enum {false, true} bool;
> +
> +//
> +// File operations are not required for EFI building,
> +// so FILE is mapped to VOID * to pass build
> +//
> +typedef VOID *FILE;
> +
> +//
> +// Global variables
> +//
> +extern int errno;
> +extern FILE *stderr;
> +
> +//
> +// Function prototypes of CRT Library routines
> +//
> +void *malloc (size_t);
> +void *realloc (void *, size_t);
> +void *calloc (size_t Num, size_t Size);
> +void free (void *);
> +void *memset (void *, int, size_t);
> +int memcmp (const void *, const void *, size_t);
> +int isdigit (int);
> +int isspace (int);
> +int tolower (int);
> +int isupper (int);
> +int isxdigit (int);
> +int isalnum (int);
> +void *memcpy (void *, const void *, size_t);
> +void *memset (void *, int, size_t);
> +void *memchr (const void *, int, size_t);
> +int memcmp (const void *, const void *, size_t);
> +void *memmove (void *, const void *, size_t);
> +int strcmp (const char *, const char *);
> +int strncmp (const char *, const char *, size_t);
> +char *strcpy (char *, const char *);
> +size_t strlen (const char *);
> +char *strcat (char *, const char *);
> +char *strchr (const char *, int);
> +int strcasecmp (const char *, const char *);
> +int strncasecmp (const char *, const char *, size_t);
> +char *strncpy (char *, size_t, const char *, size_t);
> +int strncmp (const char *, const char *, size_t);
> +char *strrchr (const char *, int);
> +unsigned long strtoul (const char *, char **, int);
> +char * strstr (const char *s1 , const char *s2);
> +long strtol (const char *, char **, int);
> +char *strerror (int);
> +size_t strspn (const char *, const char *);
> +char * strdup (const char *str);
> +char * strpbrk (const char *s1, const char *s2);
> +unsigned long long strtoull(const char * nptr, char ** endptr, int base);
> +long long strtoll (const char * nptr, char ** endptr, int base);
> +long strtol (const char * nptr, char ** endptr, int base);
> +double strtod (const char * __restrict nptr, char ** __restrict endptr);
> +size_t strcspn (const char *, const char *);
> +int printf (const char *, ...);
> +int sscanf (const char *, const char *, ...);
> +FILE *fopen (const char *, const char *);
> +size_t fread (void *, size_t, size_t, FILE *);
> +size_t fwrite (const void *, size_t, size_t, FILE *);
> +int fclose (FILE *);
> +int fprintf (FILE *, const char *, ...);
> +int fgetc (FILE * _File);
> +uid_t getuid (void);
> +uid_t geteuid (void);
> +gid_t getgid (void);
> +gid_t getegid (void);
> +void qsort (void *, size_t, size_t, int (*)(const void *, const void *));
> +char *getenv (const char *);
> +#if defined(__GNUC__) && (__GNUC__ >= 2)
> +void abort (void) __attribute__((__noreturn__));
> +#else
> +void abort (void);
> +#endif
> +int toupper (int);
> +int Digit2Val (int);
> +time_t time (time_t *);
> +
> +//
> +// Macros that directly map functions to BaseLib, BaseMemoryLib, and DebugLib functions
> +//
> +#define strcmp AsciiStrCmp
> +#define memcpy(dest,source,count) CopyMem(dest,source,(UINTN)(count))
> +#define memset(dest,ch,count) SetMem(dest,(UINTN)(count),(UINT8)(ch))
> +#define memchr(buf,ch,count) ScanMem8(buf,(UINTN)(count),(UINT8)ch)
> +#define memcmp(buf1,buf2,count) (int)(CompareMem(buf1,buf2,(UINTN)(count)))
> +#define memmove(dest,source,count) CopyMem(dest,source,(UINTN)(count))
> +#define strlen(str) (size_t)(AsciiStrnLenS(str,MAX_STRING_SIZE))
> +#define strcpy(strDest,strSource) AsciiStrCpyS(strDest,(strlen(strSource)+1),strSource)
> +#define strncpy(strDest,strSource,count) AsciiStrnCpyS(strDest,(UINTN)count,strSource,(UINTN)count)
> +#define strncpys(strDest, DestLen, strSource,count) AsciiStrnCpyS(strDest,DestLen,strSource,(UINTN)count)
> +#define strcat(strDest,strSource) AsciiStrCatS(strDest,(strlen(strSource)+strlen(strDest)+1),strSource)
> +#define strchr(str,ch) ScanMem8((VOID *)(str),AsciiStrSize(str),(UINT8)ch)
> +#define strncmp(string1,string2,count) (int)(AsciiStrnCmp(string1,string2,(UINTN)(count)))
> +#define strcasecmp(str1,str2) (int)AsciiStriCmp(str1,str2)
> +#define strstr(s1,s2) AsciiStrStr(s1,s2)
> +#define sprintf(buf,...) AsciiSPrint(buf,MAX_STRING_SIZE,__VA_ARGS__)
> +#define snprintf(buf,len,...) AsciiSPrint(buf,len,__VA_ARGS__)
> +#define vsnprintf(buf,len,format,marker) AsciiVSPrint((buf),(len),(format),(marker))
> +#define assert(expression) ASSERT(expression)
> +#define atoi(nptr) AsciiStrDecimalToUintn(nptr)
> +#define fabs(x) (((x) < 0.0)? (-x): (x))
> +#define offsetof(type,member) OFFSET_OF(type,member)
> +
> +#define EOF (-1)
> +
> +extern int errno;
> +
> +#define ERANGE 34 /* 34 Result too large */
> +
> +#endif
> diff --git a/RedfishPkg/Library/CrtLib/CrtLib.c b/RedfishPkg/Library/CrtLib/CrtLib.c
> new file mode 100644
> index 0000000000..1ff4023dbe
> --- /dev/null
> +++ b/RedfishPkg/Library/CrtLib/CrtLib.c
> @@ -0,0 +1,705 @@
> +/** @file
> + CRT wrapper functions for system call.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#include <Uefi.h>
> +#include <Library/CrtLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +
> +int errno = 0;
> +
> +/**
> + Determine if a particular character is an alphanumeric character
> + @return Returns 1 if c is an alphanumeric character, otherwise returns 0.
> +**/
> +int isalnum (int c)
> +{
> + //
> + // <alnum> ::= [0-9] | [a-z] | [A-Z]
> + //
> + return ((('0' <= (c)) && ((c) <= '9')) ||
> + (('a' <= (c)) && ((c) <= 'z')) ||
> + (('A' <= (c)) && ((c) <= 'Z')));
> +}
> +
> +/**
> + Determine if a particular character is a digital character
> +
> + @return Returns 1 if c is an digital character, otherwise returns 0.
> +**/
> +int isdchar (int c)
> +{
> + //
> + // [0-9] | [e +-.]
> + //
> + return ((('0' <= (c)) && ((c) <= '9')) ||
> + (c == 'e') || (c == 'E') ||
> + (c == '+') || (c == '-') ||
> + (c == '.'));
> +}
> +
> +/**
> + Determine if a particular character is a space character
> +
> + @return Returns 1 if c is a space character
> +**/
> +int isspace (int c)
> +{
> + //
> + // <space> ::= [ ]
> + //
> + return ((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) == '\n') || ((c) == '\v') || ((c) == '\f');
> +}
> +
> +/**
> + Allocates memory blocks
> +*/
> +void *malloc (size_t size)
> +{
> + return AllocatePool ((UINTN) size);
> +}
> +
> +/**
> + De-allocates or frees a memory block
> +*/
> +void free (void *ptr)
> +{
> + //
> + // In Standard C, free() handles a null pointer argument transparently. This
> + // is not true of FreePool() below, so protect it.
> + //
> + if (ptr != NULL) {
> + FreePool (ptr);
> + }
> +}
> +
> +/**
> + NetBSD Compatibility Function strdup creates a duplicate copy of a string.
> +
> + @return Returns the pointer to duplicated string.
> +**/
> +char * strdup(const char *str)
> +{
> + size_t len;
> + char *copy;
> +
> + len = strlen(str) + 1;
> + if ((copy = malloc(len)) == NULL)
> + return (NULL);
> + memcpy(copy, str, len);
> + return (copy);
> +}
> +
> +/** The toupper function converts a lowercase letter to a corresponding
> + uppercase letter.
> +
> + @param[in] c The character to be converted.
> +
> + @return If the argument is a character for which islower is true and
> + there are one or more corresponding characters, as specified by
> + the current locale, for which isupper is true, the toupper
> + function returns one of the corresponding characters (always the
> + same one for any given locale); otherwise, the argument is
> + returned unchanged.
> +**/
> +int
> +toupper(
> + IN int c
> + )
> +{
> + if ( (c >= 'a') && (c <= 'z') ) {
> + c = c - ('a' - 'A');
> + }
> + return c;
> +}
> +
> +/**
> + Digit to a value.
> +
> + @return Returns the value of digit.
> +**/
> +int
> +Digit2Val( int c)
> +{
> + if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))) { /* If c is one of [A-Za-z]... */
> + c = toupper(c) - 7; // Adjust so 'A' is ('9' + 1)
> + }
> + return c - '0'; // Value returned is between 0 and 35, inclusive.
> +}
> +
> +
> +/** The strtoll function converts the initial portion of the string pointed to
> + by nptr to long long int representation.
> +
> + See the description for strtol for more information.
> +
> + @return The strtoll function returns the converted value, if any. If no
> + conversion could be performed, zero is returned. If the correct
> + value is outside the range of representable values, LLONG_MIN or
> + LLONG_MAX is returned (according to the sign of the value, if any),
> + and the value of the macro ERANGE is stored in errno.
> +**/
> +long long
> +strtoll(const char * nptr, char ** endptr, int base)
> +{
> + const char *pEnd;
> + long long Result = 0;
> + long long Previous;
> + int temp;
> + BOOLEAN Negative = FALSE;
> +
> + pEnd = nptr;
> +
> + if((base < 0) || (base == 1) || (base > 36)) {
> + if(endptr != NULL) {
> + *endptr = NULL;
> + }
> + return 0;
> + }
> + // Skip leading spaces.
> + while(isspace(*nptr)) ++nptr;
> +
> + // Process Subject sequence: optional sign followed by digits.
> + if(*nptr == '+') {
> + Negative = FALSE;
> + ++nptr;
> + }
> + else if(*nptr == '-') {
> + Negative = TRUE;
> + ++nptr;
> + }
> +
> + if(*nptr == '0') { /* Might be Octal or Hex */
> + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> + if((base == 0) || (base == 16)) {
> + nptr += 2; /* Skip the "0X" */
> + base = 16; /* In case base was 0 */
> + }
> + }
> + else { /* Looks like Octal */
> + if((base == 0) || (base == 8)) {
> + ++nptr; /* Skip the leading "0" */
> + base = 8; /* In case base was 0 */
> + }
> + }
> + }
> + if(base == 0) { /* If still zero then must be decimal */
> + base = 10;
> + }
> + if(*nptr == '0') {
> + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> + pEnd = nptr;
> + }
> +
> + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> + Previous = Result;
> + Result = MultS64x64 (Result, base) + (long long int)temp;
> + if( Result <= Previous) { // Detect Overflow
> + if(Negative) {
> + Result = LLONG_MIN;
> + }
> + else {
> + Result = LLONG_MAX;
> + }
> + Negative = FALSE;
> + errno = ERANGE;
> + break;
> + }
> + pEnd = ++nptr;
> + }
> + if(Negative) {
> + Result = -Result;
> + }
> +
> + // Save pointer to final sequence
> + if(endptr != NULL) {
> + *endptr = (char *)pEnd;
> + }
> + return Result;
> +}
> +
> +/** The strtol, strtoll, strtoul, and strtoull functions convert the initial
> + portion of the string pointed to by nptr to long int, long long int,
> + unsigned long int, and unsigned long long int representation, respectively.
> + First, they decompose the input string into three parts: an initial,
> + possibly empty, sequence of white-space characters (as specified by the
> + isspace function), a subject sequence resembling an integer represented in
> + some radix determined by the value of base, and a final string of one or
> + more unrecognized characters, including the terminating null character of
> + the input string. Then, they attempt to convert the subject sequence to an
> + integer, and return the result.
> +
> + If the value of base is zero, the expected form of the subject sequence is
> + that of an integer constant, optionally preceded
> + by a plus or minus sign, but not including an integer suffix. If the value
> + of base is between 2 and 36 (inclusive), the expected form of the subject
> + sequence is a sequence of letters and digits representing an integer with
> + the radix specified by base, optionally preceded by a plus or minus sign,
> + but not including an integer suffix. The letters from a (or A) through z
> + (or Z) are ascribed the values 10 through 35; only letters and digits whose
> + ascribed values are less than that of base are permitted. If the value of
> + base is 16, the characters 0x or 0X may optionally precede the sequence of
> + letters and digits, following the sign if present.
> +
> + The subject sequence is defined as the longest initial subsequence of the
> + input string, starting with the first non-white-space character, that is of
> + the expected form. The subject sequence contains no characters if the input
> + string is empty or consists entirely of white space, or if the first
> + non-white-space character is other than a sign or a permissible letter or digit.
> +
> + If the subject sequence has the expected form and the value of base is
> + zero, the sequence of characters starting with the first digit is
> + interpreted as an integer constant. If the subject sequence has the
> + expected form and the value of base is between 2 and 36, it is used as the
> + base for conversion, ascribing to each letter its value as given above. If
> + the subject sequence begins with a minus sign, the value resulting from the
> + conversion is negated (in the return type). A pointer to the final string
> + is stored in the object pointed to by endptr, provided that endptr is
> + not a null pointer.
> +
> + In other than the "C" locale, additional locale-specific subject sequence
> + forms may be accepted.
> +
> + If the subject sequence is empty or does not have the expected form, no
> + conversion is performed; the value of nptr is stored in the object pointed
> + to by endptr, provided that endptr is not a null pointer.
> +
> + @return The strtol, strtoll, strtoul, and strtoull functions return the
> + converted value, if any. If no conversion could be performed, zero
> + is returned. If the correct value is outside the range of
> + representable values, LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX,
> + ULONG_MAX, or ULLONG_MAX is returned (according to the return type
> + and sign of the value, if any), and the value of the macro ERANGE
> + is stored in errno.
> +**/
> +long
> +strtol(const char * nptr, char ** endptr, int base)
> +{
> + const char *pEnd;
> + long Result = 0;
> + long Previous;
> + int temp;
> + BOOLEAN Negative = FALSE;
> +
> + pEnd = nptr;
> +
> + if((base < 0) || (base == 1) || (base > 36)) {
> + if(endptr != NULL) {
> + *endptr = NULL;
> + }
> + return 0;
> + }
> + // Skip leading spaces.
> + while(isspace(*nptr)) ++nptr;
> +
> + // Process Subject sequence: optional sign followed by digits.
> + if(*nptr == '+') {
> + Negative = FALSE;
> + ++nptr;
> + }
> + else if(*nptr == '-') {
> + Negative = TRUE;
> + ++nptr;
> + }
> +
> + if(*nptr == '0') { /* Might be Octal or Hex */
> + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> + if((base == 0) || (base == 16)) {
> + nptr += 2; /* Skip the "0X" */
> + base = 16; /* In case base was 0 */
> + }
> + }
> + else { /* Looks like Octal */
> + if((base == 0) || (base == 8)) {
> + ++nptr; /* Skip the leading "0" */
> + base = 8; /* In case base was 0 */
> + }
> + }
> + }
> + if(base == 0) { /* If still zero then must be decimal */
> + base = 10;
> + }
> + if(*nptr == '0') {
> + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> + pEnd = nptr;
> + }
> +
> + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> + Previous = Result;
> + Result = (Result * base) + (long int)temp;
> + if( Result <= Previous) { // Detect Overflow
> + if(Negative) {
> + Result = LONG_MIN;
> + }
> + else {
> + Result = LONG_MAX;
> + }
> + Negative = FALSE;
> + errno = ERANGE;
> + break;
> + }
> + pEnd = ++nptr;
> + }
> + if(Negative) {
> + Result = -Result;
> + }
> +
> + // Save pointer to final sequence
> + if(endptr != NULL) {
> + *endptr = (char *)pEnd;
> + }
> + return Result;
> +}
> +
> +/** The strtoull function converts the initial portion of the string pointed to
> + by nptr to unsigned long long int representation.
> +
> + See the description for strtol for more information.
> +
> + @return The strtoull function returns the converted value, if any. If no
> + conversion could be performed, zero is returned. If the correct
> + value is outside the range of representable values, ULLONG_MAX is
> + returned and the value of the macro ERANGE is stored in errno.
> +**/
> +unsigned long long
> +strtoull(const char * nptr, char ** endptr, int base)
> +{
> + const char *pEnd;
> + unsigned long long Result = 0;
> + unsigned long long Previous;
> + int temp;
> +
> + pEnd = nptr;
> +
> + if((base < 0) || (base == 1) || (base > 36)) {
> + if(endptr != NULL) {
> + *endptr = NULL;
> + }
> + return 0;
> + }
> + // Skip leading spaces.
> + while(isspace(*nptr)) ++nptr;
> +
> + // Process Subject sequence: optional + sign followed by digits.
> + if(*nptr == '+') {
> + ++nptr;
> + }
> +
> + if(*nptr == '0') { /* Might be Octal or Hex */
> + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> + if((base == 0) || (base == 16)) {
> + nptr += 2; /* Skip the "0X" */
> + base = 16; /* In case base was 0 */
> + }
> + }
> + else { /* Looks like Octal */
> + if((base == 0) || (base == 8)) {
> + ++nptr; /* Skip the leading "0" */
> + base = 8; /* In case base was 0 */
> + }
> + }
> + }
> + if(base == 0) { /* If still zero then must be decimal */
> + base = 10;
> + }
> + if(*nptr == '0') {
> + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> + pEnd = nptr;
> + }
> +
> + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> + Previous = Result;
> + Result = DivU64x32 (Result, base) + (unsigned long long)temp;
> + if( Result < Previous) { // If we overflowed
> + Result = ULLONG_MAX;
> + errno = ERANGE;
> + break;
> + }
> + pEnd = ++nptr;
> + }
> +
> + // Save pointer to final sequence
> + if(endptr != NULL) {
> + *endptr = (char *)pEnd;
> + }
> + return Result;
> +}
> +
> +/**
> + edk2 Jansson port does not support doubles, simply return 0.
> +
> + These conversion functions convert the initial portion of the string
> + pointed to by nptr to double, float, and long double representation,
> + respectively.
> +
> + The strtod(), strtof(), and strtold() functions return the converted
> + value, if any.
> +
> + If endptr is not NULL, a pointer to the character after the last charac-
> + ter used in the conversion is stored in the location referenced by
> + endptr.
> +
> + If no conversion is performed, zero is returned and the value of nptr is
> + stored in the location referenced by endptr.
> +
> + If the correct value would cause overflow, plus or minus HUGE_VAL,
> + HUGE_VALF, or HUGE_VALL is returned (according to the sign and type of
> + the return value), and ERANGE is stored in errno. If the correct value
> + would cause underflow, zero is returned and ERANGE is stored in errno.
> +
> + @return Return 0.
> +**/
> +double
> +strtod (const char * __restrict nptr, char ** __restrict endptr) {
> + if(endptr)
> + *endptr = (char *)(nptr + strlen(nptr));
> +
> + return (double)0;
> +}
> +
> +/**
> + Allocate and zero-initialize array.
> +**/
> +void *
> +calloc(size_t Num, size_t Size)
> +{
> + void *RetVal;
> + size_t NumSize;
> +
> + NumSize = Num * Size;
> + RetVal = NULL;
> + if (NumSize != 0) {
> + RetVal = malloc(NumSize);
> + if( RetVal != NULL) {
> + (VOID)ZeroMem( RetVal, NumSize);
> + }
> + }
> + DEBUG((DEBUG_POOL, "0x%p = calloc(%d, %d)\n", RetVal, Num, Size));
> +
> + return RetVal;
> +}
> +
> +//
> +// The arrays give the cumulative number of days up to the first of the
> +// month number used as the index (1 -> 12) for regular and leap years.
> +// The value at index 13 is for the whole year.
> +//
> +UINTN CumulativeDays[2][14] = {
> + {
> + 0,
> + 0,
> + 31,
> + 31 + 28,
> + 31 + 28 + 31,
> + 31 + 28 + 31 + 30,
> + 31 + 28 + 31 + 30 + 31,
> + 31 + 28 + 31 + 30 + 31 + 30,
> + 31 + 28 + 31 + 30 + 31 + 30 + 31,
> + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
> + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
> + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
> + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
> + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
> + },
> + {
> + 0,
> + 0,
> + 31,
> + 31 + 29,
> + 31 + 29 + 31,
> + 31 + 29 + 31 + 30,
> + 31 + 29 + 31 + 30 + 31,
> + 31 + 29 + 31 + 30 + 31 + 30,
> + 31 + 29 + 31 + 30 + 31 + 30 + 31,
> + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,
> + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
> + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
> + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
> + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
> + }
> +};
> +
> +#define IsLeap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
> +#define SECSPERMIN (60)
> +#define SECSPERHOUR (60 * 60)
> +#define SECSPERDAY (24 * SECSPERHOUR)
> +
> +/**
> + Get the system time as seconds elapsed since midnight, January 1, 1970.
> +**/
> +time_t time (time_t *timer)
> +{
> + EFI_TIME Time;
> + time_t CalTime;
> + UINTN Year;
> +
> + //
> + // Get the current time and date information
> + //
> + gRT->GetTime (&Time, NULL);
> +
> + //
> + // Years Handling
> + // UTime should now be set to 00:00:00 on Jan 1 of the current year.
> + //
> + for (Year = 1970, CalTime = 0; Year != Time.Year; Year++) {
> + CalTime = CalTime + (time_t)(CumulativeDays[IsLeap(Year)][13] * SECSPERDAY);
> + }
> +
> + //
> + // Add in number of seconds for current Month, Day, Hour, Minute, Seconds, and TimeZone adjustment
> + //
> + CalTime = CalTime +
> + (time_t)((Time.TimeZone != EFI_UNSPECIFIED_TIMEZONE) ? (Time.TimeZone * 60) : 0) +
> + (time_t)(CumulativeDays[IsLeap(Time.Year)][Time.Month] * SECSPERDAY) +
> + (time_t)(((Time.Day > 0) ? Time.Day - 1 : 0) * SECSPERDAY) +
> + (time_t)(Time.Hour * SECSPERHOUR) +
> + (time_t)(Time.Minute * 60) +
> + (time_t)Time.Second;
> +
> + if (timer != NULL) {
> + *timer = CalTime;
> + }
> +
> + return CalTime;
> +}
> +
> +typedef
> +int
> +(*SORT_COMPARE)(
> + IN VOID *Buffer1,
> + IN VOID *Buffer2
> + );
> +
> +/**
> + Duplicated from EDKII BaseSortLib for qsort() wrapper
> + @param[in, out] BufferToSort on call a Buffer of (possibly sorted) elements
> + on return a buffer of sorted elements
> + @param[in] Count the number of elements in the buffer to sort
> + @param[in] ElementSize Size of an element in bytes
> + @param[in] CompareFunction The function to call to perform the comparison
> + of any 2 elements
> + @param[in] Buffer Buffer of size ElementSize for use in swapping
> +**/
> +STATIC
> +VOID
> +QuickSortWorker (
> + IN OUT VOID *BufferToSort,
> + IN CONST UINTN Count,
> + IN CONST UINTN ElementSize,
> + IN SORT_COMPARE CompareFunction,
> + IN VOID *Buffer
> + )
> +{
> + VOID *Pivot;
> + UINTN LoopCount;
> + UINTN NextSwapLocation;
> +
> + ASSERT(BufferToSort != NULL);
> + ASSERT(CompareFunction != NULL);
> + ASSERT(Buffer != NULL);
> +
> + if (Count < 2 || ElementSize < 1) {
> + return;
> + }
> +
> + NextSwapLocation = 0;
> +
> + //
> + // Pick a pivot (we choose last element)
> + //
> + Pivot = ((UINT8 *)BufferToSort + ((Count - 1) * ElementSize));
> +
> + //
> + // Now get the pivot such that all on "left" are below it
> + // and everything "right" are above it
> + //
> + for (LoopCount = 0; LoopCount < Count - 1; LoopCount++)
> + {
> + //
> + // If the element is less than the pivot
> + //
> + if (CompareFunction ((VOID *)((UINT8 *)BufferToSort + ((LoopCount) * ElementSize)), Pivot) <= 0) {
> + //
> + // Swap
> + //
> + CopyMem (Buffer, (UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), ElementSize);
> + CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), (UINT8 *)BufferToSort + ((LoopCount) *
> ElementSize), ElementSize);
> + CopyMem ((UINT8 *)BufferToSort + ((LoopCount) * ElementSize), Buffer, ElementSize);
> +
> + //
> + // Increment NextSwapLocation
> + //
> + NextSwapLocation++;
> + }
> + }
> + //
> + // Swap pivot to it's final position (NextSwapLocaiton)
> + //
> + CopyMem (Buffer, Pivot, ElementSize);
> + CopyMem (Pivot, (UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), ElementSize);
> + CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), Buffer, ElementSize);
> +
> + //
> + // Now recurse on 2 paritial lists. Neither of these will have the 'pivot' element.
> + // IE list is sorted left half, pivot element, sorted right half...
> + //
> + QuickSortWorker (
> + BufferToSort,
> + NextSwapLocation,
> + ElementSize,
> + CompareFunction,
> + Buffer
> + );
> +
> + QuickSortWorker (
> + (UINT8 *)BufferToSort + (NextSwapLocation + 1) * ElementSize,
> + Count - NextSwapLocation - 1,
> + ElementSize,
> + CompareFunction,
> + Buffer
> + );
> +
> + return;
> +}
> +
> +/**
> + Performs a quick sort
> +**/
> +void qsort (void *base, size_t num, size_t width, int (*compare)(const void *, const void *))
> +{
> + VOID *Buffer;
> +
> + ASSERT (base != NULL);
> + ASSERT (compare != NULL);
> +
> + //
> + // Use CRT-style malloc to cover BS and RT memory allocation.
> + //
> + Buffer = malloc (width);
> + ASSERT (Buffer != NULL);
> +
> + //
> + // Re-use PerformQuickSort() function Implementation in EDKII BaseSortLib.
> + //
> + QuickSortWorker (base, (UINTN)num, (UINTN)width, (SORT_COMPARE)compare, Buffer);
> +
> + free (Buffer);
> + return;
> +}
> +
> +/**
> + Get character from stream, we don't support file operastion on edk2 JSON library.
> +
> + @return Returns the character currently pointed by the internal file position indicator of the specified stream
> +
> +**/
> +int fgetc(FILE * _File){
> + return 0;
> +}
> diff --git a/RedfishPkg/Library/CrtLib/CrtLib.inf b/RedfishPkg/Library/CrtLib/CrtLib.inf
> new file mode 100644
> index 0000000000..b514817cf4
> --- /dev/null
> +++ b/RedfishPkg/Library/CrtLib/CrtLib.inf
> @@ -0,0 +1,37 @@
> +## @file
> +# EDK2 C Runtime Library for opensource project.
> +#
> +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +# (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x0001001b
> + BASE_NAME = CrtLib
> + FILE_GUID = 8263B8AC-D021-425D-B337-3EC96F5DC19B
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = CrtLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION
> UEFI_DRIVER
> +
> +#
> +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64
> +#
> +
> +[Sources]
> + CrtLib.c
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> + MemoryAllocationLib
> + UefiRuntimeServicesTableLib
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + RedfishPkg/RedfishPkg.dec
> +
> +
> diff --git a/RedfishPkg/RedfishLibs.dsc.inc b/RedfishPkg/RedfishLibs.dsc.inc
> index d4c08e18ac..2a951bd8fa 100644
> --- a/RedfishPkg/RedfishLibs.dsc.inc
> +++ b/RedfishPkg/RedfishLibs.dsc.inc
> @@ -12,5 +12,6 @@
> ##
> !if $(REDFISH_ENABLE) == TRUE
> Ucs2Utf8Lib|RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> + CrtLib|RedfishPkg/Library/CrtLib/CrtLib.inf
> !endif
>
> diff --git a/RedfishPkg/RedfishPkg.ci.yaml b/RedfishPkg/RedfishPkg.ci.yaml
> index 20c297ad22..9895fdac99 100644
> --- a/RedfishPkg/RedfishPkg.ci.yaml
> +++ b/RedfishPkg/RedfishPkg.ci.yaml
> @@ -17,6 +17,25 @@
> ],
> ## Both file path and directory path are accepted.
> "IgnoreFiles": [
> + ## Below are files incorporated with open source which are
> + ## not edk2 coding standard compliant.
> + ##
> + ## EDK2 CRT library which is not edk2 coding
> + ## standard compliant.
> + ## C runtime library for EDKII JsonLib.
> + "Include/Crt/sys",
> + "Include/Crt/assert.h",
> + "Include/Crt/errno.h",
> + "Include/Crt/limits.h",
> + "Include/Crt/math.h",
> + "Include/Crt/stdarg.h",
> + "Include/Crt/stddef.h",
> + "Include/Crt/stdio.h",
> + "Include/Crt/stdlib.h",
> + "Include/Crt/string.h",
> + "Include/Crt/time.h",
> + "Include/Library/CrtLib.h",
> + "Library/CrtLib/CrtLib.c"
> ]
> },
> "CompilerPlugin": {
> diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec
> index aecc1f4a3a..2142b43640 100644
> --- a/RedfishPkg/RedfishPkg.dec
> +++ b/RedfishPkg/RedfishPkg.dec
> @@ -15,16 +15,24 @@
>
> [Includes]
> Include
> + Include/Crt # Header files for C RTL.
>
> [LibraryClasses]
> ## @libraryclass Platform Redfish Host Interface Library
> # Platform implementation-specific Redfish Host Interface.
> RedfishPlatformHostInterfaceLib|Include/Library/RedfishHostInterfaceLib.h
> +
> ## @libraryclass This library provides UCS2 to UTF8 manipulation
> # functions.
> #
> Ucs2Utf8Lib|Include/Library/BaseUcs2Utf8Lib.h
>
> + ## @libraryclass Provides the C runtime library functions
> + # CRT library is currently used by edk2 JsonLib (open source
> + # jansson project) and edk2 RedfishLib (libredfish open source
> + # project).
> + CrtLib|Include/Library/CrtLib.h
> +
> [Protocols]
> ## Include/Protocol/RedfishDiscover.h
> gEfiRedfishDiscoverProtocolGuid = { 0x5db12509, 0x4550, 0x4347, { 0x96, 0xb3, 0x73, 0xc0, 0xff, 0x6e, 0x86, 0x9f
> }}
> diff --git a/RedfishPkg/RedfishPkg.dsc b/RedfishPkg/RedfishPkg.dsc
> index 3639b620e6..aa1ccd5a95 100644
> --- a/RedfishPkg/RedfishPkg.dsc
> +++ b/RedfishPkg/RedfishPkg.dsc
> @@ -48,5 +48,6 @@
> [Components]
> RedfishPkg/Library/PlatformHostInterfaceLibNull/PlatformHostInterfaceLibNull.inf
> RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> + RedfishPkg/Library/CrtLib/CrtLib.inf
>
> !include RedfishPkg/Redfish.dsc.inc
> --
> 2.17.1
>
>
>
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime library
2020-12-14 17:06 ` [edk2-devel] " Michael D Kinney
@ 2020-12-16 6:52 ` Abner Chang
[not found] ` <16511FD303DAB3AC.18439@groups.io>
1 sibling, 0 replies; 15+ messages in thread
From: Abner Chang @ 2020-12-16 6:52 UTC (permalink / raw)
To: devel@edk2.groups.io, michael.d.kinney@intel.com
Cc: Leif Lindholm, Wang, Nickle (HPS SW), O'Hanley, Peter (EXL)
Done. Fix in next set of patches.
> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Michael D Kinney
> Sent: Tuesday, December 15, 2020 1:07 AM
> To: devel@edk2.groups.io; Chang, Abner (HPS SW/FW Technologist)
> <abner.chang@hpe.com>; Kinney, Michael D <michael.d.kinney@intel.com>
> Cc: Leif Lindholm <leif@nuviainc.com>; Wang, Nickle (HPS SW)
> <nickle.wang@hpe.com>; O'Hanley, Peter (EXL) <peter.ohanley@hpe.com>
> Subject: Re: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime library
>
> If CrtLib is a custom library to support use of jansson, then it should go into a
> private include directory in RedFishPkg, not the public include directory.
>
> The only include files that should go into the public include directory of a
> package are include files that are available to modules/libs implemented
> outside the RedFishPkg. Please review all the include files in RedFishPkg with
> this in mind.
>
> Mike
>
> > -----Original Message-----
> > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Abner
> > Chang
> > Sent: Sunday, December 13, 2020 7:53 PM
> > To: devel@edk2.groups.io
> > Cc: Leif Lindholm <leif@nuviainc.com>; Nickle Wang
> > <nickle.wang@hpe.com>; Peter O'Hanley <peter.ohanley@hpe.com>
> > Subject: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime
> > library
> >
> > CRT library is currently used by edk2 JsonLib (open source jansson
> > project) and edk2 RedfishLib (libredfish open source project). CrtLib
> > library provides the necessary C runtime equivalent edk2 functions for
> > open source projects.
> >
> > Signed-off-by: Abner Chang <abner.chang@hpe.com>
> >
> > Cc: Leif Lindholm <leif@nuviainc.com>
> > Cc: Nickle Wang <nickle.wang@hpe.com>
> > Cc: Peter O'Hanley <peter.ohanley@hpe.com>
> > ---
> > RedfishPkg/Include/Crt/assert.h | 16 +
> > RedfishPkg/Include/Crt/errno.h | 16 +
> > RedfishPkg/Include/Crt/limits.h | 16 +
> > RedfishPkg/Include/Crt/math.h | 16 +
> > RedfishPkg/Include/Crt/stdarg.h | 15 +
> > RedfishPkg/Include/Crt/stddef.h | 16 +
> > RedfishPkg/Include/Crt/stdio.h | 15 +
> > RedfishPkg/Include/Crt/stdlib.h | 16 +
> > RedfishPkg/Include/Crt/string.h | 16 +
> > RedfishPkg/Include/Crt/sys/time.h | 15 +
> > RedfishPkg/Include/Crt/sys/types.h | 15 +
> > RedfishPkg/Include/Crt/time.h | 15 +
> > RedfishPkg/Include/Library/CrtLib.h | 195 ++++++++
> > RedfishPkg/Library/CrtLib/CrtLib.c | 705
> +++++++++++++++++++++++++++
> > RedfishPkg/Library/CrtLib/CrtLib.inf | 37 ++
> > RedfishPkg/RedfishLibs.dsc.inc | 1 +
> > RedfishPkg/RedfishPkg.ci.yaml | 19 +
> > RedfishPkg/RedfishPkg.dec | 8 +
> > RedfishPkg/RedfishPkg.dsc | 1 +
> > 19 files changed, 1153 insertions(+)
> > create mode 100644 RedfishPkg/Include/Crt/assert.h create mode
> > 100644 RedfishPkg/Include/Crt/errno.h create mode 100644
> > RedfishPkg/Include/Crt/limits.h create mode 100644
> > RedfishPkg/Include/Crt/math.h create mode 100644
> > RedfishPkg/Include/Crt/stdarg.h create mode 100644
> > RedfishPkg/Include/Crt/stddef.h create mode 100644
> > RedfishPkg/Include/Crt/stdio.h create mode 100644
> > RedfishPkg/Include/Crt/stdlib.h create mode 100644
> > RedfishPkg/Include/Crt/string.h create mode 100644
> > RedfishPkg/Include/Crt/sys/time.h create mode 100644
> > RedfishPkg/Include/Crt/sys/types.h
> > create mode 100644 RedfishPkg/Include/Crt/time.h create mode 100644
> > RedfishPkg/Include/Library/CrtLib.h
> > create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.c
> > create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.inf
> >
> > diff --git a/RedfishPkg/Include/Crt/assert.h
> > b/RedfishPkg/Include/Crt/assert.h new file mode 100644 index
> > 0000000000..f9ab7ef9ca
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/assert.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_ASSERT_H_
> > +#define CRT_ASSERT_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/errno.h
> > b/RedfishPkg/Include/Crt/errno.h new file mode 100644 index
> > 0000000000..d30aee14de
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/errno.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_ERRNO_H_
> > +#define CRT_ERRNO_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/limits.h
> > b/RedfishPkg/Include/Crt/limits.h new file mode 100644 index
> > 0000000000..f3bdd33f2a
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/limits.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_LIMITS_H_
> > +#define CRT_LIMITS_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/math.h
> > b/RedfishPkg/Include/Crt/math.h new file mode 100644 index
> > 0000000000..984c0ccc21
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/math.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_MATH_H_
> > +#define CRT_MATH_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/stdarg.h
> > b/RedfishPkg/Include/Crt/stdarg.h new file mode 100644 index
> > 0000000000..d5a314ad3b
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/stdarg.h
> > @@ -0,0 +1,15 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#ifndef CRT_STDARG_H_
> > +#define CRT_STDARG_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/stddef.h
> > b/RedfishPkg/Include/Crt/stddef.h new file mode 100644 index
> > 0000000000..15a37bf50e
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/stddef.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_STDDEF_H_
> > +#define CRT_STDDEF_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/stdio.h
> > b/RedfishPkg/Include/Crt/stdio.h new file mode 100644 index
> > 0000000000..25e610be10
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/stdio.h
> > @@ -0,0 +1,15 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#ifndef CRT_STDIO_H_
> > +#define CRT_STDIO_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/stdlib.h
> > b/RedfishPkg/Include/Crt/stdlib.h new file mode 100644 index
> > 0000000000..5b3dd273c8
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/stdlib.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_STDLIB_H_
> > +#define CRT_STDLIB_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/string.h
> > b/RedfishPkg/Include/Crt/string.h new file mode 100644 index
> > 0000000000..f60b87ccd2
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/string.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_STRING_H_
> > +#define CRT_STRING_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/sys/time.h
> > b/RedfishPkg/Include/Crt/sys/time.h
> > new file mode 100644
> > index 0000000000..4ced176cda
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/sys/time.h
> > @@ -0,0 +1,15 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#ifndef CRT_SYS_TIME_H_
> > +#define CRT_SYS_TIME_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/sys/types.h
> > b/RedfishPkg/Include/Crt/sys/types.h
> > new file mode 100644
> > index 0000000000..c4f807214c
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/sys/types.h
> > @@ -0,0 +1,15 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#ifndef CRT_SYS_TYPES_H_
> > +#define CRT_SYS_TYPES_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/time.h
> > b/RedfishPkg/Include/Crt/time.h new file mode 100644 index
> > 0000000000..ca04ac8730
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/time.h
> > @@ -0,0 +1,15 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#ifndef CRT_TIME_H_
> > +#define CRT_TIME_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Library/CrtLib.h
> > b/RedfishPkg/Include/Library/CrtLib.h
> > new file mode 100644
> > index 0000000000..8c7484e75b
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Library/CrtLib.h
> > @@ -0,0 +1,195 @@
> > +/** @file
> > + CRT wrapper head functions for jansson system call.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_LIB_H_
> > +#define CRT_LIB_H_
> > +
> > +#include <Library/BaseLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/PrintLib.h>
> > +
> > +#define MAX_STRING_SIZE 0x10000000
> > +
> > +// Minimum value for an object of type long long int.
> > +#define LLONG_MIN MIN_INT64
> > +
> > +// Maximum value for an object of type long long int.
> > +#define LLONG_MAX MAX_INT64
> > +
> > +// We dont support double on edk2
> > +#define HUGE_VAL 0
> > +
> > +#if defined(MDE_CPU_X64) || defined(MDE_CPU_AARCH64) ||
> > +defined(MDE_CPU_IA64) || defined(MDE_CPU_RISCV64) // // With GCC
> we
> > +would normally use SIXTY_FOUR_BIT_LONG, but MSVC needs //
> > +SIXTY_FOUR_BIT, because 'long' is 32-bit and only 'long long' is //
> > +64-bit. Since using 'long long' works fine on GCC too, just do that.
> > +//
> > +#define SIXTY_FOUR_BIT
> > +#elif defined(MDE_CPU_IA32) || defined(MDE_CPU_ARM) ||
> > +defined(MDE_CPU_EBC) #define THIRTY_TWO_BIT #endif
> > +
> > +//
> > +// Map all va_xxxx elements to VA_xxx defined in
> > +MdePkg/Include/Base.h // #if !defined(__CC_ARM) // if va_list is not
> > +already defined
> > +#define va_list VA_LIST
> > +#define va_arg VA_ARG
> > +#define va_start VA_START
> > +#define va_end VA_END
> > +#else // __CC_ARM
> > +#define va_start(Marker, Parameter) __va_start(Marker, Parameter)
> > +#define va_arg(Marker, TYPE) __va_arg(Marker, TYPE)
> > +#define va_end(Marker) ((void)0)
> > +#endif
> > +
> > +//
> > +// Definitions for global constants used by CRT library routines //
> > +#define INT_MAX MAX_INT32 /* Maximum (signed) int value */
> > +#define LONG_MAX 0X7FFFFFFFL /* max value for a long */
> > +#define LONG_MIN (-LONG_MAX-1) /* min value for a long */
> > +#define ULONG_MAX 0xFFFFFFFF /* Maximum unsigned long value
> */
> > +#define CHAR_BIT 8 /* Number of bits in a char */
> > +
> > +// Maximum value for an object of type unsigned long long int.
> > +#define ULLONG_MAX 0xFFFFFFFFFFFFFFFFULL // 2^64 - 1 // Maximum
> > +value for an object of type unsigned char.
> > +#define UCHAR_MAX 255 // 2^8 - 1
> > +
> > +//
> > +// Basic types mapping
> > +//
> > +typedef UINTN size_t;
> > +typedef INTN ssize_t;
> > +typedef INT32 time_t;
> > +typedef UINT8 __uint8_t;
> > +typedef UINT8 sa_family_t;
> > +typedef UINT32 uid_t;
> > +typedef UINT32 gid_t;
> > +typedef INT32 int32_t;
> > +typedef UINT32 uint32_t;
> > +typedef UINT16 uint16_t;
> > +typedef UINT8 uint8_t;
> > +typedef enum {false, true} bool;
> > +
> > +//
> > +// File operations are not required for EFI building, // so FILE is
> > +mapped to VOID * to pass build // typedef VOID *FILE;
> > +
> > +//
> > +// Global variables
> > +//
> > +extern int errno;
> > +extern FILE *stderr;
> > +
> > +//
> > +// Function prototypes of CRT Library routines //
> > +void *malloc (size_t);
> > +void *realloc (void *, size_t);
> > +void *calloc (size_t Num, size_t Size);
> > +void free (void *);
> > +void *memset (void *, int, size_t);
> > +int memcmp (const void *, const void *, size_t);
> > +int isdigit (int);
> > +int isspace (int);
> > +int tolower (int);
> > +int isupper (int);
> > +int isxdigit (int);
> > +int isalnum (int);
> > +void *memcpy (void *, const void *, size_t);
> > +void *memset (void *, int, size_t);
> > +void *memchr (const void *, int, size_t);
> > +int memcmp (const void *, const void *, size_t);
> > +void *memmove (void *, const void *, size_t);
> > +int strcmp (const char *, const char *);
> > +int strncmp (const char *, const char *, size_t);
> > +char *strcpy (char *, const char *);
> > +size_t strlen (const char *);
> > +char *strcat (char *, const char *);
> > +char *strchr (const char *, int);
> > +int strcasecmp (const char *, const char *);
> > +int strncasecmp (const char *, const char *, size_t);
> > +char *strncpy (char *, size_t, const char *, size_t);
> > +int strncmp (const char *, const char *, size_t);
> > +char *strrchr (const char *, int);
> > +unsigned long strtoul (const char *, char **, int);
> > +char * strstr (const char *s1 , const char *s2);
> > +long strtol (const char *, char **, int);
> > +char *strerror (int);
> > +size_t strspn (const char *, const char *);
> > +char * strdup (const char *str);
> > +char * strpbrk (const char *s1, const char *s2);
> > +unsigned long long strtoull(const char * nptr, char ** endptr, int base);
> > +long long strtoll (const char * nptr, char ** endptr, int base);
> > +long strtol (const char * nptr, char ** endptr, int base);
> > +double strtod (const char * __restrict nptr, char ** __restrict
> endptr);
> > +size_t strcspn (const char *, const char *);
> > +int printf (const char *, ...);
> > +int sscanf (const char *, const char *, ...);
> > +FILE *fopen (const char *, const char *);
> > +size_t fread (void *, size_t, size_t, FILE *);
> > +size_t fwrite (const void *, size_t, size_t, FILE *);
> > +int fclose (FILE *);
> > +int fprintf (FILE *, const char *, ...);
> > +int fgetc (FILE * _File);
> > +uid_t getuid (void);
> > +uid_t geteuid (void);
> > +gid_t getgid (void);
> > +gid_t getegid (void);
> > +void qsort (void *, size_t, size_t, int (*)(const void *, const void
> *));
> > +char *getenv (const char *);
> > +#if defined(__GNUC__) && (__GNUC__ >= 2)
> > +void abort (void) __attribute__((__noreturn__));
> > +#else
> > +void abort (void);
> > +#endif
> > +int toupper (int);
> > +int Digit2Val (int);
> > +time_t time (time_t *);
> > +
> > +//
> > +// Macros that directly map functions to BaseLib, BaseMemoryLib, and
> > +DebugLib functions //
> > +#define strcmp AsciiStrCmp
> > +#define memcpy(dest,source,count)
> CopyMem(dest,source,(UINTN)(count))
> > +#define memset(dest,ch,count)
> SetMem(dest,(UINTN)(count),(UINT8)(ch))
> > +#define memchr(buf,ch,count)
> ScanMem8(buf,(UINTN)(count),(UINT8)ch)
> > +#define memcmp(buf1,buf2,count)
> (int)(CompareMem(buf1,buf2,(UINTN)(count)))
> > +#define memmove(dest,source,count)
> CopyMem(dest,source,(UINTN)(count))
> > +#define strlen(str)
> (size_t)(AsciiStrnLenS(str,MAX_STRING_SIZE))
> > +#define strcpy(strDest,strSource)
> AsciiStrCpyS(strDest,(strlen(strSource)+1),strSource)
> > +#define strncpy(strDest,strSource,count)
> > +AsciiStrnCpyS(strDest,(UINTN)count,strSource,(UINTN)count)
> > +#define strncpys(strDest, DestLen, strSource,count)
> AsciiStrnCpyS(strDest,DestLen,strSource,(UINTN)count)
> > +#define strcat(strDest,strSource)
> AsciiStrCatS(strDest,(strlen(strSource)+strlen(strDest)+1),strSource)
> > +#define strchr(str,ch) ScanMem8((VOID
> *)(str),AsciiStrSize(str),(UINT8)ch)
> > +#define strncmp(string1,string2,count)
> (int)(AsciiStrnCmp(string1,string2,(UINTN)(count)))
> > +#define strcasecmp(str1,str2) (int)AsciiStriCmp(str1,str2)
> > +#define strstr(s1,s2) AsciiStrStr(s1,s2)
> > +#define sprintf(buf,...)
> AsciiSPrint(buf,MAX_STRING_SIZE,__VA_ARGS__)
> > +#define snprintf(buf,len,...) AsciiSPrint(buf,len,__VA_ARGS__)
> > +#define vsnprintf(buf,len,format,marker)
> AsciiVSPrint((buf),(len),(format),(marker))
> > +#define assert(expression) ASSERT(expression)
> > +#define atoi(nptr) AsciiStrDecimalToUintn(nptr)
> > +#define fabs(x) (((x) < 0.0)? (-x): (x))
> > +#define offsetof(type,member) OFFSET_OF(type,member)
> > +
> > +#define EOF (-1)
> > +
> > +extern int errno;
> > +
> > +#define ERANGE 34 /* 34 Result too large */
> > +
> > +#endif
> > diff --git a/RedfishPkg/Library/CrtLib/CrtLib.c
> > b/RedfishPkg/Library/CrtLib/CrtLib.c
> > new file mode 100644
> > index 0000000000..1ff4023dbe
> > --- /dev/null
> > +++ b/RedfishPkg/Library/CrtLib/CrtLib.c
> > @@ -0,0 +1,705 @@
> > +/** @file
> > + CRT wrapper functions for system call.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#include <Uefi.h>
> > +#include <Library/CrtLib.h>
> > +#include <Library/MemoryAllocationLib.h> #include
> > +<Library/UefiRuntimeServicesTableLib.h>
> > +
> > +int errno = 0;
> > +
> > +/**
> > + Determine if a particular character is an alphanumeric character
> > + @return Returns 1 if c is an alphanumeric character, otherwise returns 0.
> > +**/
> > +int isalnum (int c)
> > +{
> > + //
> > + // <alnum> ::= [0-9] | [a-z] | [A-Z]
> > + //
> > + return ((('0' <= (c)) && ((c) <= '9')) ||
> > + (('a' <= (c)) && ((c) <= 'z')) ||
> > + (('A' <= (c)) && ((c) <= 'Z'))); }
> > +
> > +/**
> > + Determine if a particular character is a digital character
> > +
> > + @return Returns 1 if c is an digital character, otherwise returns 0.
> > +**/
> > +int isdchar (int c)
> > +{
> > + //
> > + // [0-9] | [e +-.]
> > + //
> > + return ((('0' <= (c)) && ((c) <= '9')) ||
> > + (c == 'e') || (c == 'E') ||
> > + (c == '+') || (c == '-') ||
> > + (c == '.'));
> > +}
> > +
> > +/**
> > + Determine if a particular character is a space character
> > +
> > + @return Returns 1 if c is a space character **/ int isspace (int
> > +c) {
> > + //
> > + // <space> ::= [ ]
> > + //
> > + return ((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) ==
> > +'\n') || ((c) == '\v') || ((c) == '\f'); }
> > +
> > +/**
> > + Allocates memory blocks
> > +*/
> > +void *malloc (size_t size)
> > +{
> > + return AllocatePool ((UINTN) size); }
> > +
> > +/**
> > + De-allocates or frees a memory block */ void free (void *ptr) {
> > + //
> > + // In Standard C, free() handles a null pointer argument
> > +transparently. This
> > + // is not true of FreePool() below, so protect it.
> > + //
> > + if (ptr != NULL) {
> > + FreePool (ptr);
> > + }
> > +}
> > +
> > +/**
> > + NetBSD Compatibility Function strdup creates a duplicate copy of a string.
> > +
> > + @return Returns the pointer to duplicated string.
> > +**/
> > +char * strdup(const char *str)
> > +{
> > + size_t len;
> > + char *copy;
> > +
> > + len = strlen(str) + 1;
> > + if ((copy = malloc(len)) == NULL)
> > + return (NULL);
> > + memcpy(copy, str, len);
> > + return (copy);
> > +}
> > +
> > +/** The toupper function converts a lowercase letter to a corresponding
> > + uppercase letter.
> > +
> > + @param[in] c The character to be converted.
> > +
> > + @return If the argument is a character for which islower is true and
> > + there are one or more corresponding characters, as specified by
> > + the current locale, for which isupper is true, the toupper
> > + function returns one of the corresponding characters (always the
> > + same one for any given locale); otherwise, the argument is
> > + returned unchanged.
> > +**/
> > +int
> > +toupper(
> > + IN int c
> > + )
> > +{
> > + if ( (c >= 'a') && (c <= 'z') ) {
> > + c = c - ('a' - 'A');
> > + }
> > + return c;
> > +}
> > +
> > +/**
> > + Digit to a value.
> > +
> > + @return Returns the value of digit.
> > +**/
> > +int
> > +Digit2Val( int c)
> > +{
> > + if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))) { /* If c is one of [A-
> Za-z]... */
> > + c = toupper(c) - 7; // Adjust so 'A' is ('9' + 1)
> > + }
> > + return c - '0'; // Value returned is between 0 and 35, inclusive.
> > +}
> > +
> > +
> > +/** The strtoll function converts the initial portion of the string pointed to
> > + by nptr to long long int representation.
> > +
> > + See the description for strtol for more information.
> > +
> > + @return The strtoll function returns the converted value, if any. If no
> > + conversion could be performed, zero is returned. If the correct
> > + value is outside the range of representable values, LLONG_MIN or
> > + LLONG_MAX is returned (according to the sign of the value, if any),
> > + and the value of the macro ERANGE is stored in errno.
> > +**/
> > +long long
> > +strtoll(const char * nptr, char ** endptr, int base) {
> > + const char *pEnd;
> > + long long Result = 0;
> > + long long Previous;
> > + int temp;
> > + BOOLEAN Negative = FALSE;
> > +
> > + pEnd = nptr;
> > +
> > + if((base < 0) || (base == 1) || (base > 36)) {
> > + if(endptr != NULL) {
> > + *endptr = NULL;
> > + }
> > + return 0;
> > + }
> > + // Skip leading spaces.
> > + while(isspace(*nptr)) ++nptr;
> > +
> > + // Process Subject sequence: optional sign followed by digits.
> > + if(*nptr == '+') {
> > + Negative = FALSE;
> > + ++nptr;
> > + }
> > + else if(*nptr == '-') {
> > + Negative = TRUE;
> > + ++nptr;
> > + }
> > +
> > + if(*nptr == '0') { /* Might be Octal or Hex */
> > + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> > + if((base == 0) || (base == 16)) {
> > + nptr += 2; /* Skip the "0X" */
> > + base = 16; /* In case base was 0 */
> > + }
> > + }
> > + else { /* Looks like Octal */
> > + if((base == 0) || (base == 8)) {
> > + ++nptr; /* Skip the leading "0" */
> > + base = 8; /* In case base was 0 */
> > + }
> > + }
> > + }
> > + if(base == 0) { /* If still zero then must be decimal */
> > + base = 10;
> > + }
> > + if(*nptr == '0') {
> > + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> > + pEnd = nptr;
> > + }
> > +
> > + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> > + Previous = Result;
> > + Result = MultS64x64 (Result, base) + (long long int)temp;
> > + if( Result <= Previous) { // Detect Overflow
> > + if(Negative) {
> > + Result = LLONG_MIN;
> > + }
> > + else {
> > + Result = LLONG_MAX;
> > + }
> > + Negative = FALSE;
> > + errno = ERANGE;
> > + break;
> > + }
> > + pEnd = ++nptr;
> > + }
> > + if(Negative) {
> > + Result = -Result;
> > + }
> > +
> > + // Save pointer to final sequence
> > + if(endptr != NULL) {
> > + *endptr = (char *)pEnd;
> > + }
> > + return Result;
> > +}
> > +
> > +/** The strtol, strtoll, strtoul, and strtoull functions convert the initial
> > + portion of the string pointed to by nptr to long int, long long int,
> > + unsigned long int, and unsigned long long int representation,
> respectively.
> > + First, they decompose the input string into three parts: an initial,
> > + possibly empty, sequence of white-space characters (as specified by
> the
> > + isspace function), a subject sequence resembling an integer
> represented in
> > + some radix determined by the value of base, and a final string of one or
> > + more unrecognized characters, including the terminating null character
> of
> > + the input string. Then, they attempt to convert the subject sequence to
> an
> > + integer, and return the result.
> > +
> > + If the value of base is zero, the expected form of the subject sequence
> is
> > + that of an integer constant, optionally preceded
> > + by a plus or minus sign, but not including an integer suffix. If the value
> > + of base is between 2 and 36 (inclusive), the expected form of the
> subject
> > + sequence is a sequence of letters and digits representing an integer
> with
> > + the radix specified by base, optionally preceded by a plus or minus sign,
> > + but not including an integer suffix. The letters from a (or A) through z
> > + (or Z) are ascribed the values 10 through 35; only letters and digits
> whose
> > + ascribed values are less than that of base are permitted. If the value of
> > + base is 16, the characters 0x or 0X may optionally precede the sequence
> of
> > + letters and digits, following the sign if present.
> > +
> > + The subject sequence is defined as the longest initial subsequence of
> the
> > + input string, starting with the first non-white-space character, that is of
> > + the expected form. The subject sequence contains no characters if the
> input
> > + string is empty or consists entirely of white space, or if the first
> > + non-white-space character is other than a sign or a permissible letter or
> digit.
> > +
> > + If the subject sequence has the expected form and the value of base is
> > + zero, the sequence of characters starting with the first digit is
> > + interpreted as an integer constant. If the subject sequence has the
> > + expected form and the value of base is between 2 and 36, it is used as
> the
> > + base for conversion, ascribing to each letter its value as given above. If
> > + the subject sequence begins with a minus sign, the value resulting from
> the
> > + conversion is negated (in the return type). A pointer to the final string
> > + is stored in the object pointed to by endptr, provided that endptr is
> > + not a null pointer.
> > +
> > + In other than the "C" locale, additional locale-specific subject sequence
> > + forms may be accepted.
> > +
> > + If the subject sequence is empty or does not have the expected form,
> no
> > + conversion is performed; the value of nptr is stored in the object
> pointed
> > + to by endptr, provided that endptr is not a null pointer.
> > +
> > + @return The strtol, strtoll, strtoul, and strtoull functions return the
> > + converted value, if any. If no conversion could be performed, zero
> > + is returned. If the correct value is outside the range of
> > + representable values, LONG_MIN, LONG_MAX, LLONG_MIN,
> LLONG_MAX,
> > + ULONG_MAX, or ULLONG_MAX is returned (according to the return
> type
> > + and sign of the value, if any), and the value of the macro ERANGE
> > + is stored in errno.
> > +**/
> > +long
> > +strtol(const char * nptr, char ** endptr, int base) {
> > + const char *pEnd;
> > + long Result = 0;
> > + long Previous;
> > + int temp;
> > + BOOLEAN Negative = FALSE;
> > +
> > + pEnd = nptr;
> > +
> > + if((base < 0) || (base == 1) || (base > 36)) {
> > + if(endptr != NULL) {
> > + *endptr = NULL;
> > + }
> > + return 0;
> > + }
> > + // Skip leading spaces.
> > + while(isspace(*nptr)) ++nptr;
> > +
> > + // Process Subject sequence: optional sign followed by digits.
> > + if(*nptr == '+') {
> > + Negative = FALSE;
> > + ++nptr;
> > + }
> > + else if(*nptr == '-') {
> > + Negative = TRUE;
> > + ++nptr;
> > + }
> > +
> > + if(*nptr == '0') { /* Might be Octal or Hex */
> > + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> > + if((base == 0) || (base == 16)) {
> > + nptr += 2; /* Skip the "0X" */
> > + base = 16; /* In case base was 0 */
> > + }
> > + }
> > + else { /* Looks like Octal */
> > + if((base == 0) || (base == 8)) {
> > + ++nptr; /* Skip the leading "0" */
> > + base = 8; /* In case base was 0 */
> > + }
> > + }
> > + }
> > + if(base == 0) { /* If still zero then must be decimal */
> > + base = 10;
> > + }
> > + if(*nptr == '0') {
> > + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> > + pEnd = nptr;
> > + }
> > +
> > + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> > + Previous = Result;
> > + Result = (Result * base) + (long int)temp;
> > + if( Result <= Previous) { // Detect Overflow
> > + if(Negative) {
> > + Result = LONG_MIN;
> > + }
> > + else {
> > + Result = LONG_MAX;
> > + }
> > + Negative = FALSE;
> > + errno = ERANGE;
> > + break;
> > + }
> > + pEnd = ++nptr;
> > + }
> > + if(Negative) {
> > + Result = -Result;
> > + }
> > +
> > + // Save pointer to final sequence
> > + if(endptr != NULL) {
> > + *endptr = (char *)pEnd;
> > + }
> > + return Result;
> > +}
> > +
> > +/** The strtoull function converts the initial portion of the string pointed
> to
> > + by nptr to unsigned long long int representation.
> > +
> > + See the description for strtol for more information.
> > +
> > + @return The strtoull function returns the converted value, if any. If no
> > + conversion could be performed, zero is returned. If the correct
> > + value is outside the range of representable values, ULLONG_MAX is
> > + returned and the value of the macro ERANGE is stored in errno.
> > +**/
> > +unsigned long long
> > +strtoull(const char * nptr, char ** endptr, int base) {
> > + const char *pEnd;
> > + unsigned long long Result = 0;
> > + unsigned long long Previous;
> > + int temp;
> > +
> > + pEnd = nptr;
> > +
> > + if((base < 0) || (base == 1) || (base > 36)) {
> > + if(endptr != NULL) {
> > + *endptr = NULL;
> > + }
> > + return 0;
> > + }
> > + // Skip leading spaces.
> > + while(isspace(*nptr)) ++nptr;
> > +
> > + // Process Subject sequence: optional + sign followed by digits.
> > + if(*nptr == '+') {
> > + ++nptr;
> > + }
> > +
> > + if(*nptr == '0') { /* Might be Octal or Hex */
> > + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> > + if((base == 0) || (base == 16)) {
> > + nptr += 2; /* Skip the "0X" */
> > + base = 16; /* In case base was 0 */
> > + }
> > + }
> > + else { /* Looks like Octal */
> > + if((base == 0) || (base == 8)) {
> > + ++nptr; /* Skip the leading "0" */
> > + base = 8; /* In case base was 0 */
> > + }
> > + }
> > + }
> > + if(base == 0) { /* If still zero then must be decimal */
> > + base = 10;
> > + }
> > + if(*nptr == '0') {
> > + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> > + pEnd = nptr;
> > + }
> > +
> > + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> > + Previous = Result;
> > + Result = DivU64x32 (Result, base) + (unsigned long long)temp;
> > + if( Result < Previous) { // If we overflowed
> > + Result = ULLONG_MAX;
> > + errno = ERANGE;
> > + break;
> > + }
> > + pEnd = ++nptr;
> > + }
> > +
> > + // Save pointer to final sequence
> > + if(endptr != NULL) {
> > + *endptr = (char *)pEnd;
> > + }
> > + return Result;
> > +}
> > +
> > +/**
> > + edk2 Jansson port does not support doubles, simply return 0.
> > +
> > + These conversion functions convert the initial portion of the
> > + string pointed to by nptr to double, float, and long double
> > + representation, respectively.
> > +
> > + The strtod(), strtof(), and strtold() functions return the
> > + converted value, if any.
> > +
> > + If endptr is not NULL, a pointer to the character after the last
> > + charac- ter used in the conversion is stored in the location
> > + referenced by endptr.
> > +
> > + If no conversion is performed, zero is returned and the value of
> > + nptr is stored in the location referenced by endptr.
> > +
> > + If the correct value would cause overflow, plus or minus HUGE_VAL,
> > + HUGE_VALF, or HUGE_VALL is returned (according to the sign and type
> > + of the return value), and ERANGE is stored in errno. If the
> > + correct value would cause underflow, zero is returned and ERANGE is
> stored in errno.
> > +
> > + @return Return 0.
> > +**/
> > +double
> > +strtod (const char * __restrict nptr, char ** __restrict endptr) {
> > + if(endptr)
> > + *endptr = (char *)(nptr + strlen(nptr));
> > +
> > + return (double)0;
> > +}
> > +
> > +/**
> > + Allocate and zero-initialize array.
> > +**/
> > +void *
> > +calloc(size_t Num, size_t Size)
> > +{
> > + void *RetVal;
> > + size_t NumSize;
> > +
> > + NumSize = Num * Size;
> > + RetVal = NULL;
> > + if (NumSize != 0) {
> > + RetVal = malloc(NumSize);
> > + if( RetVal != NULL) {
> > + (VOID)ZeroMem( RetVal, NumSize);
> > + }
> > + }
> > + DEBUG((DEBUG_POOL, "0x%p = calloc(%d, %d)\n", RetVal, Num, Size));
> > +
> > + return RetVal;
> > +}
> > +
> > +//
> > +// The arrays give the cumulative number of days up to the first of
> > +the // month number used as the index (1 -> 12) for regular and leap
> years.
> > +// The value at index 13 is for the whole year.
> > +//
> > +UINTN CumulativeDays[2][14] = {
> > + {
> > + 0,
> > + 0,
> > + 31,
> > + 31 + 28,
> > + 31 + 28 + 31,
> > + 31 + 28 + 31 + 30,
> > + 31 + 28 + 31 + 30 + 31,
> > + 31 + 28 + 31 + 30 + 31 + 30,
> > + 31 + 28 + 31 + 30 + 31 + 30 + 31,
> > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
> > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
> > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
> > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
> > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
> > + },
> > + {
> > + 0,
> > + 0,
> > + 31,
> > + 31 + 29,
> > + 31 + 29 + 31,
> > + 31 + 29 + 31 + 30,
> > + 31 + 29 + 31 + 30 + 31,
> > + 31 + 29 + 31 + 30 + 31 + 30,
> > + 31 + 29 + 31 + 30 + 31 + 30 + 31,
> > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,
> > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
> > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
> > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
> > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
> > + }
> > +};
> > +
> > +#define IsLeap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
> > +#define SECSPERMIN (60)
> > +#define SECSPERHOUR (60 * 60)
> > +#define SECSPERDAY (24 * SECSPERHOUR)
> > +
> > +/**
> > + Get the system time as seconds elapsed since midnight, January 1, 1970.
> > +**/
> > +time_t time (time_t *timer)
> > +{
> > + EFI_TIME Time;
> > + time_t CalTime;
> > + UINTN Year;
> > +
> > + //
> > + // Get the current time and date information // gRT->GetTime
> > + (&Time, NULL);
> > +
> > + //
> > + // Years Handling
> > + // UTime should now be set to 00:00:00 on Jan 1 of the current year.
> > + //
> > + for (Year = 1970, CalTime = 0; Year != Time.Year; Year++) {
> > + CalTime = CalTime + (time_t)(CumulativeDays[IsLeap(Year)][13] *
> > + SECSPERDAY); }
> > +
> > + //
> > + // Add in number of seconds for current Month, Day, Hour, Minute,
> > + Seconds, and TimeZone adjustment // CalTime = CalTime +
> > + (time_t)((Time.TimeZone != EFI_UNSPECIFIED_TIMEZONE) ?
> (Time.TimeZone * 60) : 0) +
> > + (time_t)(CumulativeDays[IsLeap(Time.Year)][Time.Month] *
> SECSPERDAY) +
> > + (time_t)(((Time.Day > 0) ? Time.Day - 1 : 0) * SECSPERDAY) +
> > + (time_t)(Time.Hour * SECSPERHOUR) +
> > + (time_t)(Time.Minute * 60) +
> > + (time_t)Time.Second;
> > +
> > + if (timer != NULL) {
> > + *timer = CalTime;
> > + }
> > +
> > + return CalTime;
> > +}
> > +
> > +typedef
> > +int
> > +(*SORT_COMPARE)(
> > + IN VOID *Buffer1,
> > + IN VOID *Buffer2
> > + );
> > +
> > +/**
> > + Duplicated from EDKII BaseSortLib for qsort() wrapper
> > + @param[in, out] BufferToSort on call a Buffer of (possibly sorted)
> elements
> > + on return a buffer of sorted elements
> > + @param[in] Count the number of elements in the buffer to sort
> > + @param[in] ElementSize Size of an element in bytes
> > + @param[in] CompareFunction The function to call to perform the
> comparison
> > + of any 2 elements
> > + @param[in] Buffer Buffer of size ElementSize for use in swapping
> > +**/
> > +STATIC
> > +VOID
> > +QuickSortWorker (
> > + IN OUT VOID *BufferToSort,
> > + IN CONST UINTN Count,
> > + IN CONST UINTN ElementSize,
> > + IN SORT_COMPARE CompareFunction,
> > + IN VOID *Buffer
> > + )
> > +{
> > + VOID *Pivot;
> > + UINTN LoopCount;
> > + UINTN NextSwapLocation;
> > +
> > + ASSERT(BufferToSort != NULL);
> > + ASSERT(CompareFunction != NULL);
> > + ASSERT(Buffer != NULL);
> > +
> > + if (Count < 2 || ElementSize < 1) {
> > + return;
> > + }
> > +
> > + NextSwapLocation = 0;
> > +
> > + //
> > + // Pick a pivot (we choose last element) // Pivot = ((UINT8
> > + *)BufferToSort + ((Count - 1) * ElementSize));
> > +
> > + //
> > + // Now get the pivot such that all on "left" are below it // and
> > + everything "right" are above it // for (LoopCount = 0; LoopCount <
> > + Count - 1; LoopCount++) {
> > + //
> > + // If the element is less than the pivot
> > + //
> > + if (CompareFunction ((VOID *)((UINT8 *)BufferToSort + ((LoopCount) *
> ElementSize)), Pivot) <= 0) {
> > + //
> > + // Swap
> > + //
> > + CopyMem (Buffer, (UINT8 *)BufferToSort + (NextSwapLocation *
> ElementSize), ElementSize);
> > + CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation *
> > + ElementSize), (UINT8 *)BufferToSort + ((LoopCount) *
> > ElementSize), ElementSize);
> > + CopyMem ((UINT8 *)BufferToSort + ((LoopCount) * ElementSize),
> > + Buffer, ElementSize);
> > +
> > + //
> > + // Increment NextSwapLocation
> > + //
> > + NextSwapLocation++;
> > + }
> > + }
> > + //
> > + // Swap pivot to it's final position (NextSwapLocaiton) //
> > + CopyMem (Buffer, Pivot, ElementSize); CopyMem (Pivot, (UINT8
> > + *)BufferToSort + (NextSwapLocation * ElementSize), ElementSize);
> > + CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation * ElementSize),
> > + Buffer, ElementSize);
> > +
> > + //
> > + // Now recurse on 2 paritial lists. Neither of these will have the 'pivot'
> element.
> > + // IE list is sorted left half, pivot element, sorted right half...
> > + //
> > + QuickSortWorker (
> > + BufferToSort,
> > + NextSwapLocation,
> > + ElementSize,
> > + CompareFunction,
> > + Buffer
> > + );
> > +
> > + QuickSortWorker (
> > + (UINT8 *)BufferToSort + (NextSwapLocation + 1) * ElementSize,
> > + Count - NextSwapLocation - 1,
> > + ElementSize,
> > + CompareFunction,
> > + Buffer
> > + );
> > +
> > + return;
> > +}
> > +
> > +/**
> > + Performs a quick sort
> > +**/
> > +void qsort (void *base, size_t num, size_t width, int
> > +(*compare)(const void *, const void *)) {
> > + VOID *Buffer;
> > +
> > + ASSERT (base != NULL);
> > + ASSERT (compare != NULL);
> > +
> > + //
> > + // Use CRT-style malloc to cover BS and RT memory allocation.
> > + //
> > + Buffer = malloc (width);
> > + ASSERT (Buffer != NULL);
> > +
> > + //
> > + // Re-use PerformQuickSort() function Implementation in EDKII
> BaseSortLib.
> > + //
> > + QuickSortWorker (base, (UINTN)num, (UINTN)width,
> > + (SORT_COMPARE)compare, Buffer);
> > +
> > + free (Buffer);
> > + return;
> > +}
> > +
> > +/**
> > + Get character from stream, we don't support file operastion on edk2
> JSON library.
> > +
> > + @return Returns the character currently pointed by the internal
> > + file position indicator of the specified stream
> > +
> > +**/
> > +int fgetc(FILE * _File){
> > + return 0;
> > +}
> > diff --git a/RedfishPkg/Library/CrtLib/CrtLib.inf
> > b/RedfishPkg/Library/CrtLib/CrtLib.inf
> > new file mode 100644
> > index 0000000000..b514817cf4
> > --- /dev/null
> > +++ b/RedfishPkg/Library/CrtLib/CrtLib.inf
> > @@ -0,0 +1,37 @@
> > +## @file
> > +# EDK2 C Runtime Library for opensource project.
> > +#
> > +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> #
> > +(C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR> #
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > + INF_VERSION = 0x0001001b
> > + BASE_NAME = CrtLib
> > + FILE_GUID = 8263B8AC-D021-425D-B337-3EC96F5DC19B
> > + MODULE_TYPE = DXE_DRIVER
> > + VERSION_STRING = 1.0
> > + LIBRARY_CLASS = CrtLib|DXE_CORE DXE_DRIVER
> DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION
> > UEFI_DRIVER
> > +
> > +#
> > +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64
> > +#
> > +
> > +[Sources]
> > + CrtLib.c
> > +
> > +[LibraryClasses]
> > + BaseLib
> > + DebugLib
> > + MemoryAllocationLib
> > + UefiRuntimeServicesTableLib
> > +
> > +[Packages]
> > + MdePkg/MdePkg.dec
> > + MdeModulePkg/MdeModulePkg.dec
> > + RedfishPkg/RedfishPkg.dec
> > +
> > +
> > diff --git a/RedfishPkg/RedfishLibs.dsc.inc
> > b/RedfishPkg/RedfishLibs.dsc.inc index d4c08e18ac..2a951bd8fa 100644
> > --- a/RedfishPkg/RedfishLibs.dsc.inc
> > +++ b/RedfishPkg/RedfishLibs.dsc.inc
> > @@ -12,5 +12,6 @@
> > ##
> > !if $(REDFISH_ENABLE) == TRUE
> > Ucs2Utf8Lib|RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > + CrtLib|RedfishPkg/Library/CrtLib/CrtLib.inf
> > !endif
> >
> > diff --git a/RedfishPkg/RedfishPkg.ci.yaml
> > b/RedfishPkg/RedfishPkg.ci.yaml index 20c297ad22..9895fdac99 100644
> > --- a/RedfishPkg/RedfishPkg.ci.yaml
> > +++ b/RedfishPkg/RedfishPkg.ci.yaml
> > @@ -17,6 +17,25 @@
> > ],
> > ## Both file path and directory path are accepted.
> > "IgnoreFiles": [
> > + ## Below are files incorporated with open source which are
> > + ## not edk2 coding standard compliant.
> > + ##
> > + ## EDK2 CRT library which is not edk2 coding
> > + ## standard compliant.
> > + ## C runtime library for EDKII JsonLib.
> > + "Include/Crt/sys",
> > + "Include/Crt/assert.h",
> > + "Include/Crt/errno.h",
> > + "Include/Crt/limits.h",
> > + "Include/Crt/math.h",
> > + "Include/Crt/stdarg.h",
> > + "Include/Crt/stddef.h",
> > + "Include/Crt/stdio.h",
> > + "Include/Crt/stdlib.h",
> > + "Include/Crt/string.h",
> > + "Include/Crt/time.h",
> > + "Include/Library/CrtLib.h",
> > + "Library/CrtLib/CrtLib.c"
> > ]
> > },
> > "CompilerPlugin": {
> > diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec
> > index aecc1f4a3a..2142b43640 100644
> > --- a/RedfishPkg/RedfishPkg.dec
> > +++ b/RedfishPkg/RedfishPkg.dec
> > @@ -15,16 +15,24 @@
> >
> > [Includes]
> > Include
> > + Include/Crt # Header files for C RTL.
> >
> > [LibraryClasses]
> > ## @libraryclass Platform Redfish Host Interface Library
> > # Platform implementation-specific Redfish Host Interface.
> >
> > RedfishPlatformHostInterfaceLib|Include/Library/RedfishHostInterfaceLi
> > b.h
> > +
> > ## @libraryclass This library provides UCS2 to UTF8 manipulation
> > # functions.
> > #
> > Ucs2Utf8Lib|Include/Library/BaseUcs2Utf8Lib.h
> >
> > + ## @libraryclass Provides the C runtime library functions
> > + # CRT library is currently used by edk2 JsonLib (open source
> > + # jansson project) and edk2 RedfishLib (libredfish open source
> > + # project).
> > + CrtLib|Include/Library/CrtLib.h
> > +
> > [Protocols]
> > ## Include/Protocol/RedfishDiscover.h
> > gEfiRedfishDiscoverProtocolGuid = { 0x5db12509, 0x4550, 0x4347, { 0x96,
> 0xb3, 0x73, 0xc0, 0xff, 0x6e, 0x86, 0x9f
> > }}
> > diff --git a/RedfishPkg/RedfishPkg.dsc b/RedfishPkg/RedfishPkg.dsc
> > index 3639b620e6..aa1ccd5a95 100644
> > --- a/RedfishPkg/RedfishPkg.dsc
> > +++ b/RedfishPkg/RedfishPkg.dsc
> > @@ -48,5 +48,6 @@
> > [Components]
> >
> RedfishPkg/Library/PlatformHostInterfaceLibNull/PlatformHostInterfaceLibN
> ull.inf
> > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > + RedfishPkg/Library/CrtLib/CrtLib.inf
> >
> > !include RedfishPkg/Redfish.dsc.inc
> > --
> > 2.17.1
> >
> >
> >
> >
> >
>
>
>
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
[parent not found: <16511FD303DAB3AC.18439@groups.io>]
* Re: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime library
[not found] ` <16511FD303DAB3AC.18439@groups.io>
@ 2020-12-20 15:07 ` Abner Chang
0 siblings, 0 replies; 15+ messages in thread
From: Abner Chang @ 2020-12-20 15:07 UTC (permalink / raw)
To: devel@edk2.groups.io, michael.d.kinney@intel.com
Cc: Leif Lindholm, Wang, Nickle (HPS SW), O'Hanley, Peter (EXL)
Hi Mike,
Any other comments on v8 patches?
Abner
> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Abner Chang
> Sent: Wednesday, December 16, 2020 2:52 PM
> To: devel@edk2.groups.io; michael.d.kinney@intel.com
> Cc: Leif Lindholm <leif@nuviainc.com>; Wang, Nickle (HPS SW)
> <nickle.wang@hpe.com>; O'Hanley, Peter (EXL) <peter.ohanley@hpe.com>
> Subject: Re: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime library
>
> Done. Fix in next set of patches.
>
> > -----Original Message-----
> > From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> > Michael D Kinney
> > Sent: Tuesday, December 15, 2020 1:07 AM
> > To: devel@edk2.groups.io; Chang, Abner (HPS SW/FW Technologist)
> > <abner.chang@hpe.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> > Cc: Leif Lindholm <leif@nuviainc.com>; Wang, Nickle (HPS SW)
> > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> <peter.ohanley@hpe.com>
> > Subject: Re: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime
> library
> >
> > If CrtLib is a custom library to support use of jansson, then it should go into
> a
> > private include directory in RedFishPkg, not the public include directory.
> >
> > The only include files that should go into the public include directory of a
> > package are include files that are available to modules/libs implemented
> > outside the RedFishPkg. Please review all the include files in RedFishPkg
> with
> > this in mind.
> >
> > Mike
> >
> > > -----Original Message-----
> > > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
> Abner
> > > Chang
> > > Sent: Sunday, December 13, 2020 7:53 PM
> > > To: devel@edk2.groups.io
> > > Cc: Leif Lindholm <leif@nuviainc.com>; Nickle Wang
> > > <nickle.wang@hpe.com>; Peter O'Hanley <peter.ohanley@hpe.com>
> > > Subject: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime
> > > library
> > >
> > > CRT library is currently used by edk2 JsonLib (open source jansson
> > > project) and edk2 RedfishLib (libredfish open source project). CrtLib
> > > library provides the necessary C runtime equivalent edk2 functions for
> > > open source projects.
> > >
> > > Signed-off-by: Abner Chang <abner.chang@hpe.com>
> > >
> > > Cc: Leif Lindholm <leif@nuviainc.com>
> > > Cc: Nickle Wang <nickle.wang@hpe.com>
> > > Cc: Peter O'Hanley <peter.ohanley@hpe.com>
> > > ---
> > > RedfishPkg/Include/Crt/assert.h | 16 +
> > > RedfishPkg/Include/Crt/errno.h | 16 +
> > > RedfishPkg/Include/Crt/limits.h | 16 +
> > > RedfishPkg/Include/Crt/math.h | 16 +
> > > RedfishPkg/Include/Crt/stdarg.h | 15 +
> > > RedfishPkg/Include/Crt/stddef.h | 16 +
> > > RedfishPkg/Include/Crt/stdio.h | 15 +
> > > RedfishPkg/Include/Crt/stdlib.h | 16 +
> > > RedfishPkg/Include/Crt/string.h | 16 +
> > > RedfishPkg/Include/Crt/sys/time.h | 15 +
> > > RedfishPkg/Include/Crt/sys/types.h | 15 +
> > > RedfishPkg/Include/Crt/time.h | 15 +
> > > RedfishPkg/Include/Library/CrtLib.h | 195 ++++++++
> > > RedfishPkg/Library/CrtLib/CrtLib.c | 705
> > +++++++++++++++++++++++++++
> > > RedfishPkg/Library/CrtLib/CrtLib.inf | 37 ++
> > > RedfishPkg/RedfishLibs.dsc.inc | 1 +
> > > RedfishPkg/RedfishPkg.ci.yaml | 19 +
> > > RedfishPkg/RedfishPkg.dec | 8 +
> > > RedfishPkg/RedfishPkg.dsc | 1 +
> > > 19 files changed, 1153 insertions(+)
> > > create mode 100644 RedfishPkg/Include/Crt/assert.h create mode
> > > 100644 RedfishPkg/Include/Crt/errno.h create mode 100644
> > > RedfishPkg/Include/Crt/limits.h create mode 100644
> > > RedfishPkg/Include/Crt/math.h create mode 100644
> > > RedfishPkg/Include/Crt/stdarg.h create mode 100644
> > > RedfishPkg/Include/Crt/stddef.h create mode 100644
> > > RedfishPkg/Include/Crt/stdio.h create mode 100644
> > > RedfishPkg/Include/Crt/stdlib.h create mode 100644
> > > RedfishPkg/Include/Crt/string.h create mode 100644
> > > RedfishPkg/Include/Crt/sys/time.h create mode 100644
> > > RedfishPkg/Include/Crt/sys/types.h
> > > create mode 100644 RedfishPkg/Include/Crt/time.h create mode 100644
> > > RedfishPkg/Include/Library/CrtLib.h
> > > create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.c
> > > create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.inf
> > >
> > > diff --git a/RedfishPkg/Include/Crt/assert.h
> > > b/RedfishPkg/Include/Crt/assert.h new file mode 100644 index
> > > 0000000000..f9ab7ef9ca
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/assert.h
> > > @@ -0,0 +1,16 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +#ifndef CRT_ASSERT_H_
> > > +#define CRT_ASSERT_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/errno.h
> > > b/RedfishPkg/Include/Crt/errno.h new file mode 100644 index
> > > 0000000000..d30aee14de
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/errno.h
> > > @@ -0,0 +1,16 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +#ifndef CRT_ERRNO_H_
> > > +#define CRT_ERRNO_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/limits.h
> > > b/RedfishPkg/Include/Crt/limits.h new file mode 100644 index
> > > 0000000000..f3bdd33f2a
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/limits.h
> > > @@ -0,0 +1,16 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +#ifndef CRT_LIMITS_H_
> > > +#define CRT_LIMITS_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/math.h
> > > b/RedfishPkg/Include/Crt/math.h new file mode 100644 index
> > > 0000000000..984c0ccc21
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/math.h
> > > @@ -0,0 +1,16 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +#ifndef CRT_MATH_H_
> > > +#define CRT_MATH_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/stdarg.h
> > > b/RedfishPkg/Include/Crt/stdarg.h new file mode 100644 index
> > > 0000000000..d5a314ad3b
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/stdarg.h
> > > @@ -0,0 +1,15 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +#ifndef CRT_STDARG_H_
> > > +#define CRT_STDARG_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/stddef.h
> > > b/RedfishPkg/Include/Crt/stddef.h new file mode 100644 index
> > > 0000000000..15a37bf50e
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/stddef.h
> > > @@ -0,0 +1,16 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +#ifndef CRT_STDDEF_H_
> > > +#define CRT_STDDEF_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/stdio.h
> > > b/RedfishPkg/Include/Crt/stdio.h new file mode 100644 index
> > > 0000000000..25e610be10
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/stdio.h
> > > @@ -0,0 +1,15 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +#ifndef CRT_STDIO_H_
> > > +#define CRT_STDIO_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/stdlib.h
> > > b/RedfishPkg/Include/Crt/stdlib.h new file mode 100644 index
> > > 0000000000..5b3dd273c8
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/stdlib.h
> > > @@ -0,0 +1,16 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +#ifndef CRT_STDLIB_H_
> > > +#define CRT_STDLIB_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/string.h
> > > b/RedfishPkg/Include/Crt/string.h new file mode 100644 index
> > > 0000000000..f60b87ccd2
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/string.h
> > > @@ -0,0 +1,16 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +#ifndef CRT_STRING_H_
> > > +#define CRT_STRING_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/sys/time.h
> > > b/RedfishPkg/Include/Crt/sys/time.h
> > > new file mode 100644
> > > index 0000000000..4ced176cda
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/sys/time.h
> > > @@ -0,0 +1,15 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +#ifndef CRT_SYS_TIME_H_
> > > +#define CRT_SYS_TIME_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/sys/types.h
> > > b/RedfishPkg/Include/Crt/sys/types.h
> > > new file mode 100644
> > > index 0000000000..c4f807214c
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/sys/types.h
> > > @@ -0,0 +1,15 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +#ifndef CRT_SYS_TYPES_H_
> > > +#define CRT_SYS_TYPES_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/time.h
> > > b/RedfishPkg/Include/Crt/time.h new file mode 100644 index
> > > 0000000000..ca04ac8730
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/time.h
> > > @@ -0,0 +1,15 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +#ifndef CRT_TIME_H_
> > > +#define CRT_TIME_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Library/CrtLib.h
> > > b/RedfishPkg/Include/Library/CrtLib.h
> > > new file mode 100644
> > > index 0000000000..8c7484e75b
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Library/CrtLib.h
> > > @@ -0,0 +1,195 @@
> > > +/** @file
> > > + CRT wrapper head functions for jansson system call.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +#ifndef CRT_LIB_H_
> > > +#define CRT_LIB_H_
> > > +
> > > +#include <Library/BaseLib.h>
> > > +#include <Library/BaseMemoryLib.h>
> > > +#include <Library/DebugLib.h>
> > > +#include <Library/PrintLib.h>
> > > +
> > > +#define MAX_STRING_SIZE 0x10000000
> > > +
> > > +// Minimum value for an object of type long long int.
> > > +#define LLONG_MIN MIN_INT64
> > > +
> > > +// Maximum value for an object of type long long int.
> > > +#define LLONG_MAX MAX_INT64
> > > +
> > > +// We dont support double on edk2
> > > +#define HUGE_VAL 0
> > > +
> > > +#if defined(MDE_CPU_X64) || defined(MDE_CPU_AARCH64) ||
> > > +defined(MDE_CPU_IA64) || defined(MDE_CPU_RISCV64) // // With
> GCC
> > we
> > > +would normally use SIXTY_FOUR_BIT_LONG, but MSVC needs //
> > > +SIXTY_FOUR_BIT, because 'long' is 32-bit and only 'long long' is //
> > > +64-bit. Since using 'long long' works fine on GCC too, just do that.
> > > +//
> > > +#define SIXTY_FOUR_BIT
> > > +#elif defined(MDE_CPU_IA32) || defined(MDE_CPU_ARM) ||
> > > +defined(MDE_CPU_EBC) #define THIRTY_TWO_BIT #endif
> > > +
> > > +//
> > > +// Map all va_xxxx elements to VA_xxx defined in
> > > +MdePkg/Include/Base.h // #if !defined(__CC_ARM) // if va_list is not
> > > +already defined
> > > +#define va_list VA_LIST
> > > +#define va_arg VA_ARG
> > > +#define va_start VA_START
> > > +#define va_end VA_END
> > > +#else // __CC_ARM
> > > +#define va_start(Marker, Parameter) __va_start(Marker, Parameter)
> > > +#define va_arg(Marker, TYPE) __va_arg(Marker, TYPE)
> > > +#define va_end(Marker) ((void)0)
> > > +#endif
> > > +
> > > +//
> > > +// Definitions for global constants used by CRT library routines //
> > > +#define INT_MAX MAX_INT32 /* Maximum (signed) int value */
> > > +#define LONG_MAX 0X7FFFFFFFL /* max value for a long */
> > > +#define LONG_MIN (-LONG_MAX-1) /* min value for a long */
> > > +#define ULONG_MAX 0xFFFFFFFF /* Maximum unsigned long
> value
> > */
> > > +#define CHAR_BIT 8 /* Number of bits in a char */
> > > +
> > > +// Maximum value for an object of type unsigned long long int.
> > > +#define ULLONG_MAX 0xFFFFFFFFFFFFFFFFULL // 2^64 - 1 // Maximum
> > > +value for an object of type unsigned char.
> > > +#define UCHAR_MAX 255 // 2^8 - 1
> > > +
> > > +//
> > > +// Basic types mapping
> > > +//
> > > +typedef UINTN size_t;
> > > +typedef INTN ssize_t;
> > > +typedef INT32 time_t;
> > > +typedef UINT8 __uint8_t;
> > > +typedef UINT8 sa_family_t;
> > > +typedef UINT32 uid_t;
> > > +typedef UINT32 gid_t;
> > > +typedef INT32 int32_t;
> > > +typedef UINT32 uint32_t;
> > > +typedef UINT16 uint16_t;
> > > +typedef UINT8 uint8_t;
> > > +typedef enum {false, true} bool;
> > > +
> > > +//
> > > +// File operations are not required for EFI building, // so FILE is
> > > +mapped to VOID * to pass build // typedef VOID *FILE;
> > > +
> > > +//
> > > +// Global variables
> > > +//
> > > +extern int errno;
> > > +extern FILE *stderr;
> > > +
> > > +//
> > > +// Function prototypes of CRT Library routines //
> > > +void *malloc (size_t);
> > > +void *realloc (void *, size_t);
> > > +void *calloc (size_t Num, size_t Size);
> > > +void free (void *);
> > > +void *memset (void *, int, size_t);
> > > +int memcmp (const void *, const void *, size_t);
> > > +int isdigit (int);
> > > +int isspace (int);
> > > +int tolower (int);
> > > +int isupper (int);
> > > +int isxdigit (int);
> > > +int isalnum (int);
> > > +void *memcpy (void *, const void *, size_t);
> > > +void *memset (void *, int, size_t);
> > > +void *memchr (const void *, int, size_t);
> > > +int memcmp (const void *, const void *, size_t);
> > > +void *memmove (void *, const void *, size_t);
> > > +int strcmp (const char *, const char *);
> > > +int strncmp (const char *, const char *, size_t);
> > > +char *strcpy (char *, const char *);
> > > +size_t strlen (const char *);
> > > +char *strcat (char *, const char *);
> > > +char *strchr (const char *, int);
> > > +int strcasecmp (const char *, const char *);
> > > +int strncasecmp (const char *, const char *, size_t);
> > > +char *strncpy (char *, size_t, const char *, size_t);
> > > +int strncmp (const char *, const char *, size_t);
> > > +char *strrchr (const char *, int);
> > > +unsigned long strtoul (const char *, char **, int);
> > > +char * strstr (const char *s1 , const char *s2);
> > > +long strtol (const char *, char **, int);
> > > +char *strerror (int);
> > > +size_t strspn (const char *, const char *);
> > > +char * strdup (const char *str);
> > > +char * strpbrk (const char *s1, const char *s2);
> > > +unsigned long long strtoull(const char * nptr, char ** endptr, int base);
> > > +long long strtoll (const char * nptr, char ** endptr, int base);
> > > +long strtol (const char * nptr, char ** endptr, int base);
> > > +double strtod (const char * __restrict nptr, char ** __restrict
> > endptr);
> > > +size_t strcspn (const char *, const char *);
> > > +int printf (const char *, ...);
> > > +int sscanf (const char *, const char *, ...);
> > > +FILE *fopen (const char *, const char *);
> > > +size_t fread (void *, size_t, size_t, FILE *);
> > > +size_t fwrite (const void *, size_t, size_t, FILE *);
> > > +int fclose (FILE *);
> > > +int fprintf (FILE *, const char *, ...);
> > > +int fgetc (FILE * _File);
> > > +uid_t getuid (void);
> > > +uid_t geteuid (void);
> > > +gid_t getgid (void);
> > > +gid_t getegid (void);
> > > +void qsort (void *, size_t, size_t, int (*)(const void *, const void
> > *));
> > > +char *getenv (const char *);
> > > +#if defined(__GNUC__) && (__GNUC__ >= 2)
> > > +void abort (void) __attribute__((__noreturn__));
> > > +#else
> > > +void abort (void);
> > > +#endif
> > > +int toupper (int);
> > > +int Digit2Val (int);
> > > +time_t time (time_t *);
> > > +
> > > +//
> > > +// Macros that directly map functions to BaseLib, BaseMemoryLib, and
> > > +DebugLib functions //
> > > +#define strcmp AsciiStrCmp
> > > +#define memcpy(dest,source,count)
> > CopyMem(dest,source,(UINTN)(count))
> > > +#define memset(dest,ch,count)
> > SetMem(dest,(UINTN)(count),(UINT8)(ch))
> > > +#define memchr(buf,ch,count)
> > ScanMem8(buf,(UINTN)(count),(UINT8)ch)
> > > +#define memcmp(buf1,buf2,count)
> > (int)(CompareMem(buf1,buf2,(UINTN)(count)))
> > > +#define memmove(dest,source,count)
> > CopyMem(dest,source,(UINTN)(count))
> > > +#define strlen(str)
> > (size_t)(AsciiStrnLenS(str,MAX_STRING_SIZE))
> > > +#define strcpy(strDest,strSource)
> > AsciiStrCpyS(strDest,(strlen(strSource)+1),strSource)
> > > +#define strncpy(strDest,strSource,count)
> > > +AsciiStrnCpyS(strDest,(UINTN)count,strSource,(UINTN)count)
> > > +#define strncpys(strDest, DestLen, strSource,count)
> > AsciiStrnCpyS(strDest,DestLen,strSource,(UINTN)count)
> > > +#define strcat(strDest,strSource)
> > AsciiStrCatS(strDest,(strlen(strSource)+strlen(strDest)+1),strSource)
> > > +#define strchr(str,ch) ScanMem8((VOID
> > *)(str),AsciiStrSize(str),(UINT8)ch)
> > > +#define strncmp(string1,string2,count)
> > (int)(AsciiStrnCmp(string1,string2,(UINTN)(count)))
> > > +#define strcasecmp(str1,str2) (int)AsciiStriCmp(str1,str2)
> > > +#define strstr(s1,s2) AsciiStrStr(s1,s2)
> > > +#define sprintf(buf,...)
> > AsciiSPrint(buf,MAX_STRING_SIZE,__VA_ARGS__)
> > > +#define snprintf(buf,len,...) AsciiSPrint(buf,len,__VA_ARGS__)
> > > +#define vsnprintf(buf,len,format,marker)
> > AsciiVSPrint((buf),(len),(format),(marker))
> > > +#define assert(expression) ASSERT(expression)
> > > +#define atoi(nptr) AsciiStrDecimalToUintn(nptr)
> > > +#define fabs(x) (((x) < 0.0)? (-x): (x))
> > > +#define offsetof(type,member) OFFSET_OF(type,member)
> > > +
> > > +#define EOF (-1)
> > > +
> > > +extern int errno;
> > > +
> > > +#define ERANGE 34 /* 34 Result too large */
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Library/CrtLib/CrtLib.c
> > > b/RedfishPkg/Library/CrtLib/CrtLib.c
> > > new file mode 100644
> > > index 0000000000..1ff4023dbe
> > > --- /dev/null
> > > +++ b/RedfishPkg/Library/CrtLib/CrtLib.c
> > > @@ -0,0 +1,705 @@
> > > +/** @file
> > > + CRT wrapper functions for system call.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +#include <Uefi.h>
> > > +#include <Library/CrtLib.h>
> > > +#include <Library/MemoryAllocationLib.h> #include
> > > +<Library/UefiRuntimeServicesTableLib.h>
> > > +
> > > +int errno = 0;
> > > +
> > > +/**
> > > + Determine if a particular character is an alphanumeric character
> > > + @return Returns 1 if c is an alphanumeric character, otherwise returns
> 0.
> > > +**/
> > > +int isalnum (int c)
> > > +{
> > > + //
> > > + // <alnum> ::= [0-9] | [a-z] | [A-Z]
> > > + //
> > > + return ((('0' <= (c)) && ((c) <= '9')) ||
> > > + (('a' <= (c)) && ((c) <= 'z')) ||
> > > + (('A' <= (c)) && ((c) <= 'Z'))); }
> > > +
> > > +/**
> > > + Determine if a particular character is a digital character
> > > +
> > > + @return Returns 1 if c is an digital character, otherwise returns 0.
> > > +**/
> > > +int isdchar (int c)
> > > +{
> > > + //
> > > + // [0-9] | [e +-.]
> > > + //
> > > + return ((('0' <= (c)) && ((c) <= '9')) ||
> > > + (c == 'e') || (c == 'E') ||
> > > + (c == '+') || (c == '-') ||
> > > + (c == '.'));
> > > +}
> > > +
> > > +/**
> > > + Determine if a particular character is a space character
> > > +
> > > + @return Returns 1 if c is a space character **/ int isspace (int
> > > +c) {
> > > + //
> > > + // <space> ::= [ ]
> > > + //
> > > + return ((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) ==
> > > +'\n') || ((c) == '\v') || ((c) == '\f'); }
> > > +
> > > +/**
> > > + Allocates memory blocks
> > > +*/
> > > +void *malloc (size_t size)
> > > +{
> > > + return AllocatePool ((UINTN) size); }
> > > +
> > > +/**
> > > + De-allocates or frees a memory block */ void free (void *ptr) {
> > > + //
> > > + // In Standard C, free() handles a null pointer argument
> > > +transparently. This
> > > + // is not true of FreePool() below, so protect it.
> > > + //
> > > + if (ptr != NULL) {
> > > + FreePool (ptr);
> > > + }
> > > +}
> > > +
> > > +/**
> > > + NetBSD Compatibility Function strdup creates a duplicate copy of a
> string.
> > > +
> > > + @return Returns the pointer to duplicated string.
> > > +**/
> > > +char * strdup(const char *str)
> > > +{
> > > + size_t len;
> > > + char *copy;
> > > +
> > > + len = strlen(str) + 1;
> > > + if ((copy = malloc(len)) == NULL)
> > > + return (NULL);
> > > + memcpy(copy, str, len);
> > > + return (copy);
> > > +}
> > > +
> > > +/** The toupper function converts a lowercase letter to a corresponding
> > > + uppercase letter.
> > > +
> > > + @param[in] c The character to be converted.
> > > +
> > > + @return If the argument is a character for which islower is true and
> > > + there are one or more corresponding characters, as specified by
> > > + the current locale, for which isupper is true, the toupper
> > > + function returns one of the corresponding characters (always the
> > > + same one for any given locale); otherwise, the argument is
> > > + returned unchanged.
> > > +**/
> > > +int
> > > +toupper(
> > > + IN int c
> > > + )
> > > +{
> > > + if ( (c >= 'a') && (c <= 'z') ) {
> > > + c = c - ('a' - 'A');
> > > + }
> > > + return c;
> > > +}
> > > +
> > > +/**
> > > + Digit to a value.
> > > +
> > > + @return Returns the value of digit.
> > > +**/
> > > +int
> > > +Digit2Val( int c)
> > > +{
> > > + if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))) { /* If c is one of
> [A-
> > Za-z]... */
> > > + c = toupper(c) - 7; // Adjust so 'A' is ('9' + 1)
> > > + }
> > > + return c - '0'; // Value returned is between 0 and 35, inclusive.
> > > +}
> > > +
> > > +
> > > +/** The strtoll function converts the initial portion of the string pointed
> to
> > > + by nptr to long long int representation.
> > > +
> > > + See the description for strtol for more information.
> > > +
> > > + @return The strtoll function returns the converted value, if any. If no
> > > + conversion could be performed, zero is returned. If the correct
> > > + value is outside the range of representable values, LLONG_MIN or
> > > + LLONG_MAX is returned (according to the sign of the value, if any),
> > > + and the value of the macro ERANGE is stored in errno.
> > > +**/
> > > +long long
> > > +strtoll(const char * nptr, char ** endptr, int base) {
> > > + const char *pEnd;
> > > + long long Result = 0;
> > > + long long Previous;
> > > + int temp;
> > > + BOOLEAN Negative = FALSE;
> > > +
> > > + pEnd = nptr;
> > > +
> > > + if((base < 0) || (base == 1) || (base > 36)) {
> > > + if(endptr != NULL) {
> > > + *endptr = NULL;
> > > + }
> > > + return 0;
> > > + }
> > > + // Skip leading spaces.
> > > + while(isspace(*nptr)) ++nptr;
> > > +
> > > + // Process Subject sequence: optional sign followed by digits.
> > > + if(*nptr == '+') {
> > > + Negative = FALSE;
> > > + ++nptr;
> > > + }
> > > + else if(*nptr == '-') {
> > > + Negative = TRUE;
> > > + ++nptr;
> > > + }
> > > +
> > > + if(*nptr == '0') { /* Might be Octal or Hex */
> > > + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> > > + if((base == 0) || (base == 16)) {
> > > + nptr += 2; /* Skip the "0X" */
> > > + base = 16; /* In case base was 0 */
> > > + }
> > > + }
> > > + else { /* Looks like Octal */
> > > + if((base == 0) || (base == 8)) {
> > > + ++nptr; /* Skip the leading "0" */
> > > + base = 8; /* In case base was 0 */
> > > + }
> > > + }
> > > + }
> > > + if(base == 0) { /* If still zero then must be decimal */
> > > + base = 10;
> > > + }
> > > + if(*nptr == '0') {
> > > + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> > > + pEnd = nptr;
> > > + }
> > > +
> > > + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> > > + Previous = Result;
> > > + Result = MultS64x64 (Result, base) + (long long int)temp;
> > > + if( Result <= Previous) { // Detect Overflow
> > > + if(Negative) {
> > > + Result = LLONG_MIN;
> > > + }
> > > + else {
> > > + Result = LLONG_MAX;
> > > + }
> > > + Negative = FALSE;
> > > + errno = ERANGE;
> > > + break;
> > > + }
> > > + pEnd = ++nptr;
> > > + }
> > > + if(Negative) {
> > > + Result = -Result;
> > > + }
> > > +
> > > + // Save pointer to final sequence
> > > + if(endptr != NULL) {
> > > + *endptr = (char *)pEnd;
> > > + }
> > > + return Result;
> > > +}
> > > +
> > > +/** The strtol, strtoll, strtoul, and strtoull functions convert the initial
> > > + portion of the string pointed to by nptr to long int, long long int,
> > > + unsigned long int, and unsigned long long int representation,
> > respectively.
> > > + First, they decompose the input string into three parts: an initial,
> > > + possibly empty, sequence of white-space characters (as specified by
> > the
> > > + isspace function), a subject sequence resembling an integer
> > represented in
> > > + some radix determined by the value of base, and a final string of one
> or
> > > + more unrecognized characters, including the terminating null
> character
> > of
> > > + the input string. Then, they attempt to convert the subject sequence
> to
> > an
> > > + integer, and return the result.
> > > +
> > > + If the value of base is zero, the expected form of the subject
> sequence
> > is
> > > + that of an integer constant, optionally preceded
> > > + by a plus or minus sign, but not including an integer suffix. If the value
> > > + of base is between 2 and 36 (inclusive), the expected form of the
> > subject
> > > + sequence is a sequence of letters and digits representing an integer
> > with
> > > + the radix specified by base, optionally preceded by a plus or minus
> sign,
> > > + but not including an integer suffix. The letters from a (or A) through z
> > > + (or Z) are ascribed the values 10 through 35; only letters and digits
> > whose
> > > + ascribed values are less than that of base are permitted. If the value
> of
> > > + base is 16, the characters 0x or 0X may optionally precede the
> sequence
> > of
> > > + letters and digits, following the sign if present.
> > > +
> > > + The subject sequence is defined as the longest initial subsequence of
> > the
> > > + input string, starting with the first non-white-space character, that is
> of
> > > + the expected form. The subject sequence contains no characters if
> the
> > input
> > > + string is empty or consists entirely of white space, or if the first
> > > + non-white-space character is other than a sign or a permissible letter
> or
> > digit.
> > > +
> > > + If the subject sequence has the expected form and the value of base
> is
> > > + zero, the sequence of characters starting with the first digit is
> > > + interpreted as an integer constant. If the subject sequence has the
> > > + expected form and the value of base is between 2 and 36, it is used as
> > the
> > > + base for conversion, ascribing to each letter its value as given above. If
> > > + the subject sequence begins with a minus sign, the value resulting
> from
> > the
> > > + conversion is negated (in the return type). A pointer to the final string
> > > + is stored in the object pointed to by endptr, provided that endptr is
> > > + not a null pointer.
> > > +
> > > + In other than the "C" locale, additional locale-specific subject
> sequence
> > > + forms may be accepted.
> > > +
> > > + If the subject sequence is empty or does not have the expected form,
> > no
> > > + conversion is performed; the value of nptr is stored in the object
> > pointed
> > > + to by endptr, provided that endptr is not a null pointer.
> > > +
> > > + @return The strtol, strtoll, strtoul, and strtoull functions return the
> > > + converted value, if any. If no conversion could be performed, zero
> > > + is returned. If the correct value is outside the range of
> > > + representable values, LONG_MIN, LONG_MAX, LLONG_MIN,
> > LLONG_MAX,
> > > + ULONG_MAX, or ULLONG_MAX is returned (according to the
> return
> > type
> > > + and sign of the value, if any), and the value of the macro ERANGE
> > > + is stored in errno.
> > > +**/
> > > +long
> > > +strtol(const char * nptr, char ** endptr, int base) {
> > > + const char *pEnd;
> > > + long Result = 0;
> > > + long Previous;
> > > + int temp;
> > > + BOOLEAN Negative = FALSE;
> > > +
> > > + pEnd = nptr;
> > > +
> > > + if((base < 0) || (base == 1) || (base > 36)) {
> > > + if(endptr != NULL) {
> > > + *endptr = NULL;
> > > + }
> > > + return 0;
> > > + }
> > > + // Skip leading spaces.
> > > + while(isspace(*nptr)) ++nptr;
> > > +
> > > + // Process Subject sequence: optional sign followed by digits.
> > > + if(*nptr == '+') {
> > > + Negative = FALSE;
> > > + ++nptr;
> > > + }
> > > + else if(*nptr == '-') {
> > > + Negative = TRUE;
> > > + ++nptr;
> > > + }
> > > +
> > > + if(*nptr == '0') { /* Might be Octal or Hex */
> > > + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> > > + if((base == 0) || (base == 16)) {
> > > + nptr += 2; /* Skip the "0X" */
> > > + base = 16; /* In case base was 0 */
> > > + }
> > > + }
> > > + else { /* Looks like Octal */
> > > + if((base == 0) || (base == 8)) {
> > > + ++nptr; /* Skip the leading "0" */
> > > + base = 8; /* In case base was 0 */
> > > + }
> > > + }
> > > + }
> > > + if(base == 0) { /* If still zero then must be decimal */
> > > + base = 10;
> > > + }
> > > + if(*nptr == '0') {
> > > + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> > > + pEnd = nptr;
> > > + }
> > > +
> > > + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> > > + Previous = Result;
> > > + Result = (Result * base) + (long int)temp;
> > > + if( Result <= Previous) { // Detect Overflow
> > > + if(Negative) {
> > > + Result = LONG_MIN;
> > > + }
> > > + else {
> > > + Result = LONG_MAX;
> > > + }
> > > + Negative = FALSE;
> > > + errno = ERANGE;
> > > + break;
> > > + }
> > > + pEnd = ++nptr;
> > > + }
> > > + if(Negative) {
> > > + Result = -Result;
> > > + }
> > > +
> > > + // Save pointer to final sequence
> > > + if(endptr != NULL) {
> > > + *endptr = (char *)pEnd;
> > > + }
> > > + return Result;
> > > +}
> > > +
> > > +/** The strtoull function converts the initial portion of the string pointed
> > to
> > > + by nptr to unsigned long long int representation.
> > > +
> > > + See the description for strtol for more information.
> > > +
> > > + @return The strtoull function returns the converted value, if any. If no
> > > + conversion could be performed, zero is returned. If the correct
> > > + value is outside the range of representable values, ULLONG_MAX
> is
> > > + returned and the value of the macro ERANGE is stored in errno.
> > > +**/
> > > +unsigned long long
> > > +strtoull(const char * nptr, char ** endptr, int base) {
> > > + const char *pEnd;
> > > + unsigned long long Result = 0;
> > > + unsigned long long Previous;
> > > + int temp;
> > > +
> > > + pEnd = nptr;
> > > +
> > > + if((base < 0) || (base == 1) || (base > 36)) {
> > > + if(endptr != NULL) {
> > > + *endptr = NULL;
> > > + }
> > > + return 0;
> > > + }
> > > + // Skip leading spaces.
> > > + while(isspace(*nptr)) ++nptr;
> > > +
> > > + // Process Subject sequence: optional + sign followed by digits.
> > > + if(*nptr == '+') {
> > > + ++nptr;
> > > + }
> > > +
> > > + if(*nptr == '0') { /* Might be Octal or Hex */
> > > + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> > > + if((base == 0) || (base == 16)) {
> > > + nptr += 2; /* Skip the "0X" */
> > > + base = 16; /* In case base was 0 */
> > > + }
> > > + }
> > > + else { /* Looks like Octal */
> > > + if((base == 0) || (base == 8)) {
> > > + ++nptr; /* Skip the leading "0" */
> > > + base = 8; /* In case base was 0 */
> > > + }
> > > + }
> > > + }
> > > + if(base == 0) { /* If still zero then must be decimal */
> > > + base = 10;
> > > + }
> > > + if(*nptr == '0') {
> > > + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> > > + pEnd = nptr;
> > > + }
> > > +
> > > + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> > > + Previous = Result;
> > > + Result = DivU64x32 (Result, base) + (unsigned long long)temp;
> > > + if( Result < Previous) { // If we overflowed
> > > + Result = ULLONG_MAX;
> > > + errno = ERANGE;
> > > + break;
> > > + }
> > > + pEnd = ++nptr;
> > > + }
> > > +
> > > + // Save pointer to final sequence
> > > + if(endptr != NULL) {
> > > + *endptr = (char *)pEnd;
> > > + }
> > > + return Result;
> > > +}
> > > +
> > > +/**
> > > + edk2 Jansson port does not support doubles, simply return 0.
> > > +
> > > + These conversion functions convert the initial portion of the
> > > + string pointed to by nptr to double, float, and long double
> > > + representation, respectively.
> > > +
> > > + The strtod(), strtof(), and strtold() functions return the
> > > + converted value, if any.
> > > +
> > > + If endptr is not NULL, a pointer to the character after the last
> > > + charac- ter used in the conversion is stored in the location
> > > + referenced by endptr.
> > > +
> > > + If no conversion is performed, zero is returned and the value of
> > > + nptr is stored in the location referenced by endptr.
> > > +
> > > + If the correct value would cause overflow, plus or minus HUGE_VAL,
> > > + HUGE_VALF, or HUGE_VALL is returned (according to the sign and type
> > > + of the return value), and ERANGE is stored in errno. If the
> > > + correct value would cause underflow, zero is returned and ERANGE is
> > stored in errno.
> > > +
> > > + @return Return 0.
> > > +**/
> > > +double
> > > +strtod (const char * __restrict nptr, char ** __restrict endptr) {
> > > + if(endptr)
> > > + *endptr = (char *)(nptr + strlen(nptr));
> > > +
> > > + return (double)0;
> > > +}
> > > +
> > > +/**
> > > + Allocate and zero-initialize array.
> > > +**/
> > > +void *
> > > +calloc(size_t Num, size_t Size)
> > > +{
> > > + void *RetVal;
> > > + size_t NumSize;
> > > +
> > > + NumSize = Num * Size;
> > > + RetVal = NULL;
> > > + if (NumSize != 0) {
> > > + RetVal = malloc(NumSize);
> > > + if( RetVal != NULL) {
> > > + (VOID)ZeroMem( RetVal, NumSize);
> > > + }
> > > + }
> > > + DEBUG((DEBUG_POOL, "0x%p = calloc(%d, %d)\n", RetVal, Num, Size));
> > > +
> > > + return RetVal;
> > > +}
> > > +
> > > +//
> > > +// The arrays give the cumulative number of days up to the first of
> > > +the // month number used as the index (1 -> 12) for regular and leap
> > years.
> > > +// The value at index 13 is for the whole year.
> > > +//
> > > +UINTN CumulativeDays[2][14] = {
> > > + {
> > > + 0,
> > > + 0,
> > > + 31,
> > > + 31 + 28,
> > > + 31 + 28 + 31,
> > > + 31 + 28 + 31 + 30,
> > > + 31 + 28 + 31 + 30 + 31,
> > > + 31 + 28 + 31 + 30 + 31 + 30,
> > > + 31 + 28 + 31 + 30 + 31 + 30 + 31,
> > > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
> > > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
> > > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
> > > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
> > > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
> > > + },
> > > + {
> > > + 0,
> > > + 0,
> > > + 31,
> > > + 31 + 29,
> > > + 31 + 29 + 31,
> > > + 31 + 29 + 31 + 30,
> > > + 31 + 29 + 31 + 30 + 31,
> > > + 31 + 29 + 31 + 30 + 31 + 30,
> > > + 31 + 29 + 31 + 30 + 31 + 30 + 31,
> > > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,
> > > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
> > > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
> > > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
> > > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
> > > + }
> > > +};
> > > +
> > > +#define IsLeap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) ==
> 0))
> > > +#define SECSPERMIN (60)
> > > +#define SECSPERHOUR (60 * 60)
> > > +#define SECSPERDAY (24 * SECSPERHOUR)
> > > +
> > > +/**
> > > + Get the system time as seconds elapsed since midnight, January 1,
> 1970.
> > > +**/
> > > +time_t time (time_t *timer)
> > > +{
> > > + EFI_TIME Time;
> > > + time_t CalTime;
> > > + UINTN Year;
> > > +
> > > + //
> > > + // Get the current time and date information // gRT->GetTime
> > > + (&Time, NULL);
> > > +
> > > + //
> > > + // Years Handling
> > > + // UTime should now be set to 00:00:00 on Jan 1 of the current year.
> > > + //
> > > + for (Year = 1970, CalTime = 0; Year != Time.Year; Year++) {
> > > + CalTime = CalTime + (time_t)(CumulativeDays[IsLeap(Year)][13] *
> > > + SECSPERDAY); }
> > > +
> > > + //
> > > + // Add in number of seconds for current Month, Day, Hour, Minute,
> > > + Seconds, and TimeZone adjustment // CalTime = CalTime +
> > > + (time_t)((Time.TimeZone != EFI_UNSPECIFIED_TIMEZONE) ?
> > (Time.TimeZone * 60) : 0) +
> > > + (time_t)(CumulativeDays[IsLeap(Time.Year)][Time.Month] *
> > SECSPERDAY) +
> > > + (time_t)(((Time.Day > 0) ? Time.Day - 1 : 0) * SECSPERDAY) +
> > > + (time_t)(Time.Hour * SECSPERHOUR) +
> > > + (time_t)(Time.Minute * 60) +
> > > + (time_t)Time.Second;
> > > +
> > > + if (timer != NULL) {
> > > + *timer = CalTime;
> > > + }
> > > +
> > > + return CalTime;
> > > +}
> > > +
> > > +typedef
> > > +int
> > > +(*SORT_COMPARE)(
> > > + IN VOID *Buffer1,
> > > + IN VOID *Buffer2
> > > + );
> > > +
> > > +/**
> > > + Duplicated from EDKII BaseSortLib for qsort() wrapper
> > > + @param[in, out] BufferToSort on call a Buffer of (possibly sorted)
> > elements
> > > + on return a buffer of sorted elements
> > > + @param[in] Count the number of elements in the buffer to sort
> > > + @param[in] ElementSize Size of an element in bytes
> > > + @param[in] CompareFunction The function to call to perform the
> > comparison
> > > + of any 2 elements
> > > + @param[in] Buffer Buffer of size ElementSize for use in
> swapping
> > > +**/
> > > +STATIC
> > > +VOID
> > > +QuickSortWorker (
> > > + IN OUT VOID *BufferToSort,
> > > + IN CONST UINTN Count,
> > > + IN CONST UINTN ElementSize,
> > > + IN SORT_COMPARE CompareFunction,
> > > + IN VOID *Buffer
> > > + )
> > > +{
> > > + VOID *Pivot;
> > > + UINTN LoopCount;
> > > + UINTN NextSwapLocation;
> > > +
> > > + ASSERT(BufferToSort != NULL);
> > > + ASSERT(CompareFunction != NULL);
> > > + ASSERT(Buffer != NULL);
> > > +
> > > + if (Count < 2 || ElementSize < 1) {
> > > + return;
> > > + }
> > > +
> > > + NextSwapLocation = 0;
> > > +
> > > + //
> > > + // Pick a pivot (we choose last element) // Pivot = ((UINT8
> > > + *)BufferToSort + ((Count - 1) * ElementSize));
> > > +
> > > + //
> > > + // Now get the pivot such that all on "left" are below it // and
> > > + everything "right" are above it // for (LoopCount = 0; LoopCount <
> > > + Count - 1; LoopCount++) {
> > > + //
> > > + // If the element is less than the pivot
> > > + //
> > > + if (CompareFunction ((VOID *)((UINT8 *)BufferToSort + ((LoopCount)
> *
> > ElementSize)), Pivot) <= 0) {
> > > + //
> > > + // Swap
> > > + //
> > > + CopyMem (Buffer, (UINT8 *)BufferToSort + (NextSwapLocation *
> > ElementSize), ElementSize);
> > > + CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation *
> > > + ElementSize), (UINT8 *)BufferToSort + ((LoopCount) *
> > > ElementSize), ElementSize);
> > > + CopyMem ((UINT8 *)BufferToSort + ((LoopCount) * ElementSize),
> > > + Buffer, ElementSize);
> > > +
> > > + //
> > > + // Increment NextSwapLocation
> > > + //
> > > + NextSwapLocation++;
> > > + }
> > > + }
> > > + //
> > > + // Swap pivot to it's final position (NextSwapLocaiton) //
> > > + CopyMem (Buffer, Pivot, ElementSize); CopyMem (Pivot, (UINT8
> > > + *)BufferToSort + (NextSwapLocation * ElementSize), ElementSize);
> > > + CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation * ElementSize),
> > > + Buffer, ElementSize);
> > > +
> > > + //
> > > + // Now recurse on 2 paritial lists. Neither of these will have the 'pivot'
> > element.
> > > + // IE list is sorted left half, pivot element, sorted right half...
> > > + //
> > > + QuickSortWorker (
> > > + BufferToSort,
> > > + NextSwapLocation,
> > > + ElementSize,
> > > + CompareFunction,
> > > + Buffer
> > > + );
> > > +
> > > + QuickSortWorker (
> > > + (UINT8 *)BufferToSort + (NextSwapLocation + 1) * ElementSize,
> > > + Count - NextSwapLocation - 1,
> > > + ElementSize,
> > > + CompareFunction,
> > > + Buffer
> > > + );
> > > +
> > > + return;
> > > +}
> > > +
> > > +/**
> > > + Performs a quick sort
> > > +**/
> > > +void qsort (void *base, size_t num, size_t width, int
> > > +(*compare)(const void *, const void *)) {
> > > + VOID *Buffer;
> > > +
> > > + ASSERT (base != NULL);
> > > + ASSERT (compare != NULL);
> > > +
> > > + //
> > > + // Use CRT-style malloc to cover BS and RT memory allocation.
> > > + //
> > > + Buffer = malloc (width);
> > > + ASSERT (Buffer != NULL);
> > > +
> > > + //
> > > + // Re-use PerformQuickSort() function Implementation in EDKII
> > BaseSortLib.
> > > + //
> > > + QuickSortWorker (base, (UINTN)num, (UINTN)width,
> > > + (SORT_COMPARE)compare, Buffer);
> > > +
> > > + free (Buffer);
> > > + return;
> > > +}
> > > +
> > > +/**
> > > + Get character from stream, we don't support file operastion on edk2
> > JSON library.
> > > +
> > > + @return Returns the character currently pointed by the internal
> > > + file position indicator of the specified stream
> > > +
> > > +**/
> > > +int fgetc(FILE * _File){
> > > + return 0;
> > > +}
> > > diff --git a/RedfishPkg/Library/CrtLib/CrtLib.inf
> > > b/RedfishPkg/Library/CrtLib/CrtLib.inf
> > > new file mode 100644
> > > index 0000000000..b514817cf4
> > > --- /dev/null
> > > +++ b/RedfishPkg/Library/CrtLib/CrtLib.inf
> > > @@ -0,0 +1,37 @@
> > > +## @file
> > > +# EDK2 C Runtime Library for opensource project.
> > > +#
> > > +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> #
> > > +(C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR> #
> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +#
> > > +##
> > > +
> > > +[Defines]
> > > + INF_VERSION = 0x0001001b
> > > + BASE_NAME = CrtLib
> > > + FILE_GUID = 8263B8AC-D021-425D-B337-3EC96F5DC19B
> > > + MODULE_TYPE = DXE_DRIVER
> > > + VERSION_STRING = 1.0
> > > + LIBRARY_CLASS = CrtLib|DXE_CORE DXE_DRIVER
> > DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION
> > > UEFI_DRIVER
> > > +
> > > +#
> > > +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64
> > > +#
> > > +
> > > +[Sources]
> > > + CrtLib.c
> > > +
> > > +[LibraryClasses]
> > > + BaseLib
> > > + DebugLib
> > > + MemoryAllocationLib
> > > + UefiRuntimeServicesTableLib
> > > +
> > > +[Packages]
> > > + MdePkg/MdePkg.dec
> > > + MdeModulePkg/MdeModulePkg.dec
> > > + RedfishPkg/RedfishPkg.dec
> > > +
> > > +
> > > diff --git a/RedfishPkg/RedfishLibs.dsc.inc
> > > b/RedfishPkg/RedfishLibs.dsc.inc index d4c08e18ac..2a951bd8fa 100644
> > > --- a/RedfishPkg/RedfishLibs.dsc.inc
> > > +++ b/RedfishPkg/RedfishLibs.dsc.inc
> > > @@ -12,5 +12,6 @@
> > > ##
> > > !if $(REDFISH_ENABLE) == TRUE
> > > Ucs2Utf8Lib|RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > > + CrtLib|RedfishPkg/Library/CrtLib/CrtLib.inf
> > > !endif
> > >
> > > diff --git a/RedfishPkg/RedfishPkg.ci.yaml
> > > b/RedfishPkg/RedfishPkg.ci.yaml index 20c297ad22..9895fdac99 100644
> > > --- a/RedfishPkg/RedfishPkg.ci.yaml
> > > +++ b/RedfishPkg/RedfishPkg.ci.yaml
> > > @@ -17,6 +17,25 @@
> > > ],
> > > ## Both file path and directory path are accepted.
> > > "IgnoreFiles": [
> > > + ## Below are files incorporated with open source which are
> > > + ## not edk2 coding standard compliant.
> > > + ##
> > > + ## EDK2 CRT library which is not edk2 coding
> > > + ## standard compliant.
> > > + ## C runtime library for EDKII JsonLib.
> > > + "Include/Crt/sys",
> > > + "Include/Crt/assert.h",
> > > + "Include/Crt/errno.h",
> > > + "Include/Crt/limits.h",
> > > + "Include/Crt/math.h",
> > > + "Include/Crt/stdarg.h",
> > > + "Include/Crt/stddef.h",
> > > + "Include/Crt/stdio.h",
> > > + "Include/Crt/stdlib.h",
> > > + "Include/Crt/string.h",
> > > + "Include/Crt/time.h",
> > > + "Include/Library/CrtLib.h",
> > > + "Library/CrtLib/CrtLib.c"
> > > ]
> > > },
> > > "CompilerPlugin": {
> > > diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec
> > > index aecc1f4a3a..2142b43640 100644
> > > --- a/RedfishPkg/RedfishPkg.dec
> > > +++ b/RedfishPkg/RedfishPkg.dec
> > > @@ -15,16 +15,24 @@
> > >
> > > [Includes]
> > > Include
> > > + Include/Crt # Header files for C RTL.
> > >
> > > [LibraryClasses]
> > > ## @libraryclass Platform Redfish Host Interface Library
> > > # Platform implementation-specific Redfish Host Interface.
> > >
> > > RedfishPlatformHostInterfaceLib|Include/Library/RedfishHostInterfaceLi
> > > b.h
> > > +
> > > ## @libraryclass This library provides UCS2 to UTF8 manipulation
> > > # functions.
> > > #
> > > Ucs2Utf8Lib|Include/Library/BaseUcs2Utf8Lib.h
> > >
> > > + ## @libraryclass Provides the C runtime library functions
> > > + # CRT library is currently used by edk2 JsonLib (open source
> > > + # jansson project) and edk2 RedfishLib (libredfish open source
> > > + # project).
> > > + CrtLib|Include/Library/CrtLib.h
> > > +
> > > [Protocols]
> > > ## Include/Protocol/RedfishDiscover.h
> > > gEfiRedfishDiscoverProtocolGuid = { 0x5db12509, 0x4550, 0x4347,
> { 0x96,
> > 0xb3, 0x73, 0xc0, 0xff, 0x6e, 0x86, 0x9f
> > > }}
> > > diff --git a/RedfishPkg/RedfishPkg.dsc b/RedfishPkg/RedfishPkg.dsc
> > > index 3639b620e6..aa1ccd5a95 100644
> > > --- a/RedfishPkg/RedfishPkg.dsc
> > > +++ b/RedfishPkg/RedfishPkg.dsc
> > > @@ -48,5 +48,6 @@
> > > [Components]
> > >
> >
> RedfishPkg/Library/PlatformHostInterfaceLibNull/PlatformHostInterfaceLibN
> > ull.inf
> > > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > > + RedfishPkg/Library/CrtLib/CrtLib.inf
> > >
> > > !include RedfishPkg/Redfish.dsc.inc
> > > --
> > > 2.17.1
> > >
> > >
> > >
> > >
> > >
> >
> >
> >
> >
> >
>
>
>
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime library
2020-12-14 3:53 ` [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime library Abner Chang
2020-12-14 17:06 ` [edk2-devel] " Michael D Kinney
@ 2020-12-14 23:30 ` Michael D Kinney
2020-12-16 4:20 ` Abner Chang
2020-12-15 0:19 ` Michael D Kinney
2 siblings, 1 reply; 15+ messages in thread
From: Michael D Kinney @ 2020-12-14 23:30 UTC (permalink / raw)
To: devel@edk2.groups.io, abner.chang@hpe.com, Kinney, Michael D
Cc: Leif Lindholm, Nickle Wang, Peter O'Hanley
Hi Abner,
Comments included below.
Mike
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Abner Chang
> Sent: Sunday, December 13, 2020 7:53 PM
> To: devel@edk2.groups.io
> Cc: Leif Lindholm <leif@nuviainc.com>; Nickle Wang <nickle.wang@hpe.com>; Peter O'Hanley <peter.ohanley@hpe.com>
> Subject: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime library
>
> CRT library is currently used by edk2 JsonLib (open source
> jansson project) and edk2 RedfishLib (libredfish open source
> project). CrtLib library provides the necessary C runtime
> equivalent edk2 functions for open source projects.
>
> Signed-off-by: Abner Chang <abner.chang@hpe.com>
>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Nickle Wang <nickle.wang@hpe.com>
> Cc: Peter O'Hanley <peter.ohanley@hpe.com>
> ---
> RedfishPkg/Include/Crt/assert.h | 16 +
> RedfishPkg/Include/Crt/errno.h | 16 +
> RedfishPkg/Include/Crt/limits.h | 16 +
> RedfishPkg/Include/Crt/math.h | 16 +
> RedfishPkg/Include/Crt/stdarg.h | 15 +
> RedfishPkg/Include/Crt/stddef.h | 16 +
> RedfishPkg/Include/Crt/stdio.h | 15 +
> RedfishPkg/Include/Crt/stdlib.h | 16 +
> RedfishPkg/Include/Crt/string.h | 16 +
> RedfishPkg/Include/Crt/sys/time.h | 15 +
> RedfishPkg/Include/Crt/sys/types.h | 15 +
> RedfishPkg/Include/Crt/time.h | 15 +
> RedfishPkg/Include/Library/CrtLib.h | 195 ++++++++
> RedfishPkg/Library/CrtLib/CrtLib.c | 705 +++++++++++++++++++++++++++
> RedfishPkg/Library/CrtLib/CrtLib.inf | 37 ++
> RedfishPkg/RedfishLibs.dsc.inc | 1 +
> RedfishPkg/RedfishPkg.ci.yaml | 19 +
> RedfishPkg/RedfishPkg.dec | 8 +
> RedfishPkg/RedfishPkg.dsc | 1 +
> 19 files changed, 1153 insertions(+)
> create mode 100644 RedfishPkg/Include/Crt/assert.h
> create mode 100644 RedfishPkg/Include/Crt/errno.h
> create mode 100644 RedfishPkg/Include/Crt/limits.h
> create mode 100644 RedfishPkg/Include/Crt/math.h
> create mode 100644 RedfishPkg/Include/Crt/stdarg.h
> create mode 100644 RedfishPkg/Include/Crt/stddef.h
> create mode 100644 RedfishPkg/Include/Crt/stdio.h
> create mode 100644 RedfishPkg/Include/Crt/stdlib.h
> create mode 100644 RedfishPkg/Include/Crt/string.h
> create mode 100644 RedfishPkg/Include/Crt/sys/time.h
> create mode 100644 RedfishPkg/Include/Crt/sys/types.h
> create mode 100644 RedfishPkg/Include/Crt/time.h
> create mode 100644 RedfishPkg/Include/Library/CrtLib.h
> create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.c
> create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.inf
>
> diff --git a/RedfishPkg/Include/Crt/assert.h b/RedfishPkg/Include/Crt/assert.h
> new file mode 100644
> index 0000000000..f9ab7ef9ca
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/assert.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_ASSERT_H_
> +#define CRT_ASSERT_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/errno.h b/RedfishPkg/Include/Crt/errno.h
> new file mode 100644
> index 0000000000..d30aee14de
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/errno.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_ERRNO_H_
> +#define CRT_ERRNO_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/limits.h b/RedfishPkg/Include/Crt/limits.h
> new file mode 100644
> index 0000000000..f3bdd33f2a
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/limits.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_LIMITS_H_
> +#define CRT_LIMITS_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/math.h b/RedfishPkg/Include/Crt/math.h
> new file mode 100644
> index 0000000000..984c0ccc21
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/math.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_MATH_H_
> +#define CRT_MATH_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/stdarg.h b/RedfishPkg/Include/Crt/stdarg.h
> new file mode 100644
> index 0000000000..d5a314ad3b
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/stdarg.h
> @@ -0,0 +1,15 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef CRT_STDARG_H_
> +#define CRT_STDARG_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/stddef.h b/RedfishPkg/Include/Crt/stddef.h
> new file mode 100644
> index 0000000000..15a37bf50e
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/stddef.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_STDDEF_H_
> +#define CRT_STDDEF_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/stdio.h b/RedfishPkg/Include/Crt/stdio.h
> new file mode 100644
> index 0000000000..25e610be10
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/stdio.h
> @@ -0,0 +1,15 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef CRT_STDIO_H_
> +#define CRT_STDIO_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/stdlib.h b/RedfishPkg/Include/Crt/stdlib.h
> new file mode 100644
> index 0000000000..5b3dd273c8
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/stdlib.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_STDLIB_H_
> +#define CRT_STDLIB_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/string.h b/RedfishPkg/Include/Crt/string.h
> new file mode 100644
> index 0000000000..f60b87ccd2
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/string.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_STRING_H_
> +#define CRT_STRING_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/sys/time.h b/RedfishPkg/Include/Crt/sys/time.h
> new file mode 100644
> index 0000000000..4ced176cda
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/sys/time.h
> @@ -0,0 +1,15 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef CRT_SYS_TIME_H_
> +#define CRT_SYS_TIME_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/sys/types.h b/RedfishPkg/Include/Crt/sys/types.h
> new file mode 100644
> index 0000000000..c4f807214c
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/sys/types.h
> @@ -0,0 +1,15 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef CRT_SYS_TYPES_H_
> +#define CRT_SYS_TYPES_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/time.h b/RedfishPkg/Include/Crt/time.h
> new file mode 100644
> index 0000000000..ca04ac8730
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/time.h
> @@ -0,0 +1,15 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef CRT_TIME_H_
> +#define CRT_TIME_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Library/CrtLib.h b/RedfishPkg/Include/Library/CrtLib.h
> new file mode 100644
> index 0000000000..8c7484e75b
> --- /dev/null
> +++ b/RedfishPkg/Include/Library/CrtLib.h
> @@ -0,0 +1,195 @@
> +/** @file
> + CRT wrapper head functions for jansson system call.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_LIB_H_
> +#define CRT_LIB_H_
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PrintLib.h>
> +
> +#define MAX_STRING_SIZE 0x10000000
> +
> +// Minimum value for an object of type long long int.
> +#define LLONG_MIN MIN_INT64
> +
> +// Maximum value for an object of type long long int.
> +#define LLONG_MAX MAX_INT64
> +
> +// We dont support double on edk2
> +#define HUGE_VAL 0
> +
> +#if defined(MDE_CPU_X64) || defined(MDE_CPU_AARCH64) || defined(MDE_CPU_IA64) || defined(MDE_CPU_RISCV64)
> +//
> +// With GCC we would normally use SIXTY_FOUR_BIT_LONG, but MSVC needs
> +// SIXTY_FOUR_BIT, because 'long' is 32-bit and only 'long long' is
> +// 64-bit. Since using 'long long' works fine on GCC too, just do that.
> +//
> +#define SIXTY_FOUR_BIT
> +#elif defined(MDE_CPU_IA32) || defined(MDE_CPU_ARM) || defined(MDE_CPU_EBC)
> +#define THIRTY_TWO_BIT
> +#endif
> +
> +//
> +// Map all va_xxxx elements to VA_xxx defined in MdePkg/Include/Base.h
> +//
> +#if !defined(__CC_ARM) // if va_list is not already defined
> +#define va_list VA_LIST
> +#define va_arg VA_ARG
> +#define va_start VA_START
> +#define va_end VA_END
> +#else // __CC_ARM
> +#define va_start(Marker, Parameter) __va_start(Marker, Parameter)
> +#define va_arg(Marker, TYPE) __va_arg(Marker, TYPE)
> +#define va_end(Marker) ((void)0)
> +#endif
> +
> +//
> +// Definitions for global constants used by CRT library routines
> +//
> +#define INT_MAX MAX_INT32 /* Maximum (signed) int value */
> +#define LONG_MAX 0X7FFFFFFFL /* max value for a long */
> +#define LONG_MIN (-LONG_MAX-1) /* min value for a long */
> +#define ULONG_MAX 0xFFFFFFFF /* Maximum unsigned long value */
> +#define CHAR_BIT 8 /* Number of bits in a char */
> +
> +// Maximum value for an object of type unsigned long long int.
> +#define ULLONG_MAX 0xFFFFFFFFFFFFFFFFULL // 2^64 - 1
> +// Maximum value for an object of type unsigned char.
> +#define UCHAR_MAX 255 // 2^8 - 1
> +
> +//
> +// Basic types mapping
> +//
> +typedef UINTN size_t;
> +typedef INTN ssize_t;
> +typedef INT32 time_t;
> +typedef UINT8 __uint8_t;
> +typedef UINT8 sa_family_t;
> +typedef UINT32 uid_t;
> +typedef UINT32 gid_t;
> +typedef INT32 int32_t;
> +typedef UINT32 uint32_t;
> +typedef UINT16 uint16_t;
> +typedef UINT8 uint8_t;
> +typedef enum {false, true} bool;
> +
> +//
> +// File operations are not required for EFI building,
> +// so FILE is mapped to VOID * to pass build
> +//
> +typedef VOID *FILE;
> +
> +//
> +// Global variables
> +//
> +extern int errno;
> +extern FILE *stderr;
> +
> +//
> +// Function prototypes of CRT Library routines
> +//
> +void *malloc (size_t);
> +void *realloc (void *, size_t);
> +void *calloc (size_t Num, size_t Size);
> +void free (void *);
> +void *memset (void *, int, size_t);
> +int memcmp (const void *, const void *, size_t);
> +int isdigit (int);
> +int isspace (int);
> +int tolower (int);
> +int isupper (int);
> +int isxdigit (int);
> +int isalnum (int);
> +void *memcpy (void *, const void *, size_t);
> +void *memset (void *, int, size_t);
> +void *memchr (const void *, int, size_t);
> +int memcmp (const void *, const void *, size_t);
> +void *memmove (void *, const void *, size_t);
> +int strcmp (const char *, const char *);
> +int strncmp (const char *, const char *, size_t);
> +char *strcpy (char *, const char *);
> +size_t strlen (const char *);
> +char *strcat (char *, const char *);
> +char *strchr (const char *, int);
> +int strcasecmp (const char *, const char *);
> +int strncasecmp (const char *, const char *, size_t);
> +char *strncpy (char *, size_t, const char *, size_t);
> +int strncmp (const char *, const char *, size_t);
> +char *strrchr (const char *, int);
> +unsigned long strtoul (const char *, char **, int);
> +char * strstr (const char *s1 , const char *s2);
> +long strtol (const char *, char **, int);
> +char *strerror (int);
> +size_t strspn (const char *, const char *);
> +char * strdup (const char *str);
> +char * strpbrk (const char *s1, const char *s2);
> +unsigned long long strtoull(const char * nptr, char ** endptr, int base);
> +long long strtoll (const char * nptr, char ** endptr, int base);
> +long strtol (const char * nptr, char ** endptr, int base);
> +double strtod (const char * __restrict nptr, char ** __restrict endptr);
> +size_t strcspn (const char *, const char *);
> +int printf (const char *, ...);
> +int sscanf (const char *, const char *, ...);
> +FILE *fopen (const char *, const char *);
> +size_t fread (void *, size_t, size_t, FILE *);
> +size_t fwrite (const void *, size_t, size_t, FILE *);
> +int fclose (FILE *);
> +int fprintf (FILE *, const char *, ...);
> +int fgetc (FILE * _File);
> +uid_t getuid (void);
> +uid_t geteuid (void);
> +gid_t getgid (void);
> +gid_t getegid (void);
> +void qsort (void *, size_t, size_t, int (*)(const void *, const void *));
> +char *getenv (const char *);
> +#if defined(__GNUC__) && (__GNUC__ >= 2)
> +void abort (void) __attribute__((__noreturn__));
> +#else
> +void abort (void);
> +#endif
> +int toupper (int);
> +int Digit2Val (int);
> +time_t time (time_t *);
> +
> +//
> +// Macros that directly map functions to BaseLib, BaseMemoryLib, and DebugLib functions
> +//
> +#define strcmp AsciiStrCmp
> +#define memcpy(dest,source,count) CopyMem(dest,source,(UINTN)(count))
> +#define memset(dest,ch,count) SetMem(dest,(UINTN)(count),(UINT8)(ch))
> +#define memchr(buf,ch,count) ScanMem8(buf,(UINTN)(count),(UINT8)ch)
> +#define memcmp(buf1,buf2,count) (int)(CompareMem(buf1,buf2,(UINTN)(count)))
> +#define memmove(dest,source,count) CopyMem(dest,source,(UINTN)(count))
> +#define strlen(str) (size_t)(AsciiStrnLenS(str,MAX_STRING_SIZE))
What is MAX_STRING_SIZE? How do you know there are no buffer overruns looking for the end
of the string? I guess this is more of a jansson lib question???
> +#define strcpy(strDest,strSource) AsciiStrCpyS(strDest,(strlen(strSource)+1),strSource)
> +#define strncpy(strDest,strSource,count) AsciiStrnCpyS(strDest,(UINTN)count,strSource,(UINTN)count)
> +#define strncpys(strDest, DestLen, strSource,count) AsciiStrnCpyS(strDest,DestLen,strSource,(UINTN)count)
> +#define strcat(strDest,strSource) AsciiStrCatS(strDest,(strlen(strSource)+strlen(strDest)+1),strSource)
> +#define strchr(str,ch) ScanMem8((VOID *)(str),AsciiStrSize(str),(UINT8)ch)
> +#define strncmp(string1,string2,count) (int)(AsciiStrnCmp(string1,string2,(UINTN)(count)))
> +#define strcasecmp(str1,str2) (int)AsciiStriCmp(str1,str2)
> +#define strstr(s1,s2) AsciiStrStr(s1,s2)
> +#define sprintf(buf,...) AsciiSPrint(buf,MAX_STRING_SIZE,__VA_ARGS__)
> +#define snprintf(buf,len,...) AsciiSPrint(buf,len,__VA_ARGS__)
> +#define vsnprintf(buf,len,format,marker) AsciiVSPrint((buf),(len),(format),(marker))
The EDK II PrintLib format string is not identical to libc printf() format string.
Are you sure the usage by jansson is compatible?
> +#define assert(expression) ASSERT(expression)
> +#define atoi(nptr) AsciiStrDecimalToUintn(nptr)
Is this really compatible in behavior?
> +#define fabs(x) (((x) < 0.0)? (-x): (x))
Is fabs() actually used? Using floating point from UEFI/PI environment is complex
and requires interrupts to be disabled/restored and potentially some context
save/restore around use of floating point registers. If there is anyways to
eliminate all uses of floating point, that would be much better.
> +#define offsetof(type,member) OFFSET_OF(type,member)
> +
> +#define EOF (-1)
> +
> +extern int errno;
> +
> +#define ERANGE 34 /* 34 Result too large */
> +
> +#endif
> diff --git a/RedfishPkg/Library/CrtLib/CrtLib.c b/RedfishPkg/Library/CrtLib/CrtLib.c
> new file mode 100644
> index 0000000000..1ff4023dbe
> --- /dev/null
> +++ b/RedfishPkg/Library/CrtLib/CrtLib.c
> @@ -0,0 +1,705 @@
> +/** @file
> + CRT wrapper functions for system call.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#include <Uefi.h>
> +#include <Library/CrtLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +
> +int errno = 0;
> +
> +/**
> + Determine if a particular character is an alphanumeric character
> + @return Returns 1 if c is an alphanumeric character, otherwise returns 0.
> +**/
> +int isalnum (int c)
> +{
> + //
> + // <alnum> ::= [0-9] | [a-z] | [A-Z]
> + //
> + return ((('0' <= (c)) && ((c) <= '9')) ||
> + (('a' <= (c)) && ((c) <= 'z')) ||
> + (('A' <= (c)) && ((c) <= 'Z')));
> +}
> +
> +/**
> + Determine if a particular character is a digital character
> +
> + @return Returns 1 if c is an digital character, otherwise returns 0.
> +**/
> +int isdchar (int c)
> +{
> + //
> + // [0-9] | [e +-.]
> + //
> + return ((('0' <= (c)) && ((c) <= '9')) ||
> + (c == 'e') || (c == 'E') ||
> + (c == '+') || (c == '-') ||
> + (c == '.'));
> +}
> +
> +/**
> + Determine if a particular character is a space character
> +
> + @return Returns 1 if c is a space character
> +**/
> +int isspace (int c)
> +{
> + //
> + // <space> ::= [ ]
> + //
> + return ((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) == '\n') || ((c) == '\v') || ((c) == '\f');
> +}
> +
> +/**
> + Allocates memory blocks
> +*/
> +void *malloc (size_t size)
> +{
> + return AllocatePool ((UINTN) size);
> +}
> +
> +/**
> + De-allocates or frees a memory block
> +*/
> +void free (void *ptr)
> +{
> + //
> + // In Standard C, free() handles a null pointer argument transparently. This
> + // is not true of FreePool() below, so protect it.
> + //
> + if (ptr != NULL) {
> + FreePool (ptr);
> + }
> +}
> +
> +/**
> + NetBSD Compatibility Function strdup creates a duplicate copy of a string.
> +
> + @return Returns the pointer to duplicated string.
> +**/
> +char * strdup(const char *str)
> +{
> + size_t len;
> + char *copy;
> +
> + len = strlen(str) + 1;
> + if ((copy = malloc(len)) == NULL)
> + return (NULL);
> + memcpy(copy, str, len);
> + return (copy);
> +}
> +
> +/** The toupper function converts a lowercase letter to a corresponding
> + uppercase letter.
> +
> + @param[in] c The character to be converted.
> +
> + @return If the argument is a character for which islower is true and
> + there are one or more corresponding characters, as specified by
> + the current locale, for which isupper is true, the toupper
> + function returns one of the corresponding characters (always the
> + same one for any given locale); otherwise, the argument is
> + returned unchanged.
> +**/
> +int
> +toupper(
> + IN int c
> + )
> +{
> + if ( (c >= 'a') && (c <= 'z') ) {
> + c = c - ('a' - 'A');
> + }
> + return c;
> +}
> +
> +/**
> + Digit to a value.
> +
> + @return Returns the value of digit.
> +**/
> +int
> +Digit2Val( int c)
> +{
> + if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))) { /* If c is one of [A-Za-z]... */
> + c = toupper(c) - 7; // Adjust so 'A' is ('9' + 1)
> + }
> + return c - '0'; // Value returned is between 0 and 35, inclusive.
> +}
> +
> +
> +/** The strtoll function converts the initial portion of the string pointed to
> + by nptr to long long int representation.
> +
> + See the description for strtol for more information.
> +
> + @return The strtoll function returns the converted value, if any. If no
> + conversion could be performed, zero is returned. If the correct
> + value is outside the range of representable values, LLONG_MIN or
> + LLONG_MAX is returned (according to the sign of the value, if any),
> + and the value of the macro ERANGE is stored in errno.
> +**/
> +long long
> +strtoll(const char * nptr, char ** endptr, int base)
> +{
> + const char *pEnd;
> + long long Result = 0;
> + long long Previous;
> + int temp;
> + BOOLEAN Negative = FALSE;
> +
> + pEnd = nptr;
> +
> + if((base < 0) || (base == 1) || (base > 36)) {
> + if(endptr != NULL) {
> + *endptr = NULL;
> + }
> + return 0;
> + }
> + // Skip leading spaces.
> + while(isspace(*nptr)) ++nptr;
> +
> + // Process Subject sequence: optional sign followed by digits.
> + if(*nptr == '+') {
> + Negative = FALSE;
> + ++nptr;
> + }
> + else if(*nptr == '-') {
> + Negative = TRUE;
> + ++nptr;
> + }
> +
> + if(*nptr == '0') { /* Might be Octal or Hex */
> + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> + if((base == 0) || (base == 16)) {
> + nptr += 2; /* Skip the "0X" */
> + base = 16; /* In case base was 0 */
> + }
> + }
> + else { /* Looks like Octal */
> + if((base == 0) || (base == 8)) {
> + ++nptr; /* Skip the leading "0" */
> + base = 8; /* In case base was 0 */
> + }
> + }
> + }
> + if(base == 0) { /* If still zero then must be decimal */
> + base = 10;
> + }
> + if(*nptr == '0') {
> + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> + pEnd = nptr;
> + }
> +
> + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> + Previous = Result;
> + Result = MultS64x64 (Result, base) + (long long int)temp;
> + if( Result <= Previous) { // Detect Overflow
> + if(Negative) {
> + Result = LLONG_MIN;
> + }
> + else {
> + Result = LLONG_MAX;
> + }
> + Negative = FALSE;
> + errno = ERANGE;
> + break;
> + }
> + pEnd = ++nptr;
> + }
> + if(Negative) {
> + Result = -Result;
> + }
> +
> + // Save pointer to final sequence
> + if(endptr != NULL) {
> + *endptr = (char *)pEnd;
> + }
> + return Result;
> +}
> +
> +/** The strtol, strtoll, strtoul, and strtoull functions convert the initial
> + portion of the string pointed to by nptr to long int, long long int,
> + unsigned long int, and unsigned long long int representation, respectively.
> + First, they decompose the input string into three parts: an initial,
> + possibly empty, sequence of white-space characters (as specified by the
> + isspace function), a subject sequence resembling an integer represented in
> + some radix determined by the value of base, and a final string of one or
> + more unrecognized characters, including the terminating null character of
> + the input string. Then, they attempt to convert the subject sequence to an
> + integer, and return the result.
> +
> + If the value of base is zero, the expected form of the subject sequence is
> + that of an integer constant, optionally preceded
> + by a plus or minus sign, but not including an integer suffix. If the value
> + of base is between 2 and 36 (inclusive), the expected form of the subject
> + sequence is a sequence of letters and digits representing an integer with
> + the radix specified by base, optionally preceded by a plus or minus sign,
> + but not including an integer suffix. The letters from a (or A) through z
> + (or Z) are ascribed the values 10 through 35; only letters and digits whose
> + ascribed values are less than that of base are permitted. If the value of
> + base is 16, the characters 0x or 0X may optionally precede the sequence of
> + letters and digits, following the sign if present.
> +
> + The subject sequence is defined as the longest initial subsequence of the
> + input string, starting with the first non-white-space character, that is of
> + the expected form. The subject sequence contains no characters if the input
> + string is empty or consists entirely of white space, or if the first
> + non-white-space character is other than a sign or a permissible letter or digit.
> +
> + If the subject sequence has the expected form and the value of base is
> + zero, the sequence of characters starting with the first digit is
> + interpreted as an integer constant. If the subject sequence has the
> + expected form and the value of base is between 2 and 36, it is used as the
> + base for conversion, ascribing to each letter its value as given above. If
> + the subject sequence begins with a minus sign, the value resulting from the
> + conversion is negated (in the return type). A pointer to the final string
> + is stored in the object pointed to by endptr, provided that endptr is
> + not a null pointer.
> +
> + In other than the "C" locale, additional locale-specific subject sequence
> + forms may be accepted.
> +
> + If the subject sequence is empty or does not have the expected form, no
> + conversion is performed; the value of nptr is stored in the object pointed
> + to by endptr, provided that endptr is not a null pointer.
> +
> + @return The strtol, strtoll, strtoul, and strtoull functions return the
> + converted value, if any. If no conversion could be performed, zero
> + is returned. If the correct value is outside the range of
> + representable values, LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX,
> + ULONG_MAX, or ULLONG_MAX is returned (according to the return type
> + and sign of the value, if any), and the value of the macro ERANGE
> + is stored in errno.
> +**/
> +long
> +strtol(const char * nptr, char ** endptr, int base)
> +{
> + const char *pEnd;
> + long Result = 0;
> + long Previous;
> + int temp;
> + BOOLEAN Negative = FALSE;
> +
> + pEnd = nptr;
> +
> + if((base < 0) || (base == 1) || (base > 36)) {
> + if(endptr != NULL) {
> + *endptr = NULL;
> + }
> + return 0;
> + }
> + // Skip leading spaces.
> + while(isspace(*nptr)) ++nptr;
> +
> + // Process Subject sequence: optional sign followed by digits.
> + if(*nptr == '+') {
> + Negative = FALSE;
> + ++nptr;
> + }
> + else if(*nptr == '-') {
> + Negative = TRUE;
> + ++nptr;
> + }
> +
> + if(*nptr == '0') { /* Might be Octal or Hex */
> + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> + if((base == 0) || (base == 16)) {
> + nptr += 2; /* Skip the "0X" */
> + base = 16; /* In case base was 0 */
> + }
> + }
> + else { /* Looks like Octal */
> + if((base == 0) || (base == 8)) {
> + ++nptr; /* Skip the leading "0" */
> + base = 8; /* In case base was 0 */
> + }
> + }
> + }
> + if(base == 0) { /* If still zero then must be decimal */
> + base = 10;
> + }
> + if(*nptr == '0') {
> + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> + pEnd = nptr;
> + }
> +
> + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> + Previous = Result;
> + Result = (Result * base) + (long int)temp;
> + if( Result <= Previous) { // Detect Overflow
> + if(Negative) {
> + Result = LONG_MIN;
> + }
> + else {
> + Result = LONG_MAX;
> + }
> + Negative = FALSE;
> + errno = ERANGE;
> + break;
> + }
> + pEnd = ++nptr;
> + }
> + if(Negative) {
> + Result = -Result;
> + }
> +
> + // Save pointer to final sequence
> + if(endptr != NULL) {
> + *endptr = (char *)pEnd;
> + }
> + return Result;
> +}
> +
> +/** The strtoull function converts the initial portion of the string pointed to
> + by nptr to unsigned long long int representation.
> +
> + See the description for strtol for more information.
> +
> + @return The strtoull function returns the converted value, if any. If no
> + conversion could be performed, zero is returned. If the correct
> + value is outside the range of representable values, ULLONG_MAX is
> + returned and the value of the macro ERANGE is stored in errno.
> +**/
> +unsigned long long
> +strtoull(const char * nptr, char ** endptr, int base)
> +{
> + const char *pEnd;
> + unsigned long long Result = 0;
> + unsigned long long Previous;
> + int temp;
> +
> + pEnd = nptr;
> +
> + if((base < 0) || (base == 1) || (base > 36)) {
> + if(endptr != NULL) {
> + *endptr = NULL;
> + }
> + return 0;
> + }
> + // Skip leading spaces.
> + while(isspace(*nptr)) ++nptr;
> +
> + // Process Subject sequence: optional + sign followed by digits.
> + if(*nptr == '+') {
> + ++nptr;
> + }
> +
> + if(*nptr == '0') { /* Might be Octal or Hex */
> + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> + if((base == 0) || (base == 16)) {
> + nptr += 2; /* Skip the "0X" */
> + base = 16; /* In case base was 0 */
> + }
> + }
> + else { /* Looks like Octal */
> + if((base == 0) || (base == 8)) {
> + ++nptr; /* Skip the leading "0" */
> + base = 8; /* In case base was 0 */
> + }
> + }
> + }
> + if(base == 0) { /* If still zero then must be decimal */
> + base = 10;
> + }
> + if(*nptr == '0') {
> + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> + pEnd = nptr;
> + }
> +
> + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> + Previous = Result;
> + Result = DivU64x32 (Result, base) + (unsigned long long)temp;
> + if( Result < Previous) { // If we overflowed
> + Result = ULLONG_MAX;
> + errno = ERANGE;
> + break;
> + }
> + pEnd = ++nptr;
> + }
> +
> + // Save pointer to final sequence
> + if(endptr != NULL) {
> + *endptr = (char *)pEnd;
> + }
> + return Result;
> +}
> +
> +/**
> + edk2 Jansson port does not support doubles, simply return 0.
> +
> + These conversion functions convert the initial portion of the string
> + pointed to by nptr to double, float, and long double representation,
> + respectively.
> +
> + The strtod(), strtof(), and strtold() functions return the converted
> + value, if any.
> +
> + If endptr is not NULL, a pointer to the character after the last charac-
> + ter used in the conversion is stored in the location referenced by
> + endptr.
> +
> + If no conversion is performed, zero is returned and the value of nptr is
> + stored in the location referenced by endptr.
> +
> + If the correct value would cause overflow, plus or minus HUGE_VAL,
> + HUGE_VALF, or HUGE_VALL is returned (according to the sign and type of
> + the return value), and ERANGE is stored in errno. If the correct value
> + would cause underflow, zero is returned and ERANGE is stored in errno.
> +
> + @return Return 0.
> +**/
> +double
> +strtod (const char * __restrict nptr, char ** __restrict endptr) {
> + if(endptr)
> + *endptr = (char *)(nptr + strlen(nptr));
> +
> + return (double)0;
> +}
Even the use of the type double to return 0 has issues in UEFI/PI.
Can you figure out how to remove the use of strtod() by jansson?
> +
> +/**
> + Allocate and zero-initialize array.
> +**/
> +void *
> +calloc(size_t Num, size_t Size)
> +{
> + void *RetVal;
> + size_t NumSize;
> +
> + NumSize = Num * Size;
> + RetVal = NULL;
> + if (NumSize != 0) {
> + RetVal = malloc(NumSize);
> + if( RetVal != NULL) {
> + (VOID)ZeroMem( RetVal, NumSize);
> + }
> + }
> + DEBUG((DEBUG_POOL, "0x%p = calloc(%d, %d)\n", RetVal, Num, Size));
> +
> + return RetVal;
> +}
> +
> +//
> +// The arrays give the cumulative number of days up to the first of the
> +// month number used as the index (1 -> 12) for regular and leap years.
> +// The value at index 13 is for the whole year.
> +//
> +UINTN CumulativeDays[2][14] = {
> + {
> + 0,
> + 0,
> + 31,
> + 31 + 28,
> + 31 + 28 + 31,
> + 31 + 28 + 31 + 30,
> + 31 + 28 + 31 + 30 + 31,
> + 31 + 28 + 31 + 30 + 31 + 30,
> + 31 + 28 + 31 + 30 + 31 + 30 + 31,
> + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
> + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
> + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
> + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
> + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
> + },
> + {
> + 0,
> + 0,
> + 31,
> + 31 + 29,
> + 31 + 29 + 31,
> + 31 + 29 + 31 + 30,
> + 31 + 29 + 31 + 30 + 31,
> + 31 + 29 + 31 + 30 + 31 + 30,
> + 31 + 29 + 31 + 30 + 31 + 30 + 31,
> + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,
> + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
> + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
> + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
> + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
> + }
> +};
> +
> +#define IsLeap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
> +#define SECSPERMIN (60)
> +#define SECSPERHOUR (60 * 60)
> +#define SECSPERDAY (24 * SECSPERHOUR)
> +
> +/**
> + Get the system time as seconds elapsed since midnight, January 1, 1970.
> +**/
> +time_t time (time_t *timer)
> +{
> + EFI_TIME Time;
> + time_t CalTime;
> + UINTN Year;
> +
> + //
> + // Get the current time and date information
> + //
> + gRT->GetTime (&Time, NULL);
> +
> + //
> + // Years Handling
> + // UTime should now be set to 00:00:00 on Jan 1 of the current year.
> + //
> + for (Year = 1970, CalTime = 0; Year != Time.Year; Year++) {
> + CalTime = CalTime + (time_t)(CumulativeDays[IsLeap(Year)][13] * SECSPERDAY);
> + }
> +
> + //
> + // Add in number of seconds for current Month, Day, Hour, Minute, Seconds, and TimeZone adjustment
> + //
> + CalTime = CalTime +
> + (time_t)((Time.TimeZone != EFI_UNSPECIFIED_TIMEZONE) ? (Time.TimeZone * 60) : 0) +
> + (time_t)(CumulativeDays[IsLeap(Time.Year)][Time.Month] * SECSPERDAY) +
> + (time_t)(((Time.Day > 0) ? Time.Day - 1 : 0) * SECSPERDAY) +
> + (time_t)(Time.Hour * SECSPERHOUR) +
> + (time_t)(Time.Minute * 60) +
> + (time_t)Time.Second;
> +
> + if (timer != NULL) {
> + *timer = CalTime;
> + }
> +
> + return CalTime;
> +}
> +
> +typedef
> +int
> +(*SORT_COMPARE)(
> + IN VOID *Buffer1,
> + IN VOID *Buffer2
> + );
> +
> +/**
> + Duplicated from EDKII BaseSortLib for qsort() wrapper
> + @param[in, out] BufferToSort on call a Buffer of (possibly sorted) elements
> + on return a buffer of sorted elements
> + @param[in] Count the number of elements in the buffer to sort
> + @param[in] ElementSize Size of an element in bytes
> + @param[in] CompareFunction The function to call to perform the comparison
> + of any 2 elements
> + @param[in] Buffer Buffer of size ElementSize for use in swapping
> +**/
> +STATIC
> +VOID
> +QuickSortWorker (
> + IN OUT VOID *BufferToSort,
> + IN CONST UINTN Count,
> + IN CONST UINTN ElementSize,
> + IN SORT_COMPARE CompareFunction,
> + IN VOID *Buffer
> + )
> +{
> + VOID *Pivot;
> + UINTN LoopCount;
> + UINTN NextSwapLocation;
> +
> + ASSERT(BufferToSort != NULL);
> + ASSERT(CompareFunction != NULL);
> + ASSERT(Buffer != NULL);
> +
> + if (Count < 2 || ElementSize < 1) {
> + return;
> + }
> +
> + NextSwapLocation = 0;
> +
> + //
> + // Pick a pivot (we choose last element)
> + //
> + Pivot = ((UINT8 *)BufferToSort + ((Count - 1) * ElementSize));
> +
> + //
> + // Now get the pivot such that all on "left" are below it
> + // and everything "right" are above it
> + //
> + for (LoopCount = 0; LoopCount < Count - 1; LoopCount++)
> + {
> + //
> + // If the element is less than the pivot
> + //
> + if (CompareFunction ((VOID *)((UINT8 *)BufferToSort + ((LoopCount) * ElementSize)), Pivot) <= 0) {
> + //
> + // Swap
> + //
> + CopyMem (Buffer, (UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), ElementSize);
> + CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), (UINT8 *)BufferToSort + ((LoopCount) *
> ElementSize), ElementSize);
> + CopyMem ((UINT8 *)BufferToSort + ((LoopCount) * ElementSize), Buffer, ElementSize);
> +
> + //
> + // Increment NextSwapLocation
> + //
> + NextSwapLocation++;
> + }
> + }
> + //
> + // Swap pivot to it's final position (NextSwapLocaiton)
> + //
> + CopyMem (Buffer, Pivot, ElementSize);
> + CopyMem (Pivot, (UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), ElementSize);
> + CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), Buffer, ElementSize);
> +
> + //
> + // Now recurse on 2 paritial lists. Neither of these will have the 'pivot' element.
> + // IE list is sorted left half, pivot element, sorted right half...
> + //
> + QuickSortWorker (
> + BufferToSort,
> + NextSwapLocation,
> + ElementSize,
> + CompareFunction,
> + Buffer
> + );
> +
> + QuickSortWorker (
> + (UINT8 *)BufferToSort + (NextSwapLocation + 1) * ElementSize,
> + Count - NextSwapLocation - 1,
> + ElementSize,
> + CompareFunction,
> + Buffer
> + );
> +
> + return;
> +}
> +
> +/**
> + Performs a quick sort
> +**/
> +void qsort (void *base, size_t num, size_t width, int (*compare)(const void *, const void *))
> +{
> + VOID *Buffer;
> +
> + ASSERT (base != NULL);
> + ASSERT (compare != NULL);
> +
> + //
> + // Use CRT-style malloc to cover BS and RT memory allocation.
> + //
> + Buffer = malloc (width);
> + ASSERT (Buffer != NULL);
> +
> + //
> + // Re-use PerformQuickSort() function Implementation in EDKII BaseSortLib.
> + //
> + QuickSortWorker (base, (UINTN)num, (UINTN)width, (SORT_COMPARE)compare, Buffer);
> +
> + free (Buffer);
> + return;
> +}
> +
> +/**
> + Get character from stream, we don't support file operastion on edk2 JSON library.
> +
> + @return Returns the character currently pointed by the internal file position indicator of the specified stream
> +
> +**/
> +int fgetc(FILE * _File){
> + return 0;
> +}
> diff --git a/RedfishPkg/Library/CrtLib/CrtLib.inf b/RedfishPkg/Library/CrtLib/CrtLib.inf
> new file mode 100644
> index 0000000000..b514817cf4
> --- /dev/null
> +++ b/RedfishPkg/Library/CrtLib/CrtLib.inf
> @@ -0,0 +1,37 @@
> +## @file
> +# EDK2 C Runtime Library for opensource project.
> +#
> +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +# (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x0001001b
> + BASE_NAME = CrtLib
> + FILE_GUID = 8263B8AC-D021-425D-B337-3EC96F5DC19B
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = CrtLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION
> UEFI_DRIVER
> +
> +#
> +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64
> +#
> +
> +[Sources]
> + CrtLib.c
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> + MemoryAllocationLib
> + UefiRuntimeServicesTableLib
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + RedfishPkg/RedfishPkg.dec
> +
> +
> diff --git a/RedfishPkg/RedfishLibs.dsc.inc b/RedfishPkg/RedfishLibs.dsc.inc
> index d4c08e18ac..2a951bd8fa 100644
> --- a/RedfishPkg/RedfishLibs.dsc.inc
> +++ b/RedfishPkg/RedfishLibs.dsc.inc
> @@ -12,5 +12,6 @@
> ##
> !if $(REDFISH_ENABLE) == TRUE
> Ucs2Utf8Lib|RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> + CrtLib|RedfishPkg/Library/CrtLib/CrtLib.inf
> !endif
>
> diff --git a/RedfishPkg/RedfishPkg.ci.yaml b/RedfishPkg/RedfishPkg.ci.yaml
> index 20c297ad22..9895fdac99 100644
> --- a/RedfishPkg/RedfishPkg.ci.yaml
> +++ b/RedfishPkg/RedfishPkg.ci.yaml
> @@ -17,6 +17,25 @@
> ],
> ## Both file path and directory path are accepted.
> "IgnoreFiles": [
> + ## Below are files incorporated with open source which are
> + ## not edk2 coding standard compliant.
> + ##
> + ## EDK2 CRT library which is not edk2 coding
> + ## standard compliant.
> + ## C runtime library for EDKII JsonLib.
> + "Include/Crt/sys",
> + "Include/Crt/assert.h",
> + "Include/Crt/errno.h",
> + "Include/Crt/limits.h",
> + "Include/Crt/math.h",
> + "Include/Crt/stdarg.h",
> + "Include/Crt/stddef.h",
> + "Include/Crt/stdio.h",
> + "Include/Crt/stdlib.h",
> + "Include/Crt/string.h",
> + "Include/Crt/time.h",
> + "Include/Library/CrtLib.h",
> + "Library/CrtLib/CrtLib.c"
> ]
> },
> "CompilerPlugin": {
> diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec
> index aecc1f4a3a..2142b43640 100644
> --- a/RedfishPkg/RedfishPkg.dec
> +++ b/RedfishPkg/RedfishPkg.dec
> @@ -15,16 +15,24 @@
>
> [Includes]
> Include
> + Include/Crt # Header files for C RTL.
>
> [LibraryClasses]
> ## @libraryclass Platform Redfish Host Interface Library
> # Platform implementation-specific Redfish Host Interface.
> RedfishPlatformHostInterfaceLib|Include/Library/RedfishHostInterfaceLib.h
> +
> ## @libraryclass This library provides UCS2 to UTF8 manipulation
> # functions.
> #
> Ucs2Utf8Lib|Include/Library/BaseUcs2Utf8Lib.h
>
> + ## @libraryclass Provides the C runtime library functions
> + # CRT library is currently used by edk2 JsonLib (open source
> + # jansson project) and edk2 RedfishLib (libredfish open source
> + # project).
> + CrtLib|Include/Library/CrtLib.h
> +
> [Protocols]
> ## Include/Protocol/RedfishDiscover.h
> gEfiRedfishDiscoverProtocolGuid = { 0x5db12509, 0x4550, 0x4347, { 0x96, 0xb3, 0x73, 0xc0, 0xff, 0x6e, 0x86, 0x9f
> }}
> diff --git a/RedfishPkg/RedfishPkg.dsc b/RedfishPkg/RedfishPkg.dsc
> index 3639b620e6..aa1ccd5a95 100644
> --- a/RedfishPkg/RedfishPkg.dsc
> +++ b/RedfishPkg/RedfishPkg.dsc
> @@ -48,5 +48,6 @@
> [Components]
> RedfishPkg/Library/PlatformHostInterfaceLibNull/PlatformHostInterfaceLibNull.inf
> RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> + RedfishPkg/Library/CrtLib/CrtLib.inf
>
> !include RedfishPkg/Redfish.dsc.inc
> --
> 2.17.1
>
>
>
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime library
2020-12-14 23:30 ` Michael D Kinney
@ 2020-12-16 4:20 ` Abner Chang
0 siblings, 0 replies; 15+ messages in thread
From: Abner Chang @ 2020-12-16 4:20 UTC (permalink / raw)
To: devel@edk2.groups.io, michael.d.kinney@intel.com
Cc: Leif Lindholm, Wang, Nickle (HPS SW), O'Hanley, Peter (EXL)
> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Michael D Kinney
> Sent: Tuesday, December 15, 2020 7:30 AM
> To: devel@edk2.groups.io; Chang, Abner (HPS SW/FW Technologist)
> <abner.chang@hpe.com>; Kinney, Michael D <michael.d.kinney@intel.com>
> Cc: Leif Lindholm <leif@nuviainc.com>; Wang, Nickle (HPS SW)
> <nickle.wang@hpe.com>; O'Hanley, Peter (EXL) <peter.ohanley@hpe.com>
> Subject: Re: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime library
>
> Hi Abner,
>
> Comments included below.
>
> Mike
>
>
>
> > -----Original Message-----
> > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Abner
> > Chang
> > Sent: Sunday, December 13, 2020 7:53 PM
> > To: devel@edk2.groups.io
> > Cc: Leif Lindholm <leif@nuviainc.com>; Nickle Wang
> > <nickle.wang@hpe.com>; Peter O'Hanley <peter.ohanley@hpe.com>
> > Subject: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime
> > library
> >
> > CRT library is currently used by edk2 JsonLib (open source jansson
> > project) and edk2 RedfishLib (libredfish open source project). CrtLib
> > library provides the necessary C runtime equivalent edk2 functions for
> > open source projects.
> >
> > Signed-off-by: Abner Chang <abner.chang@hpe.com>
> >
> > Cc: Leif Lindholm <leif@nuviainc.com>
> > Cc: Nickle Wang <nickle.wang@hpe.com>
> > Cc: Peter O'Hanley <peter.ohanley@hpe.com>
> > ---
> > RedfishPkg/Include/Crt/assert.h | 16 +
> > RedfishPkg/Include/Crt/errno.h | 16 +
> > RedfishPkg/Include/Crt/limits.h | 16 +
> > RedfishPkg/Include/Crt/math.h | 16 +
> > RedfishPkg/Include/Crt/stdarg.h | 15 +
> > RedfishPkg/Include/Crt/stddef.h | 16 +
> > RedfishPkg/Include/Crt/stdio.h | 15 +
> > RedfishPkg/Include/Crt/stdlib.h | 16 +
> > RedfishPkg/Include/Crt/string.h | 16 +
> > RedfishPkg/Include/Crt/sys/time.h | 15 +
> > RedfishPkg/Include/Crt/sys/types.h | 15 +
> > RedfishPkg/Include/Crt/time.h | 15 +
> > RedfishPkg/Include/Library/CrtLib.h | 195 ++++++++
> > RedfishPkg/Library/CrtLib/CrtLib.c | 705
> +++++++++++++++++++++++++++
> > RedfishPkg/Library/CrtLib/CrtLib.inf | 37 ++
> > RedfishPkg/RedfishLibs.dsc.inc | 1 +
> > RedfishPkg/RedfishPkg.ci.yaml | 19 +
> > RedfishPkg/RedfishPkg.dec | 8 +
> > RedfishPkg/RedfishPkg.dsc | 1 +
> > 19 files changed, 1153 insertions(+)
> > create mode 100644 RedfishPkg/Include/Crt/assert.h create mode
> > 100644 RedfishPkg/Include/Crt/errno.h create mode 100644
> > RedfishPkg/Include/Crt/limits.h create mode 100644
> > RedfishPkg/Include/Crt/math.h create mode 100644
> > RedfishPkg/Include/Crt/stdarg.h create mode 100644
> > RedfishPkg/Include/Crt/stddef.h create mode 100644
> > RedfishPkg/Include/Crt/stdio.h create mode 100644
> > RedfishPkg/Include/Crt/stdlib.h create mode 100644
> > RedfishPkg/Include/Crt/string.h create mode 100644
> > RedfishPkg/Include/Crt/sys/time.h create mode 100644
> > RedfishPkg/Include/Crt/sys/types.h
> > create mode 100644 RedfishPkg/Include/Crt/time.h create mode 100644
> > RedfishPkg/Include/Library/CrtLib.h
> > create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.c
> > create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.inf
> >
> > diff --git a/RedfishPkg/Include/Crt/assert.h
> > b/RedfishPkg/Include/Crt/assert.h new file mode 100644 index
> > 0000000000..f9ab7ef9ca
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/assert.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_ASSERT_H_
> > +#define CRT_ASSERT_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/errno.h
> > b/RedfishPkg/Include/Crt/errno.h new file mode 100644 index
> > 0000000000..d30aee14de
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/errno.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_ERRNO_H_
> > +#define CRT_ERRNO_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/limits.h
> > b/RedfishPkg/Include/Crt/limits.h new file mode 100644 index
> > 0000000000..f3bdd33f2a
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/limits.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_LIMITS_H_
> > +#define CRT_LIMITS_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/math.h
> > b/RedfishPkg/Include/Crt/math.h new file mode 100644 index
> > 0000000000..984c0ccc21
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/math.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_MATH_H_
> > +#define CRT_MATH_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/stdarg.h
> > b/RedfishPkg/Include/Crt/stdarg.h new file mode 100644 index
> > 0000000000..d5a314ad3b
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/stdarg.h
> > @@ -0,0 +1,15 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#ifndef CRT_STDARG_H_
> > +#define CRT_STDARG_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/stddef.h
> > b/RedfishPkg/Include/Crt/stddef.h new file mode 100644 index
> > 0000000000..15a37bf50e
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/stddef.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_STDDEF_H_
> > +#define CRT_STDDEF_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/stdio.h
> > b/RedfishPkg/Include/Crt/stdio.h new file mode 100644 index
> > 0000000000..25e610be10
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/stdio.h
> > @@ -0,0 +1,15 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#ifndef CRT_STDIO_H_
> > +#define CRT_STDIO_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/stdlib.h
> > b/RedfishPkg/Include/Crt/stdlib.h new file mode 100644 index
> > 0000000000..5b3dd273c8
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/stdlib.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_STDLIB_H_
> > +#define CRT_STDLIB_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/string.h
> > b/RedfishPkg/Include/Crt/string.h new file mode 100644 index
> > 0000000000..f60b87ccd2
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/string.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_STRING_H_
> > +#define CRT_STRING_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/sys/time.h
> > b/RedfishPkg/Include/Crt/sys/time.h
> > new file mode 100644
> > index 0000000000..4ced176cda
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/sys/time.h
> > @@ -0,0 +1,15 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#ifndef CRT_SYS_TIME_H_
> > +#define CRT_SYS_TIME_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/sys/types.h
> > b/RedfishPkg/Include/Crt/sys/types.h
> > new file mode 100644
> > index 0000000000..c4f807214c
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/sys/types.h
> > @@ -0,0 +1,15 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#ifndef CRT_SYS_TYPES_H_
> > +#define CRT_SYS_TYPES_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/time.h
> > b/RedfishPkg/Include/Crt/time.h new file mode 100644 index
> > 0000000000..ca04ac8730
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/time.h
> > @@ -0,0 +1,15 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#ifndef CRT_TIME_H_
> > +#define CRT_TIME_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Library/CrtLib.h
> > b/RedfishPkg/Include/Library/CrtLib.h
> > new file mode 100644
> > index 0000000000..8c7484e75b
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Library/CrtLib.h
> > @@ -0,0 +1,195 @@
> > +/** @file
> > + CRT wrapper head functions for jansson system call.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_LIB_H_
> > +#define CRT_LIB_H_
> > +
> > +#include <Library/BaseLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/PrintLib.h>
> > +
> > +#define MAX_STRING_SIZE 0x10000000
> > +
> > +// Minimum value for an object of type long long int.
> > +#define LLONG_MIN MIN_INT64
> > +
> > +// Maximum value for an object of type long long int.
> > +#define LLONG_MAX MAX_INT64
> > +
> > +// We dont support double on edk2
> > +#define HUGE_VAL 0
> > +
> > +#if defined(MDE_CPU_X64) || defined(MDE_CPU_AARCH64) ||
> > +defined(MDE_CPU_IA64) || defined(MDE_CPU_RISCV64) // // With GCC
> we
> > +would normally use SIXTY_FOUR_BIT_LONG, but MSVC needs //
> > +SIXTY_FOUR_BIT, because 'long' is 32-bit and only 'long long' is //
> > +64-bit. Since using 'long long' works fine on GCC too, just do that.
> > +//
> > +#define SIXTY_FOUR_BIT
> > +#elif defined(MDE_CPU_IA32) || defined(MDE_CPU_ARM) ||
> > +defined(MDE_CPU_EBC) #define THIRTY_TWO_BIT #endif
> > +
> > +//
> > +// Map all va_xxxx elements to VA_xxx defined in
> > +MdePkg/Include/Base.h // #if !defined(__CC_ARM) // if va_list is not
> > +already defined
> > +#define va_list VA_LIST
> > +#define va_arg VA_ARG
> > +#define va_start VA_START
> > +#define va_end VA_END
> > +#else // __CC_ARM
> > +#define va_start(Marker, Parameter) __va_start(Marker, Parameter)
> > +#define va_arg(Marker, TYPE) __va_arg(Marker, TYPE)
> > +#define va_end(Marker) ((void)0)
> > +#endif
> > +
> > +//
> > +// Definitions for global constants used by CRT library routines //
> > +#define INT_MAX MAX_INT32 /* Maximum (signed) int value */
> > +#define LONG_MAX 0X7FFFFFFFL /* max value for a long */
> > +#define LONG_MIN (-LONG_MAX-1) /* min value for a long */
> > +#define ULONG_MAX 0xFFFFFFFF /* Maximum unsigned long value
> */
> > +#define CHAR_BIT 8 /* Number of bits in a char */
> > +
> > +// Maximum value for an object of type unsigned long long int.
> > +#define ULLONG_MAX 0xFFFFFFFFFFFFFFFFULL // 2^64 - 1 // Maximum
> > +value for an object of type unsigned char.
> > +#define UCHAR_MAX 255 // 2^8 - 1
> > +
> > +//
> > +// Basic types mapping
> > +//
> > +typedef UINTN size_t;
> > +typedef INTN ssize_t;
> > +typedef INT32 time_t;
> > +typedef UINT8 __uint8_t;
> > +typedef UINT8 sa_family_t;
> > +typedef UINT32 uid_t;
> > +typedef UINT32 gid_t;
> > +typedef INT32 int32_t;
> > +typedef UINT32 uint32_t;
> > +typedef UINT16 uint16_t;
> > +typedef UINT8 uint8_t;
> > +typedef enum {false, true} bool;
> > +
> > +//
> > +// File operations are not required for EFI building, // so FILE is
> > +mapped to VOID * to pass build // typedef VOID *FILE;
> > +
> > +//
> > +// Global variables
> > +//
> > +extern int errno;
> > +extern FILE *stderr;
> > +
> > +//
> > +// Function prototypes of CRT Library routines //
> > +void *malloc (size_t);
> > +void *realloc (void *, size_t);
> > +void *calloc (size_t Num, size_t Size);
> > +void free (void *);
> > +void *memset (void *, int, size_t);
> > +int memcmp (const void *, const void *, size_t);
> > +int isdigit (int);
> > +int isspace (int);
> > +int tolower (int);
> > +int isupper (int);
> > +int isxdigit (int);
> > +int isalnum (int);
> > +void *memcpy (void *, const void *, size_t);
> > +void *memset (void *, int, size_t);
> > +void *memchr (const void *, int, size_t);
> > +int memcmp (const void *, const void *, size_t);
> > +void *memmove (void *, const void *, size_t);
> > +int strcmp (const char *, const char *);
> > +int strncmp (const char *, const char *, size_t);
> > +char *strcpy (char *, const char *);
> > +size_t strlen (const char *);
> > +char *strcat (char *, const char *);
> > +char *strchr (const char *, int);
> > +int strcasecmp (const char *, const char *);
> > +int strncasecmp (const char *, const char *, size_t);
> > +char *strncpy (char *, size_t, const char *, size_t);
> > +int strncmp (const char *, const char *, size_t);
> > +char *strrchr (const char *, int);
> > +unsigned long strtoul (const char *, char **, int);
> > +char * strstr (const char *s1 , const char *s2);
> > +long strtol (const char *, char **, int);
> > +char *strerror (int);
> > +size_t strspn (const char *, const char *);
> > +char * strdup (const char *str);
> > +char * strpbrk (const char *s1, const char *s2);
> > +unsigned long long strtoull(const char * nptr, char ** endptr, int base);
> > +long long strtoll (const char * nptr, char ** endptr, int base);
> > +long strtol (const char * nptr, char ** endptr, int base);
> > +double strtod (const char * __restrict nptr, char ** __restrict
> endptr);
> > +size_t strcspn (const char *, const char *);
> > +int printf (const char *, ...);
> > +int sscanf (const char *, const char *, ...);
> > +FILE *fopen (const char *, const char *);
> > +size_t fread (void *, size_t, size_t, FILE *);
> > +size_t fwrite (const void *, size_t, size_t, FILE *);
> > +int fclose (FILE *);
> > +int fprintf (FILE *, const char *, ...);
> > +int fgetc (FILE * _File);
> > +uid_t getuid (void);
> > +uid_t geteuid (void);
> > +gid_t getgid (void);
> > +gid_t getegid (void);
> > +void qsort (void *, size_t, size_t, int (*)(const void *, const void
> *));
> > +char *getenv (const char *);
> > +#if defined(__GNUC__) && (__GNUC__ >= 2)
> > +void abort (void) __attribute__((__noreturn__));
> > +#else
> > +void abort (void);
> > +#endif
> > +int toupper (int);
> > +int Digit2Val (int);
> > +time_t time (time_t *);
> > +
> > +//
> > +// Macros that directly map functions to BaseLib, BaseMemoryLib, and
> > +DebugLib functions //
> > +#define strcmp AsciiStrCmp
> > +#define memcpy(dest,source,count)
> CopyMem(dest,source,(UINTN)(count))
> > +#define memset(dest,ch,count)
> SetMem(dest,(UINTN)(count),(UINT8)(ch))
> > +#define memchr(buf,ch,count)
> ScanMem8(buf,(UINTN)(count),(UINT8)ch)
> > +#define memcmp(buf1,buf2,count)
> (int)(CompareMem(buf1,buf2,(UINTN)(count)))
> > +#define memmove(dest,source,count)
> CopyMem(dest,source,(UINTN)(count))
> > +#define strlen(str)
> (size_t)(AsciiStrnLenS(str,MAX_STRING_SIZE))
>
> What is MAX_STRING_SIZE? How do you know there are no buffer overruns
> looking for the end of the string? I guess this is more of a jansson lib
> question???
No, that is because we use AsciiStrnLenS for strlen(). We could just use AsciiStrLen() for strlen() that makes more sense. what do you think?
>
> > +#define strcpy(strDest,strSource)
> AsciiStrCpyS(strDest,(strlen(strSource)+1),strSource)
> > +#define strncpy(strDest,strSource,count)
> > +AsciiStrnCpyS(strDest,(UINTN)count,strSource,(UINTN)count)
> > +#define strncpys(strDest, DestLen, strSource,count)
> AsciiStrnCpyS(strDest,DestLen,strSource,(UINTN)count)
> > +#define strcat(strDest,strSource)
> AsciiStrCatS(strDest,(strlen(strSource)+strlen(strDest)+1),strSource)
> > +#define strchr(str,ch) ScanMem8((VOID
> *)(str),AsciiStrSize(str),(UINT8)ch)
> > +#define strncmp(string1,string2,count)
> (int)(AsciiStrnCmp(string1,string2,(UINTN)(count)))
> > +#define strcasecmp(str1,str2) (int)AsciiStriCmp(str1,str2)
> > +#define strstr(s1,s2) AsciiStrStr(s1,s2)
> > +#define sprintf(buf,...)
> AsciiSPrint(buf,MAX_STRING_SIZE,__VA_ARGS__)
> > +#define snprintf(buf,len,...) AsciiSPrint(buf,len,__VA_ARGS__)
> > +#define vsnprintf(buf,len,format,marker)
> > +AsciiVSPrint((buf),(len),(format),(marker))
>
> The EDK II PrintLib format string is not identical to libc printf() format string.
> Are you sure the usage by jansson is compatible?
The one problem I can see is sprintf
#define sprintf(buf,...) AsciiSPrint(buf,MAX_STRING_SIZE,__VA_ARGS__)
which has the different prototype. Luckily we don’t encounter problem because the jansson source code we use doesn’t use sprintf(), it only used in some jansson test tool. I will remove this definition and other unused ones as well.
I don’t see any particular issues when we run edk2 Redfish code on other print functions.
>
> > +#define assert(expression) ASSERT(expression)
> > +#define atoi(nptr) AsciiStrDecimalToUintn(nptr)
>
> Is this really compatible in behavior?
>
> > +#define fabs(x) (((x) < 0.0)? (-x): (x))
>
> Is fabs() actually used? Using floating point from UEFI/PI environment is
> complex and requires interrupts to be disabled/restored and potentially
> some context save/restore around use of floating point registers. If there is
> anyways to eliminate all uses of floating point, that would be much better.
No this is not used, will remove this. I missed to check it.
These C functions are used in both jansson and libredfish library. Will review those again.
>
> > +#define offsetof(type,member) OFFSET_OF(type,member)
> > +
> > +#define EOF (-1)
> > +
> > +extern int errno;
> > +
> > +#define ERANGE 34 /* 34 Result too large */
> > +
> > +#endif
> > diff --git a/RedfishPkg/Library/CrtLib/CrtLib.c
> > b/RedfishPkg/Library/CrtLib/CrtLib.c
> > new file mode 100644
> > index 0000000000..1ff4023dbe
> > --- /dev/null
> > +++ b/RedfishPkg/Library/CrtLib/CrtLib.c
> > @@ -0,0 +1,705 @@
> > +/** @file
> > + CRT wrapper functions for system call.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#include <Uefi.h>
> > +#include <Library/CrtLib.h>
> > +#include <Library/MemoryAllocationLib.h> #include
> > +<Library/UefiRuntimeServicesTableLib.h>
> > +
> > +int errno = 0;
> > +
> > +/**
> > + Determine if a particular character is an alphanumeric character
> > + @return Returns 1 if c is an alphanumeric character, otherwise returns 0.
> > +**/
> > +int isalnum (int c)
> > +{
> > + //
> > + // <alnum> ::= [0-9] | [a-z] | [A-Z]
> > + //
> > + return ((('0' <= (c)) && ((c) <= '9')) ||
> > + (('a' <= (c)) && ((c) <= 'z')) ||
> > + (('A' <= (c)) && ((c) <= 'Z'))); }
> > +
> > +/**
> > + Determine if a particular character is a digital character
> > +
> > + @return Returns 1 if c is an digital character, otherwise returns 0.
> > +**/
> > +int isdchar (int c)
> > +{
> > + //
> > + // [0-9] | [e +-.]
> > + //
> > + return ((('0' <= (c)) && ((c) <= '9')) ||
> > + (c == 'e') || (c == 'E') ||
> > + (c == '+') || (c == '-') ||
> > + (c == '.'));
> > +}
> > +
> > +/**
> > + Determine if a particular character is a space character
> > +
> > + @return Returns 1 if c is a space character **/ int isspace (int
> > +c) {
> > + //
> > + // <space> ::= [ ]
> > + //
> > + return ((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) ==
> > +'\n') || ((c) == '\v') || ((c) == '\f'); }
> > +
> > +/**
> > + Allocates memory blocks
> > +*/
> > +void *malloc (size_t size)
> > +{
> > + return AllocatePool ((UINTN) size); }
> > +
> > +/**
> > + De-allocates or frees a memory block */ void free (void *ptr) {
> > + //
> > + // In Standard C, free() handles a null pointer argument
> > +transparently. This
> > + // is not true of FreePool() below, so protect it.
> > + //
> > + if (ptr != NULL) {
> > + FreePool (ptr);
> > + }
> > +}
> > +
> > +/**
> > + NetBSD Compatibility Function strdup creates a duplicate copy of a string.
> > +
> > + @return Returns the pointer to duplicated string.
> > +**/
> > +char * strdup(const char *str)
> > +{
> > + size_t len;
> > + char *copy;
> > +
> > + len = strlen(str) + 1;
> > + if ((copy = malloc(len)) == NULL)
> > + return (NULL);
> > + memcpy(copy, str, len);
> > + return (copy);
> > +}
> > +
> > +/** The toupper function converts a lowercase letter to a corresponding
> > + uppercase letter.
> > +
> > + @param[in] c The character to be converted.
> > +
> > + @return If the argument is a character for which islower is true and
> > + there are one or more corresponding characters, as specified by
> > + the current locale, for which isupper is true, the toupper
> > + function returns one of the corresponding characters (always the
> > + same one for any given locale); otherwise, the argument is
> > + returned unchanged.
> > +**/
> > +int
> > +toupper(
> > + IN int c
> > + )
> > +{
> > + if ( (c >= 'a') && (c <= 'z') ) {
> > + c = c - ('a' - 'A');
> > + }
> > + return c;
> > +}
> > +
> > +/**
> > + Digit to a value.
> > +
> > + @return Returns the value of digit.
> > +**/
> > +int
> > +Digit2Val( int c)
> > +{
> > + if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))) { /* If c is one of [A-
> Za-z]... */
> > + c = toupper(c) - 7; // Adjust so 'A' is ('9' + 1)
> > + }
> > + return c - '0'; // Value returned is between 0 and 35, inclusive.
> > +}
> > +
> > +
> > +/** The strtoll function converts the initial portion of the string pointed to
> > + by nptr to long long int representation.
> > +
> > + See the description for strtol for more information.
> > +
> > + @return The strtoll function returns the converted value, if any. If no
> > + conversion could be performed, zero is returned. If the correct
> > + value is outside the range of representable values, LLONG_MIN or
> > + LLONG_MAX is returned (according to the sign of the value, if any),
> > + and the value of the macro ERANGE is stored in errno.
> > +**/
> > +long long
> > +strtoll(const char * nptr, char ** endptr, int base) {
> > + const char *pEnd;
> > + long long Result = 0;
> > + long long Previous;
> > + int temp;
> > + BOOLEAN Negative = FALSE;
> > +
> > + pEnd = nptr;
> > +
> > + if((base < 0) || (base == 1) || (base > 36)) {
> > + if(endptr != NULL) {
> > + *endptr = NULL;
> > + }
> > + return 0;
> > + }
> > + // Skip leading spaces.
> > + while(isspace(*nptr)) ++nptr;
> > +
> > + // Process Subject sequence: optional sign followed by digits.
> > + if(*nptr == '+') {
> > + Negative = FALSE;
> > + ++nptr;
> > + }
> > + else if(*nptr == '-') {
> > + Negative = TRUE;
> > + ++nptr;
> > + }
> > +
> > + if(*nptr == '0') { /* Might be Octal or Hex */
> > + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> > + if((base == 0) || (base == 16)) {
> > + nptr += 2; /* Skip the "0X" */
> > + base = 16; /* In case base was 0 */
> > + }
> > + }
> > + else { /* Looks like Octal */
> > + if((base == 0) || (base == 8)) {
> > + ++nptr; /* Skip the leading "0" */
> > + base = 8; /* In case base was 0 */
> > + }
> > + }
> > + }
> > + if(base == 0) { /* If still zero then must be decimal */
> > + base = 10;
> > + }
> > + if(*nptr == '0') {
> > + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> > + pEnd = nptr;
> > + }
> > +
> > + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> > + Previous = Result;
> > + Result = MultS64x64 (Result, base) + (long long int)temp;
> > + if( Result <= Previous) { // Detect Overflow
> > + if(Negative) {
> > + Result = LLONG_MIN;
> > + }
> > + else {
> > + Result = LLONG_MAX;
> > + }
> > + Negative = FALSE;
> > + errno = ERANGE;
> > + break;
> > + }
> > + pEnd = ++nptr;
> > + }
> > + if(Negative) {
> > + Result = -Result;
> > + }
> > +
> > + // Save pointer to final sequence
> > + if(endptr != NULL) {
> > + *endptr = (char *)pEnd;
> > + }
> > + return Result;
> > +}
> > +
> > +/** The strtol, strtoll, strtoul, and strtoull functions convert the initial
> > + portion of the string pointed to by nptr to long int, long long int,
> > + unsigned long int, and unsigned long long int representation,
> respectively.
> > + First, they decompose the input string into three parts: an initial,
> > + possibly empty, sequence of white-space characters (as specified by
> the
> > + isspace function), a subject sequence resembling an integer
> represented in
> > + some radix determined by the value of base, and a final string of one or
> > + more unrecognized characters, including the terminating null character
> of
> > + the input string. Then, they attempt to convert the subject sequence to
> an
> > + integer, and return the result.
> > +
> > + If the value of base is zero, the expected form of the subject sequence
> is
> > + that of an integer constant, optionally preceded
> > + by a plus or minus sign, but not including an integer suffix. If the value
> > + of base is between 2 and 36 (inclusive), the expected form of the
> subject
> > + sequence is a sequence of letters and digits representing an integer
> with
> > + the radix specified by base, optionally preceded by a plus or minus sign,
> > + but not including an integer suffix. The letters from a (or A) through z
> > + (or Z) are ascribed the values 10 through 35; only letters and digits
> whose
> > + ascribed values are less than that of base are permitted. If the value of
> > + base is 16, the characters 0x or 0X may optionally precede the sequence
> of
> > + letters and digits, following the sign if present.
> > +
> > + The subject sequence is defined as the longest initial subsequence of
> the
> > + input string, starting with the first non-white-space character, that is of
> > + the expected form. The subject sequence contains no characters if the
> input
> > + string is empty or consists entirely of white space, or if the first
> > + non-white-space character is other than a sign or a permissible letter or
> digit.
> > +
> > + If the subject sequence has the expected form and the value of base is
> > + zero, the sequence of characters starting with the first digit is
> > + interpreted as an integer constant. If the subject sequence has the
> > + expected form and the value of base is between 2 and 36, it is used as
> the
> > + base for conversion, ascribing to each letter its value as given above. If
> > + the subject sequence begins with a minus sign, the value resulting from
> the
> > + conversion is negated (in the return type). A pointer to the final string
> > + is stored in the object pointed to by endptr, provided that endptr is
> > + not a null pointer.
> > +
> > + In other than the "C" locale, additional locale-specific subject sequence
> > + forms may be accepted.
> > +
> > + If the subject sequence is empty or does not have the expected form,
> no
> > + conversion is performed; the value of nptr is stored in the object
> pointed
> > + to by endptr, provided that endptr is not a null pointer.
> > +
> > + @return The strtol, strtoll, strtoul, and strtoull functions return the
> > + converted value, if any. If no conversion could be performed, zero
> > + is returned. If the correct value is outside the range of
> > + representable values, LONG_MIN, LONG_MAX, LLONG_MIN,
> LLONG_MAX,
> > + ULONG_MAX, or ULLONG_MAX is returned (according to the return
> type
> > + and sign of the value, if any), and the value of the macro ERANGE
> > + is stored in errno.
> > +**/
> > +long
> > +strtol(const char * nptr, char ** endptr, int base) {
> > + const char *pEnd;
> > + long Result = 0;
> > + long Previous;
> > + int temp;
> > + BOOLEAN Negative = FALSE;
> > +
> > + pEnd = nptr;
> > +
> > + if((base < 0) || (base == 1) || (base > 36)) {
> > + if(endptr != NULL) {
> > + *endptr = NULL;
> > + }
> > + return 0;
> > + }
> > + // Skip leading spaces.
> > + while(isspace(*nptr)) ++nptr;
> > +
> > + // Process Subject sequence: optional sign followed by digits.
> > + if(*nptr == '+') {
> > + Negative = FALSE;
> > + ++nptr;
> > + }
> > + else if(*nptr == '-') {
> > + Negative = TRUE;
> > + ++nptr;
> > + }
> > +
> > + if(*nptr == '0') { /* Might be Octal or Hex */
> > + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> > + if((base == 0) || (base == 16)) {
> > + nptr += 2; /* Skip the "0X" */
> > + base = 16; /* In case base was 0 */
> > + }
> > + }
> > + else { /* Looks like Octal */
> > + if((base == 0) || (base == 8)) {
> > + ++nptr; /* Skip the leading "0" */
> > + base = 8; /* In case base was 0 */
> > + }
> > + }
> > + }
> > + if(base == 0) { /* If still zero then must be decimal */
> > + base = 10;
> > + }
> > + if(*nptr == '0') {
> > + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> > + pEnd = nptr;
> > + }
> > +
> > + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> > + Previous = Result;
> > + Result = (Result * base) + (long int)temp;
> > + if( Result <= Previous) { // Detect Overflow
> > + if(Negative) {
> > + Result = LONG_MIN;
> > + }
> > + else {
> > + Result = LONG_MAX;
> > + }
> > + Negative = FALSE;
> > + errno = ERANGE;
> > + break;
> > + }
> > + pEnd = ++nptr;
> > + }
> > + if(Negative) {
> > + Result = -Result;
> > + }
> > +
> > + // Save pointer to final sequence
> > + if(endptr != NULL) {
> > + *endptr = (char *)pEnd;
> > + }
> > + return Result;
> > +}
> > +
> > +/** The strtoull function converts the initial portion of the string pointed
> to
> > + by nptr to unsigned long long int representation.
> > +
> > + See the description for strtol for more information.
> > +
> > + @return The strtoull function returns the converted value, if any. If no
> > + conversion could be performed, zero is returned. If the correct
> > + value is outside the range of representable values, ULLONG_MAX is
> > + returned and the value of the macro ERANGE is stored in errno.
> > +**/
> > +unsigned long long
> > +strtoull(const char * nptr, char ** endptr, int base) {
> > + const char *pEnd;
> > + unsigned long long Result = 0;
> > + unsigned long long Previous;
> > + int temp;
> > +
> > + pEnd = nptr;
> > +
> > + if((base < 0) || (base == 1) || (base > 36)) {
> > + if(endptr != NULL) {
> > + *endptr = NULL;
> > + }
> > + return 0;
> > + }
> > + // Skip leading spaces.
> > + while(isspace(*nptr)) ++nptr;
> > +
> > + // Process Subject sequence: optional + sign followed by digits.
> > + if(*nptr == '+') {
> > + ++nptr;
> > + }
> > +
> > + if(*nptr == '0') { /* Might be Octal or Hex */
> > + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> > + if((base == 0) || (base == 16)) {
> > + nptr += 2; /* Skip the "0X" */
> > + base = 16; /* In case base was 0 */
> > + }
> > + }
> > + else { /* Looks like Octal */
> > + if((base == 0) || (base == 8)) {
> > + ++nptr; /* Skip the leading "0" */
> > + base = 8; /* In case base was 0 */
> > + }
> > + }
> > + }
> > + if(base == 0) { /* If still zero then must be decimal */
> > + base = 10;
> > + }
> > + if(*nptr == '0') {
> > + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> > + pEnd = nptr;
> > + }
> > +
> > + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> > + Previous = Result;
> > + Result = DivU64x32 (Result, base) + (unsigned long long)temp;
> > + if( Result < Previous) { // If we overflowed
> > + Result = ULLONG_MAX;
> > + errno = ERANGE;
> > + break;
> > + }
> > + pEnd = ++nptr;
> > + }
> > +
> > + // Save pointer to final sequence
> > + if(endptr != NULL) {
> > + *endptr = (char *)pEnd;
> > + }
> > + return Result;
> > +}
> > +
> > +/**
> > + edk2 Jansson port does not support doubles, simply return 0.
> > +
> > + These conversion functions convert the initial portion of the
> > + string pointed to by nptr to double, float, and long double
> > + representation, respectively.
> > +
> > + The strtod(), strtof(), and strtold() functions return the
> > + converted value, if any.
> > +
> > + If endptr is not NULL, a pointer to the character after the last
> > + charac- ter used in the conversion is stored in the location
> > + referenced by endptr.
> > +
> > + If no conversion is performed, zero is returned and the value of
> > + nptr is stored in the location referenced by endptr.
> > +
> > + If the correct value would cause overflow, plus or minus HUGE_VAL,
> > + HUGE_VALF, or HUGE_VALL is returned (according to the sign and type
> > + of the return value), and ERANGE is stored in errno. If the
> > + correct value would cause underflow, zero is returned and ERANGE is
> stored in errno.
> > +
> > + @return Return 0.
> > +**/
> > +double
> > +strtod (const char * __restrict nptr, char ** __restrict endptr) {
> > + if(endptr)
> > + *endptr = (char *)(nptr + strlen(nptr));
> > +
> > + return (double)0;
> > +}
>
> Even the use of the type double to return 0 has issues in UEFI/PI.
> Can you figure out how to remove the use of strtod() by jansson?
There is no option for jansson to remove strtod, that is too specific. double type is used in JSON and it is a default supported number.
The implementation we have now is to return 0 which is the same as the definition of HUGE_VAL in CrtLib.h. HUGE_VAL is used in jannson to check if the value is overflow. Set HUGE_VAL to 0 leads jsonp_strtod to return -1 to the caller.
I think we can give strtod an ASSERT to not returning double and output the error message.
But we may need to fix the problem of using floating point on edk2 later.
>
> > +
> > +/**
> > + Allocate and zero-initialize array.
> > +**/
> > +void *
> > +calloc(size_t Num, size_t Size)
> > +{
> > + void *RetVal;
> > + size_t NumSize;
> > +
> > + NumSize = Num * Size;
> > + RetVal = NULL;
> > + if (NumSize != 0) {
> > + RetVal = malloc(NumSize);
> > + if( RetVal != NULL) {
> > + (VOID)ZeroMem( RetVal, NumSize);
> > + }
> > + }
> > + DEBUG((DEBUG_POOL, "0x%p = calloc(%d, %d)\n", RetVal, Num, Size));
> > +
> > + return RetVal;
> > +}
> > +
> > +//
> > +// The arrays give the cumulative number of days up to the first of
> > +the // month number used as the index (1 -> 12) for regular and leap
> years.
> > +// The value at index 13 is for the whole year.
> > +//
> > +UINTN CumulativeDays[2][14] = {
> > + {
> > + 0,
> > + 0,
> > + 31,
> > + 31 + 28,
> > + 31 + 28 + 31,
> > + 31 + 28 + 31 + 30,
> > + 31 + 28 + 31 + 30 + 31,
> > + 31 + 28 + 31 + 30 + 31 + 30,
> > + 31 + 28 + 31 + 30 + 31 + 30 + 31,
> > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
> > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
> > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
> > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
> > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
> > + },
> > + {
> > + 0,
> > + 0,
> > + 31,
> > + 31 + 29,
> > + 31 + 29 + 31,
> > + 31 + 29 + 31 + 30,
> > + 31 + 29 + 31 + 30 + 31,
> > + 31 + 29 + 31 + 30 + 31 + 30,
> > + 31 + 29 + 31 + 30 + 31 + 30 + 31,
> > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,
> > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
> > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
> > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
> > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
> > + }
> > +};
> > +
> > +#define IsLeap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
> > +#define SECSPERMIN (60)
> > +#define SECSPERHOUR (60 * 60)
> > +#define SECSPERDAY (24 * SECSPERHOUR)
> > +
> > +/**
> > + Get the system time as seconds elapsed since midnight, January 1, 1970.
> > +**/
> > +time_t time (time_t *timer)
> > +{
> > + EFI_TIME Time;
> > + time_t CalTime;
> > + UINTN Year;
> > +
> > + //
> > + // Get the current time and date information // gRT->GetTime
> > + (&Time, NULL);
> > +
> > + //
> > + // Years Handling
> > + // UTime should now be set to 00:00:00 on Jan 1 of the current year.
> > + //
> > + for (Year = 1970, CalTime = 0; Year != Time.Year; Year++) {
> > + CalTime = CalTime + (time_t)(CumulativeDays[IsLeap(Year)][13] *
> > + SECSPERDAY); }
> > +
> > + //
> > + // Add in number of seconds for current Month, Day, Hour, Minute,
> > + Seconds, and TimeZone adjustment // CalTime = CalTime +
> > + (time_t)((Time.TimeZone != EFI_UNSPECIFIED_TIMEZONE) ?
> (Time.TimeZone * 60) : 0) +
> > + (time_t)(CumulativeDays[IsLeap(Time.Year)][Time.Month] *
> SECSPERDAY) +
> > + (time_t)(((Time.Day > 0) ? Time.Day - 1 : 0) * SECSPERDAY) +
> > + (time_t)(Time.Hour * SECSPERHOUR) +
> > + (time_t)(Time.Minute * 60) +
> > + (time_t)Time.Second;
> > +
> > + if (timer != NULL) {
> > + *timer = CalTime;
> > + }
> > +
> > + return CalTime;
> > +}
> > +
> > +typedef
> > +int
> > +(*SORT_COMPARE)(
> > + IN VOID *Buffer1,
> > + IN VOID *Buffer2
> > + );
> > +
> > +/**
> > + Duplicated from EDKII BaseSortLib for qsort() wrapper
> > + @param[in, out] BufferToSort on call a Buffer of (possibly sorted)
> elements
> > + on return a buffer of sorted elements
> > + @param[in] Count the number of elements in the buffer to sort
> > + @param[in] ElementSize Size of an element in bytes
> > + @param[in] CompareFunction The function to call to perform the
> comparison
> > + of any 2 elements
> > + @param[in] Buffer Buffer of size ElementSize for use in swapping
> > +**/
> > +STATIC
> > +VOID
> > +QuickSortWorker (
> > + IN OUT VOID *BufferToSort,
> > + IN CONST UINTN Count,
> > + IN CONST UINTN ElementSize,
> > + IN SORT_COMPARE CompareFunction,
> > + IN VOID *Buffer
> > + )
> > +{
> > + VOID *Pivot;
> > + UINTN LoopCount;
> > + UINTN NextSwapLocation;
> > +
> > + ASSERT(BufferToSort != NULL);
> > + ASSERT(CompareFunction != NULL);
> > + ASSERT(Buffer != NULL);
> > +
> > + if (Count < 2 || ElementSize < 1) {
> > + return;
> > + }
> > +
> > + NextSwapLocation = 0;
> > +
> > + //
> > + // Pick a pivot (we choose last element) // Pivot = ((UINT8
> > + *)BufferToSort + ((Count - 1) * ElementSize));
> > +
> > + //
> > + // Now get the pivot such that all on "left" are below it // and
> > + everything "right" are above it // for (LoopCount = 0; LoopCount <
> > + Count - 1; LoopCount++) {
> > + //
> > + // If the element is less than the pivot
> > + //
> > + if (CompareFunction ((VOID *)((UINT8 *)BufferToSort + ((LoopCount) *
> ElementSize)), Pivot) <= 0) {
> > + //
> > + // Swap
> > + //
> > + CopyMem (Buffer, (UINT8 *)BufferToSort + (NextSwapLocation *
> ElementSize), ElementSize);
> > + CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation *
> > + ElementSize), (UINT8 *)BufferToSort + ((LoopCount) *
> > ElementSize), ElementSize);
> > + CopyMem ((UINT8 *)BufferToSort + ((LoopCount) * ElementSize),
> > + Buffer, ElementSize);
> > +
> > + //
> > + // Increment NextSwapLocation
> > + //
> > + NextSwapLocation++;
> > + }
> > + }
> > + //
> > + // Swap pivot to it's final position (NextSwapLocaiton) //
> > + CopyMem (Buffer, Pivot, ElementSize); CopyMem (Pivot, (UINT8
> > + *)BufferToSort + (NextSwapLocation * ElementSize), ElementSize);
> > + CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation * ElementSize),
> > + Buffer, ElementSize);
> > +
> > + //
> > + // Now recurse on 2 paritial lists. Neither of these will have the 'pivot'
> element.
> > + // IE list is sorted left half, pivot element, sorted right half...
> > + //
> > + QuickSortWorker (
> > + BufferToSort,
> > + NextSwapLocation,
> > + ElementSize,
> > + CompareFunction,
> > + Buffer
> > + );
> > +
> > + QuickSortWorker (
> > + (UINT8 *)BufferToSort + (NextSwapLocation + 1) * ElementSize,
> > + Count - NextSwapLocation - 1,
> > + ElementSize,
> > + CompareFunction,
> > + Buffer
> > + );
> > +
> > + return;
> > +}
> > +
> > +/**
> > + Performs a quick sort
> > +**/
> > +void qsort (void *base, size_t num, size_t width, int
> > +(*compare)(const void *, const void *)) {
> > + VOID *Buffer;
> > +
> > + ASSERT (base != NULL);
> > + ASSERT (compare != NULL);
> > +
> > + //
> > + // Use CRT-style malloc to cover BS and RT memory allocation.
> > + //
> > + Buffer = malloc (width);
> > + ASSERT (Buffer != NULL);
> > +
> > + //
> > + // Re-use PerformQuickSort() function Implementation in EDKII
> BaseSortLib.
> > + //
> > + QuickSortWorker (base, (UINTN)num, (UINTN)width,
> > + (SORT_COMPARE)compare, Buffer);
> > +
> > + free (Buffer);
> > + return;
> > +}
> > +
> > +/**
> > + Get character from stream, we don't support file operastion on edk2
> JSON library.
> > +
> > + @return Returns the character currently pointed by the internal
> > + file position indicator of the specified stream
> > +
> > +**/
> > +int fgetc(FILE * _File){
> > + return 0;
> > +}
> > diff --git a/RedfishPkg/Library/CrtLib/CrtLib.inf
> > b/RedfishPkg/Library/CrtLib/CrtLib.inf
> > new file mode 100644
> > index 0000000000..b514817cf4
> > --- /dev/null
> > +++ b/RedfishPkg/Library/CrtLib/CrtLib.inf
> > @@ -0,0 +1,37 @@
> > +## @file
> > +# EDK2 C Runtime Library for opensource project.
> > +#
> > +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> #
> > +(C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR> #
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > + INF_VERSION = 0x0001001b
> > + BASE_NAME = CrtLib
> > + FILE_GUID = 8263B8AC-D021-425D-B337-3EC96F5DC19B
> > + MODULE_TYPE = DXE_DRIVER
> > + VERSION_STRING = 1.0
> > + LIBRARY_CLASS = CrtLib|DXE_CORE DXE_DRIVER
> DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION
> > UEFI_DRIVER
> > +
> > +#
> > +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64
> > +#
> > +
> > +[Sources]
> > + CrtLib.c
> > +
> > +[LibraryClasses]
> > + BaseLib
> > + DebugLib
> > + MemoryAllocationLib
> > + UefiRuntimeServicesTableLib
> > +
> > +[Packages]
> > + MdePkg/MdePkg.dec
> > + MdeModulePkg/MdeModulePkg.dec
> > + RedfishPkg/RedfishPkg.dec
> > +
> > +
> > diff --git a/RedfishPkg/RedfishLibs.dsc.inc
> > b/RedfishPkg/RedfishLibs.dsc.inc index d4c08e18ac..2a951bd8fa 100644
> > --- a/RedfishPkg/RedfishLibs.dsc.inc
> > +++ b/RedfishPkg/RedfishLibs.dsc.inc
> > @@ -12,5 +12,6 @@
> > ##
> > !if $(REDFISH_ENABLE) == TRUE
> > Ucs2Utf8Lib|RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > + CrtLib|RedfishPkg/Library/CrtLib/CrtLib.inf
> > !endif
> >
> > diff --git a/RedfishPkg/RedfishPkg.ci.yaml
> > b/RedfishPkg/RedfishPkg.ci.yaml index 20c297ad22..9895fdac99 100644
> > --- a/RedfishPkg/RedfishPkg.ci.yaml
> > +++ b/RedfishPkg/RedfishPkg.ci.yaml
> > @@ -17,6 +17,25 @@
> > ],
> > ## Both file path and directory path are accepted.
> > "IgnoreFiles": [
> > + ## Below are files incorporated with open source which are
> > + ## not edk2 coding standard compliant.
> > + ##
> > + ## EDK2 CRT library which is not edk2 coding
> > + ## standard compliant.
> > + ## C runtime library for EDKII JsonLib.
> > + "Include/Crt/sys",
> > + "Include/Crt/assert.h",
> > + "Include/Crt/errno.h",
> > + "Include/Crt/limits.h",
> > + "Include/Crt/math.h",
> > + "Include/Crt/stdarg.h",
> > + "Include/Crt/stddef.h",
> > + "Include/Crt/stdio.h",
> > + "Include/Crt/stdlib.h",
> > + "Include/Crt/string.h",
> > + "Include/Crt/time.h",
> > + "Include/Library/CrtLib.h",
> > + "Library/CrtLib/CrtLib.c"
> > ]
> > },
> > "CompilerPlugin": {
> > diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec
> > index aecc1f4a3a..2142b43640 100644
> > --- a/RedfishPkg/RedfishPkg.dec
> > +++ b/RedfishPkg/RedfishPkg.dec
> > @@ -15,16 +15,24 @@
> >
> > [Includes]
> > Include
> > + Include/Crt # Header files for C RTL.
> >
> > [LibraryClasses]
> > ## @libraryclass Platform Redfish Host Interface Library
> > # Platform implementation-specific Redfish Host Interface.
> >
> > RedfishPlatformHostInterfaceLib|Include/Library/RedfishHostInterfaceLi
> > b.h
> > +
> > ## @libraryclass This library provides UCS2 to UTF8 manipulation
> > # functions.
> > #
> > Ucs2Utf8Lib|Include/Library/BaseUcs2Utf8Lib.h
> >
> > + ## @libraryclass Provides the C runtime library functions
> > + # CRT library is currently used by edk2 JsonLib (open source
> > + # jansson project) and edk2 RedfishLib (libredfish open source
> > + # project).
> > + CrtLib|Include/Library/CrtLib.h
> > +
> > [Protocols]
> > ## Include/Protocol/RedfishDiscover.h
> > gEfiRedfishDiscoverProtocolGuid = { 0x5db12509, 0x4550, 0x4347, { 0x96,
> 0xb3, 0x73, 0xc0, 0xff, 0x6e, 0x86, 0x9f
> > }}
> > diff --git a/RedfishPkg/RedfishPkg.dsc b/RedfishPkg/RedfishPkg.dsc
> > index 3639b620e6..aa1ccd5a95 100644
> > --- a/RedfishPkg/RedfishPkg.dsc
> > +++ b/RedfishPkg/RedfishPkg.dsc
> > @@ -48,5 +48,6 @@
> > [Components]
> >
> RedfishPkg/Library/PlatformHostInterfaceLibNull/PlatformHostInterfaceLibN
> ull.inf
> > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > + RedfishPkg/Library/CrtLib/CrtLib.inf
> >
> > !include RedfishPkg/Redfish.dsc.inc
> > --
> > 2.17.1
> >
> >
> >
> >
> >
>
>
>
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime library
2020-12-14 3:53 ` [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime library Abner Chang
2020-12-14 17:06 ` [edk2-devel] " Michael D Kinney
2020-12-14 23:30 ` Michael D Kinney
@ 2020-12-15 0:19 ` Michael D Kinney
2020-12-16 4:38 ` Abner Chang
[not found] ` <CS1PR8401MB1144B554CE75DDDA5E4C1ECEFFC50@CS1PR8401MB1144.NAMPRD84.PROD.OUTLOOK.COM>
2 siblings, 2 replies; 15+ messages in thread
From: Michael D Kinney @ 2020-12-15 0:19 UTC (permalink / raw)
To: devel@edk2.groups.io, abner.chang@hpe.com, Kinney, Michael D
Cc: Leif Lindholm, Nickle Wang, Peter O'Hanley
Hi Abner,
I see what appears to be some duplication of the qsort source code.
Can you use the PerformQuickSort() API from the QsortLib in the MdeModulePkg?
Thanks,
Mike
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Abner Chang
> Sent: Sunday, December 13, 2020 7:53 PM
> To: devel@edk2.groups.io
> Cc: Leif Lindholm <leif@nuviainc.com>; Nickle Wang <nickle.wang@hpe.com>; Peter O'Hanley <peter.ohanley@hpe.com>
> Subject: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime library
>
> CRT library is currently used by edk2 JsonLib (open source
> jansson project) and edk2 RedfishLib (libredfish open source
> project). CrtLib library provides the necessary C runtime
> equivalent edk2 functions for open source projects.
>
> Signed-off-by: Abner Chang <abner.chang@hpe.com>
>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Nickle Wang <nickle.wang@hpe.com>
> Cc: Peter O'Hanley <peter.ohanley@hpe.com>
> ---
> RedfishPkg/Include/Crt/assert.h | 16 +
> RedfishPkg/Include/Crt/errno.h | 16 +
> RedfishPkg/Include/Crt/limits.h | 16 +
> RedfishPkg/Include/Crt/math.h | 16 +
> RedfishPkg/Include/Crt/stdarg.h | 15 +
> RedfishPkg/Include/Crt/stddef.h | 16 +
> RedfishPkg/Include/Crt/stdio.h | 15 +
> RedfishPkg/Include/Crt/stdlib.h | 16 +
> RedfishPkg/Include/Crt/string.h | 16 +
> RedfishPkg/Include/Crt/sys/time.h | 15 +
> RedfishPkg/Include/Crt/sys/types.h | 15 +
> RedfishPkg/Include/Crt/time.h | 15 +
> RedfishPkg/Include/Library/CrtLib.h | 195 ++++++++
> RedfishPkg/Library/CrtLib/CrtLib.c | 705 +++++++++++++++++++++++++++
> RedfishPkg/Library/CrtLib/CrtLib.inf | 37 ++
> RedfishPkg/RedfishLibs.dsc.inc | 1 +
> RedfishPkg/RedfishPkg.ci.yaml | 19 +
> RedfishPkg/RedfishPkg.dec | 8 +
> RedfishPkg/RedfishPkg.dsc | 1 +
> 19 files changed, 1153 insertions(+)
> create mode 100644 RedfishPkg/Include/Crt/assert.h
> create mode 100644 RedfishPkg/Include/Crt/errno.h
> create mode 100644 RedfishPkg/Include/Crt/limits.h
> create mode 100644 RedfishPkg/Include/Crt/math.h
> create mode 100644 RedfishPkg/Include/Crt/stdarg.h
> create mode 100644 RedfishPkg/Include/Crt/stddef.h
> create mode 100644 RedfishPkg/Include/Crt/stdio.h
> create mode 100644 RedfishPkg/Include/Crt/stdlib.h
> create mode 100644 RedfishPkg/Include/Crt/string.h
> create mode 100644 RedfishPkg/Include/Crt/sys/time.h
> create mode 100644 RedfishPkg/Include/Crt/sys/types.h
> create mode 100644 RedfishPkg/Include/Crt/time.h
> create mode 100644 RedfishPkg/Include/Library/CrtLib.h
> create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.c
> create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.inf
>
> diff --git a/RedfishPkg/Include/Crt/assert.h b/RedfishPkg/Include/Crt/assert.h
> new file mode 100644
> index 0000000000..f9ab7ef9ca
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/assert.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_ASSERT_H_
> +#define CRT_ASSERT_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/errno.h b/RedfishPkg/Include/Crt/errno.h
> new file mode 100644
> index 0000000000..d30aee14de
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/errno.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_ERRNO_H_
> +#define CRT_ERRNO_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/limits.h b/RedfishPkg/Include/Crt/limits.h
> new file mode 100644
> index 0000000000..f3bdd33f2a
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/limits.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_LIMITS_H_
> +#define CRT_LIMITS_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/math.h b/RedfishPkg/Include/Crt/math.h
> new file mode 100644
> index 0000000000..984c0ccc21
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/math.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_MATH_H_
> +#define CRT_MATH_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/stdarg.h b/RedfishPkg/Include/Crt/stdarg.h
> new file mode 100644
> index 0000000000..d5a314ad3b
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/stdarg.h
> @@ -0,0 +1,15 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef CRT_STDARG_H_
> +#define CRT_STDARG_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/stddef.h b/RedfishPkg/Include/Crt/stddef.h
> new file mode 100644
> index 0000000000..15a37bf50e
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/stddef.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_STDDEF_H_
> +#define CRT_STDDEF_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/stdio.h b/RedfishPkg/Include/Crt/stdio.h
> new file mode 100644
> index 0000000000..25e610be10
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/stdio.h
> @@ -0,0 +1,15 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef CRT_STDIO_H_
> +#define CRT_STDIO_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/stdlib.h b/RedfishPkg/Include/Crt/stdlib.h
> new file mode 100644
> index 0000000000..5b3dd273c8
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/stdlib.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_STDLIB_H_
> +#define CRT_STDLIB_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/string.h b/RedfishPkg/Include/Crt/string.h
> new file mode 100644
> index 0000000000..f60b87ccd2
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/string.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_STRING_H_
> +#define CRT_STRING_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/sys/time.h b/RedfishPkg/Include/Crt/sys/time.h
> new file mode 100644
> index 0000000000..4ced176cda
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/sys/time.h
> @@ -0,0 +1,15 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef CRT_SYS_TIME_H_
> +#define CRT_SYS_TIME_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/sys/types.h b/RedfishPkg/Include/Crt/sys/types.h
> new file mode 100644
> index 0000000000..c4f807214c
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/sys/types.h
> @@ -0,0 +1,15 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef CRT_SYS_TYPES_H_
> +#define CRT_SYS_TYPES_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Crt/time.h b/RedfishPkg/Include/Crt/time.h
> new file mode 100644
> index 0000000000..ca04ac8730
> --- /dev/null
> +++ b/RedfishPkg/Include/Crt/time.h
> @@ -0,0 +1,15 @@
> +/** @file
> + Include file to support building the third-party jansson library.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef CRT_TIME_H_
> +#define CRT_TIME_H_
> +
> +#include <Library/CrtLib.h>
> +
> +#endif
> diff --git a/RedfishPkg/Include/Library/CrtLib.h b/RedfishPkg/Include/Library/CrtLib.h
> new file mode 100644
> index 0000000000..8c7484e75b
> --- /dev/null
> +++ b/RedfishPkg/Include/Library/CrtLib.h
> @@ -0,0 +1,195 @@
> +/** @file
> + CRT wrapper head functions for jansson system call.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CRT_LIB_H_
> +#define CRT_LIB_H_
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PrintLib.h>
> +
> +#define MAX_STRING_SIZE 0x10000000
> +
> +// Minimum value for an object of type long long int.
> +#define LLONG_MIN MIN_INT64
> +
> +// Maximum value for an object of type long long int.
> +#define LLONG_MAX MAX_INT64
> +
> +// We dont support double on edk2
> +#define HUGE_VAL 0
> +
> +#if defined(MDE_CPU_X64) || defined(MDE_CPU_AARCH64) || defined(MDE_CPU_IA64) || defined(MDE_CPU_RISCV64)
> +//
> +// With GCC we would normally use SIXTY_FOUR_BIT_LONG, but MSVC needs
> +// SIXTY_FOUR_BIT, because 'long' is 32-bit and only 'long long' is
> +// 64-bit. Since using 'long long' works fine on GCC too, just do that.
> +//
> +#define SIXTY_FOUR_BIT
> +#elif defined(MDE_CPU_IA32) || defined(MDE_CPU_ARM) || defined(MDE_CPU_EBC)
> +#define THIRTY_TWO_BIT
> +#endif
> +
> +//
> +// Map all va_xxxx elements to VA_xxx defined in MdePkg/Include/Base.h
> +//
> +#if !defined(__CC_ARM) // if va_list is not already defined
> +#define va_list VA_LIST
> +#define va_arg VA_ARG
> +#define va_start VA_START
> +#define va_end VA_END
> +#else // __CC_ARM
> +#define va_start(Marker, Parameter) __va_start(Marker, Parameter)
> +#define va_arg(Marker, TYPE) __va_arg(Marker, TYPE)
> +#define va_end(Marker) ((void)0)
> +#endif
> +
> +//
> +// Definitions for global constants used by CRT library routines
> +//
> +#define INT_MAX MAX_INT32 /* Maximum (signed) int value */
> +#define LONG_MAX 0X7FFFFFFFL /* max value for a long */
> +#define LONG_MIN (-LONG_MAX-1) /* min value for a long */
> +#define ULONG_MAX 0xFFFFFFFF /* Maximum unsigned long value */
> +#define CHAR_BIT 8 /* Number of bits in a char */
> +
> +// Maximum value for an object of type unsigned long long int.
> +#define ULLONG_MAX 0xFFFFFFFFFFFFFFFFULL // 2^64 - 1
> +// Maximum value for an object of type unsigned char.
> +#define UCHAR_MAX 255 // 2^8 - 1
> +
> +//
> +// Basic types mapping
> +//
> +typedef UINTN size_t;
> +typedef INTN ssize_t;
> +typedef INT32 time_t;
> +typedef UINT8 __uint8_t;
> +typedef UINT8 sa_family_t;
> +typedef UINT32 uid_t;
> +typedef UINT32 gid_t;
> +typedef INT32 int32_t;
> +typedef UINT32 uint32_t;
> +typedef UINT16 uint16_t;
> +typedef UINT8 uint8_t;
> +typedef enum {false, true} bool;
> +
> +//
> +// File operations are not required for EFI building,
> +// so FILE is mapped to VOID * to pass build
> +//
> +typedef VOID *FILE;
> +
> +//
> +// Global variables
> +//
> +extern int errno;
> +extern FILE *stderr;
> +
> +//
> +// Function prototypes of CRT Library routines
> +//
> +void *malloc (size_t);
> +void *realloc (void *, size_t);
> +void *calloc (size_t Num, size_t Size);
> +void free (void *);
> +void *memset (void *, int, size_t);
> +int memcmp (const void *, const void *, size_t);
> +int isdigit (int);
> +int isspace (int);
> +int tolower (int);
> +int isupper (int);
> +int isxdigit (int);
> +int isalnum (int);
> +void *memcpy (void *, const void *, size_t);
> +void *memset (void *, int, size_t);
> +void *memchr (const void *, int, size_t);
> +int memcmp (const void *, const void *, size_t);
> +void *memmove (void *, const void *, size_t);
> +int strcmp (const char *, const char *);
> +int strncmp (const char *, const char *, size_t);
> +char *strcpy (char *, const char *);
> +size_t strlen (const char *);
> +char *strcat (char *, const char *);
> +char *strchr (const char *, int);
> +int strcasecmp (const char *, const char *);
> +int strncasecmp (const char *, const char *, size_t);
> +char *strncpy (char *, size_t, const char *, size_t);
> +int strncmp (const char *, const char *, size_t);
> +char *strrchr (const char *, int);
> +unsigned long strtoul (const char *, char **, int);
> +char * strstr (const char *s1 , const char *s2);
> +long strtol (const char *, char **, int);
> +char *strerror (int);
> +size_t strspn (const char *, const char *);
> +char * strdup (const char *str);
> +char * strpbrk (const char *s1, const char *s2);
> +unsigned long long strtoull(const char * nptr, char ** endptr, int base);
> +long long strtoll (const char * nptr, char ** endptr, int base);
> +long strtol (const char * nptr, char ** endptr, int base);
> +double strtod (const char * __restrict nptr, char ** __restrict endptr);
> +size_t strcspn (const char *, const char *);
> +int printf (const char *, ...);
> +int sscanf (const char *, const char *, ...);
> +FILE *fopen (const char *, const char *);
> +size_t fread (void *, size_t, size_t, FILE *);
> +size_t fwrite (const void *, size_t, size_t, FILE *);
> +int fclose (FILE *);
> +int fprintf (FILE *, const char *, ...);
> +int fgetc (FILE * _File);
> +uid_t getuid (void);
> +uid_t geteuid (void);
> +gid_t getgid (void);
> +gid_t getegid (void);
> +void qsort (void *, size_t, size_t, int (*)(const void *, const void *));
> +char *getenv (const char *);
> +#if defined(__GNUC__) && (__GNUC__ >= 2)
> +void abort (void) __attribute__((__noreturn__));
> +#else
> +void abort (void);
> +#endif
> +int toupper (int);
> +int Digit2Val (int);
> +time_t time (time_t *);
> +
> +//
> +// Macros that directly map functions to BaseLib, BaseMemoryLib, and DebugLib functions
> +//
> +#define strcmp AsciiStrCmp
> +#define memcpy(dest,source,count) CopyMem(dest,source,(UINTN)(count))
> +#define memset(dest,ch,count) SetMem(dest,(UINTN)(count),(UINT8)(ch))
> +#define memchr(buf,ch,count) ScanMem8(buf,(UINTN)(count),(UINT8)ch)
> +#define memcmp(buf1,buf2,count) (int)(CompareMem(buf1,buf2,(UINTN)(count)))
> +#define memmove(dest,source,count) CopyMem(dest,source,(UINTN)(count))
> +#define strlen(str) (size_t)(AsciiStrnLenS(str,MAX_STRING_SIZE))
> +#define strcpy(strDest,strSource) AsciiStrCpyS(strDest,(strlen(strSource)+1),strSource)
> +#define strncpy(strDest,strSource,count) AsciiStrnCpyS(strDest,(UINTN)count,strSource,(UINTN)count)
> +#define strncpys(strDest, DestLen, strSource,count) AsciiStrnCpyS(strDest,DestLen,strSource,(UINTN)count)
> +#define strcat(strDest,strSource) AsciiStrCatS(strDest,(strlen(strSource)+strlen(strDest)+1),strSource)
> +#define strchr(str,ch) ScanMem8((VOID *)(str),AsciiStrSize(str),(UINT8)ch)
> +#define strncmp(string1,string2,count) (int)(AsciiStrnCmp(string1,string2,(UINTN)(count)))
> +#define strcasecmp(str1,str2) (int)AsciiStriCmp(str1,str2)
> +#define strstr(s1,s2) AsciiStrStr(s1,s2)
> +#define sprintf(buf,...) AsciiSPrint(buf,MAX_STRING_SIZE,__VA_ARGS__)
> +#define snprintf(buf,len,...) AsciiSPrint(buf,len,__VA_ARGS__)
> +#define vsnprintf(buf,len,format,marker) AsciiVSPrint((buf),(len),(format),(marker))
> +#define assert(expression) ASSERT(expression)
> +#define atoi(nptr) AsciiStrDecimalToUintn(nptr)
> +#define fabs(x) (((x) < 0.0)? (-x): (x))
> +#define offsetof(type,member) OFFSET_OF(type,member)
> +
> +#define EOF (-1)
> +
> +extern int errno;
> +
> +#define ERANGE 34 /* 34 Result too large */
> +
> +#endif
> diff --git a/RedfishPkg/Library/CrtLib/CrtLib.c b/RedfishPkg/Library/CrtLib/CrtLib.c
> new file mode 100644
> index 0000000000..1ff4023dbe
> --- /dev/null
> +++ b/RedfishPkg/Library/CrtLib/CrtLib.c
> @@ -0,0 +1,705 @@
> +/** @file
> + CRT wrapper functions for system call.
> +
> + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#include <Uefi.h>
> +#include <Library/CrtLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +
> +int errno = 0;
> +
> +/**
> + Determine if a particular character is an alphanumeric character
> + @return Returns 1 if c is an alphanumeric character, otherwise returns 0.
> +**/
> +int isalnum (int c)
> +{
> + //
> + // <alnum> ::= [0-9] | [a-z] | [A-Z]
> + //
> + return ((('0' <= (c)) && ((c) <= '9')) ||
> + (('a' <= (c)) && ((c) <= 'z')) ||
> + (('A' <= (c)) && ((c) <= 'Z')));
> +}
> +
> +/**
> + Determine if a particular character is a digital character
> +
> + @return Returns 1 if c is an digital character, otherwise returns 0.
> +**/
> +int isdchar (int c)
> +{
> + //
> + // [0-9] | [e +-.]
> + //
> + return ((('0' <= (c)) && ((c) <= '9')) ||
> + (c == 'e') || (c == 'E') ||
> + (c == '+') || (c == '-') ||
> + (c == '.'));
> +}
> +
> +/**
> + Determine if a particular character is a space character
> +
> + @return Returns 1 if c is a space character
> +**/
> +int isspace (int c)
> +{
> + //
> + // <space> ::= [ ]
> + //
> + return ((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) == '\n') || ((c) == '\v') || ((c) == '\f');
> +}
> +
> +/**
> + Allocates memory blocks
> +*/
> +void *malloc (size_t size)
> +{
> + return AllocatePool ((UINTN) size);
> +}
> +
> +/**
> + De-allocates or frees a memory block
> +*/
> +void free (void *ptr)
> +{
> + //
> + // In Standard C, free() handles a null pointer argument transparently. This
> + // is not true of FreePool() below, so protect it.
> + //
> + if (ptr != NULL) {
> + FreePool (ptr);
> + }
> +}
> +
> +/**
> + NetBSD Compatibility Function strdup creates a duplicate copy of a string.
> +
> + @return Returns the pointer to duplicated string.
> +**/
> +char * strdup(const char *str)
> +{
> + size_t len;
> + char *copy;
> +
> + len = strlen(str) + 1;
> + if ((copy = malloc(len)) == NULL)
> + return (NULL);
> + memcpy(copy, str, len);
> + return (copy);
> +}
> +
> +/** The toupper function converts a lowercase letter to a corresponding
> + uppercase letter.
> +
> + @param[in] c The character to be converted.
> +
> + @return If the argument is a character for which islower is true and
> + there are one or more corresponding characters, as specified by
> + the current locale, for which isupper is true, the toupper
> + function returns one of the corresponding characters (always the
> + same one for any given locale); otherwise, the argument is
> + returned unchanged.
> +**/
> +int
> +toupper(
> + IN int c
> + )
> +{
> + if ( (c >= 'a') && (c <= 'z') ) {
> + c = c - ('a' - 'A');
> + }
> + return c;
> +}
> +
> +/**
> + Digit to a value.
> +
> + @return Returns the value of digit.
> +**/
> +int
> +Digit2Val( int c)
> +{
> + if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))) { /* If c is one of [A-Za-z]... */
> + c = toupper(c) - 7; // Adjust so 'A' is ('9' + 1)
> + }
> + return c - '0'; // Value returned is between 0 and 35, inclusive.
> +}
> +
> +
> +/** The strtoll function converts the initial portion of the string pointed to
> + by nptr to long long int representation.
> +
> + See the description for strtol for more information.
> +
> + @return The strtoll function returns the converted value, if any. If no
> + conversion could be performed, zero is returned. If the correct
> + value is outside the range of representable values, LLONG_MIN or
> + LLONG_MAX is returned (according to the sign of the value, if any),
> + and the value of the macro ERANGE is stored in errno.
> +**/
> +long long
> +strtoll(const char * nptr, char ** endptr, int base)
> +{
> + const char *pEnd;
> + long long Result = 0;
> + long long Previous;
> + int temp;
> + BOOLEAN Negative = FALSE;
> +
> + pEnd = nptr;
> +
> + if((base < 0) || (base == 1) || (base > 36)) {
> + if(endptr != NULL) {
> + *endptr = NULL;
> + }
> + return 0;
> + }
> + // Skip leading spaces.
> + while(isspace(*nptr)) ++nptr;
> +
> + // Process Subject sequence: optional sign followed by digits.
> + if(*nptr == '+') {
> + Negative = FALSE;
> + ++nptr;
> + }
> + else if(*nptr == '-') {
> + Negative = TRUE;
> + ++nptr;
> + }
> +
> + if(*nptr == '0') { /* Might be Octal or Hex */
> + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> + if((base == 0) || (base == 16)) {
> + nptr += 2; /* Skip the "0X" */
> + base = 16; /* In case base was 0 */
> + }
> + }
> + else { /* Looks like Octal */
> + if((base == 0) || (base == 8)) {
> + ++nptr; /* Skip the leading "0" */
> + base = 8; /* In case base was 0 */
> + }
> + }
> + }
> + if(base == 0) { /* If still zero then must be decimal */
> + base = 10;
> + }
> + if(*nptr == '0') {
> + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> + pEnd = nptr;
> + }
> +
> + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> + Previous = Result;
> + Result = MultS64x64 (Result, base) + (long long int)temp;
> + if( Result <= Previous) { // Detect Overflow
> + if(Negative) {
> + Result = LLONG_MIN;
> + }
> + else {
> + Result = LLONG_MAX;
> + }
> + Negative = FALSE;
> + errno = ERANGE;
> + break;
> + }
> + pEnd = ++nptr;
> + }
> + if(Negative) {
> + Result = -Result;
> + }
> +
> + // Save pointer to final sequence
> + if(endptr != NULL) {
> + *endptr = (char *)pEnd;
> + }
> + return Result;
> +}
> +
> +/** The strtol, strtoll, strtoul, and strtoull functions convert the initial
> + portion of the string pointed to by nptr to long int, long long int,
> + unsigned long int, and unsigned long long int representation, respectively.
> + First, they decompose the input string into three parts: an initial,
> + possibly empty, sequence of white-space characters (as specified by the
> + isspace function), a subject sequence resembling an integer represented in
> + some radix determined by the value of base, and a final string of one or
> + more unrecognized characters, including the terminating null character of
> + the input string. Then, they attempt to convert the subject sequence to an
> + integer, and return the result.
> +
> + If the value of base is zero, the expected form of the subject sequence is
> + that of an integer constant, optionally preceded
> + by a plus or minus sign, but not including an integer suffix. If the value
> + of base is between 2 and 36 (inclusive), the expected form of the subject
> + sequence is a sequence of letters and digits representing an integer with
> + the radix specified by base, optionally preceded by a plus or minus sign,
> + but not including an integer suffix. The letters from a (or A) through z
> + (or Z) are ascribed the values 10 through 35; only letters and digits whose
> + ascribed values are less than that of base are permitted. If the value of
> + base is 16, the characters 0x or 0X may optionally precede the sequence of
> + letters and digits, following the sign if present.
> +
> + The subject sequence is defined as the longest initial subsequence of the
> + input string, starting with the first non-white-space character, that is of
> + the expected form. The subject sequence contains no characters if the input
> + string is empty or consists entirely of white space, or if the first
> + non-white-space character is other than a sign or a permissible letter or digit.
> +
> + If the subject sequence has the expected form and the value of base is
> + zero, the sequence of characters starting with the first digit is
> + interpreted as an integer constant. If the subject sequence has the
> + expected form and the value of base is between 2 and 36, it is used as the
> + base for conversion, ascribing to each letter its value as given above. If
> + the subject sequence begins with a minus sign, the value resulting from the
> + conversion is negated (in the return type). A pointer to the final string
> + is stored in the object pointed to by endptr, provided that endptr is
> + not a null pointer.
> +
> + In other than the "C" locale, additional locale-specific subject sequence
> + forms may be accepted.
> +
> + If the subject sequence is empty or does not have the expected form, no
> + conversion is performed; the value of nptr is stored in the object pointed
> + to by endptr, provided that endptr is not a null pointer.
> +
> + @return The strtol, strtoll, strtoul, and strtoull functions return the
> + converted value, if any. If no conversion could be performed, zero
> + is returned. If the correct value is outside the range of
> + representable values, LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX,
> + ULONG_MAX, or ULLONG_MAX is returned (according to the return type
> + and sign of the value, if any), and the value of the macro ERANGE
> + is stored in errno.
> +**/
> +long
> +strtol(const char * nptr, char ** endptr, int base)
> +{
> + const char *pEnd;
> + long Result = 0;
> + long Previous;
> + int temp;
> + BOOLEAN Negative = FALSE;
> +
> + pEnd = nptr;
> +
> + if((base < 0) || (base == 1) || (base > 36)) {
> + if(endptr != NULL) {
> + *endptr = NULL;
> + }
> + return 0;
> + }
> + // Skip leading spaces.
> + while(isspace(*nptr)) ++nptr;
> +
> + // Process Subject sequence: optional sign followed by digits.
> + if(*nptr == '+') {
> + Negative = FALSE;
> + ++nptr;
> + }
> + else if(*nptr == '-') {
> + Negative = TRUE;
> + ++nptr;
> + }
> +
> + if(*nptr == '0') { /* Might be Octal or Hex */
> + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> + if((base == 0) || (base == 16)) {
> + nptr += 2; /* Skip the "0X" */
> + base = 16; /* In case base was 0 */
> + }
> + }
> + else { /* Looks like Octal */
> + if((base == 0) || (base == 8)) {
> + ++nptr; /* Skip the leading "0" */
> + base = 8; /* In case base was 0 */
> + }
> + }
> + }
> + if(base == 0) { /* If still zero then must be decimal */
> + base = 10;
> + }
> + if(*nptr == '0') {
> + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> + pEnd = nptr;
> + }
> +
> + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> + Previous = Result;
> + Result = (Result * base) + (long int)temp;
> + if( Result <= Previous) { // Detect Overflow
> + if(Negative) {
> + Result = LONG_MIN;
> + }
> + else {
> + Result = LONG_MAX;
> + }
> + Negative = FALSE;
> + errno = ERANGE;
> + break;
> + }
> + pEnd = ++nptr;
> + }
> + if(Negative) {
> + Result = -Result;
> + }
> +
> + // Save pointer to final sequence
> + if(endptr != NULL) {
> + *endptr = (char *)pEnd;
> + }
> + return Result;
> +}
> +
> +/** The strtoull function converts the initial portion of the string pointed to
> + by nptr to unsigned long long int representation.
> +
> + See the description for strtol for more information.
> +
> + @return The strtoull function returns the converted value, if any. If no
> + conversion could be performed, zero is returned. If the correct
> + value is outside the range of representable values, ULLONG_MAX is
> + returned and the value of the macro ERANGE is stored in errno.
> +**/
> +unsigned long long
> +strtoull(const char * nptr, char ** endptr, int base)
> +{
> + const char *pEnd;
> + unsigned long long Result = 0;
> + unsigned long long Previous;
> + int temp;
> +
> + pEnd = nptr;
> +
> + if((base < 0) || (base == 1) || (base > 36)) {
> + if(endptr != NULL) {
> + *endptr = NULL;
> + }
> + return 0;
> + }
> + // Skip leading spaces.
> + while(isspace(*nptr)) ++nptr;
> +
> + // Process Subject sequence: optional + sign followed by digits.
> + if(*nptr == '+') {
> + ++nptr;
> + }
> +
> + if(*nptr == '0') { /* Might be Octal or Hex */
> + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> + if((base == 0) || (base == 16)) {
> + nptr += 2; /* Skip the "0X" */
> + base = 16; /* In case base was 0 */
> + }
> + }
> + else { /* Looks like Octal */
> + if((base == 0) || (base == 8)) {
> + ++nptr; /* Skip the leading "0" */
> + base = 8; /* In case base was 0 */
> + }
> + }
> + }
> + if(base == 0) { /* If still zero then must be decimal */
> + base = 10;
> + }
> + if(*nptr == '0') {
> + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> + pEnd = nptr;
> + }
> +
> + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> + Previous = Result;
> + Result = DivU64x32 (Result, base) + (unsigned long long)temp;
> + if( Result < Previous) { // If we overflowed
> + Result = ULLONG_MAX;
> + errno = ERANGE;
> + break;
> + }
> + pEnd = ++nptr;
> + }
> +
> + // Save pointer to final sequence
> + if(endptr != NULL) {
> + *endptr = (char *)pEnd;
> + }
> + return Result;
> +}
> +
> +/**
> + edk2 Jansson port does not support doubles, simply return 0.
> +
> + These conversion functions convert the initial portion of the string
> + pointed to by nptr to double, float, and long double representation,
> + respectively.
> +
> + The strtod(), strtof(), and strtold() functions return the converted
> + value, if any.
> +
> + If endptr is not NULL, a pointer to the character after the last charac-
> + ter used in the conversion is stored in the location referenced by
> + endptr.
> +
> + If no conversion is performed, zero is returned and the value of nptr is
> + stored in the location referenced by endptr.
> +
> + If the correct value would cause overflow, plus or minus HUGE_VAL,
> + HUGE_VALF, or HUGE_VALL is returned (according to the sign and type of
> + the return value), and ERANGE is stored in errno. If the correct value
> + would cause underflow, zero is returned and ERANGE is stored in errno.
> +
> + @return Return 0.
> +**/
> +double
> +strtod (const char * __restrict nptr, char ** __restrict endptr) {
> + if(endptr)
> + *endptr = (char *)(nptr + strlen(nptr));
> +
> + return (double)0;
> +}
> +
> +/**
> + Allocate and zero-initialize array.
> +**/
> +void *
> +calloc(size_t Num, size_t Size)
> +{
> + void *RetVal;
> + size_t NumSize;
> +
> + NumSize = Num * Size;
> + RetVal = NULL;
> + if (NumSize != 0) {
> + RetVal = malloc(NumSize);
> + if( RetVal != NULL) {
> + (VOID)ZeroMem( RetVal, NumSize);
> + }
> + }
> + DEBUG((DEBUG_POOL, "0x%p = calloc(%d, %d)\n", RetVal, Num, Size));
> +
> + return RetVal;
> +}
> +
> +//
> +// The arrays give the cumulative number of days up to the first of the
> +// month number used as the index (1 -> 12) for regular and leap years.
> +// The value at index 13 is for the whole year.
> +//
> +UINTN CumulativeDays[2][14] = {
> + {
> + 0,
> + 0,
> + 31,
> + 31 + 28,
> + 31 + 28 + 31,
> + 31 + 28 + 31 + 30,
> + 31 + 28 + 31 + 30 + 31,
> + 31 + 28 + 31 + 30 + 31 + 30,
> + 31 + 28 + 31 + 30 + 31 + 30 + 31,
> + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
> + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
> + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
> + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
> + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
> + },
> + {
> + 0,
> + 0,
> + 31,
> + 31 + 29,
> + 31 + 29 + 31,
> + 31 + 29 + 31 + 30,
> + 31 + 29 + 31 + 30 + 31,
> + 31 + 29 + 31 + 30 + 31 + 30,
> + 31 + 29 + 31 + 30 + 31 + 30 + 31,
> + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,
> + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
> + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
> + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
> + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
> + }
> +};
> +
> +#define IsLeap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
> +#define SECSPERMIN (60)
> +#define SECSPERHOUR (60 * 60)
> +#define SECSPERDAY (24 * SECSPERHOUR)
> +
> +/**
> + Get the system time as seconds elapsed since midnight, January 1, 1970.
> +**/
> +time_t time (time_t *timer)
> +{
> + EFI_TIME Time;
> + time_t CalTime;
> + UINTN Year;
> +
> + //
> + // Get the current time and date information
> + //
> + gRT->GetTime (&Time, NULL);
> +
> + //
> + // Years Handling
> + // UTime should now be set to 00:00:00 on Jan 1 of the current year.
> + //
> + for (Year = 1970, CalTime = 0; Year != Time.Year; Year++) {
> + CalTime = CalTime + (time_t)(CumulativeDays[IsLeap(Year)][13] * SECSPERDAY);
> + }
> +
> + //
> + // Add in number of seconds for current Month, Day, Hour, Minute, Seconds, and TimeZone adjustment
> + //
> + CalTime = CalTime +
> + (time_t)((Time.TimeZone != EFI_UNSPECIFIED_TIMEZONE) ? (Time.TimeZone * 60) : 0) +
> + (time_t)(CumulativeDays[IsLeap(Time.Year)][Time.Month] * SECSPERDAY) +
> + (time_t)(((Time.Day > 0) ? Time.Day - 1 : 0) * SECSPERDAY) +
> + (time_t)(Time.Hour * SECSPERHOUR) +
> + (time_t)(Time.Minute * 60) +
> + (time_t)Time.Second;
> +
> + if (timer != NULL) {
> + *timer = CalTime;
> + }
> +
> + return CalTime;
> +}
> +
> +typedef
> +int
> +(*SORT_COMPARE)(
> + IN VOID *Buffer1,
> + IN VOID *Buffer2
> + );
> +
> +/**
> + Duplicated from EDKII BaseSortLib for qsort() wrapper
> + @param[in, out] BufferToSort on call a Buffer of (possibly sorted) elements
> + on return a buffer of sorted elements
> + @param[in] Count the number of elements in the buffer to sort
> + @param[in] ElementSize Size of an element in bytes
> + @param[in] CompareFunction The function to call to perform the comparison
> + of any 2 elements
> + @param[in] Buffer Buffer of size ElementSize for use in swapping
> +**/
> +STATIC
> +VOID
> +QuickSortWorker (
> + IN OUT VOID *BufferToSort,
> + IN CONST UINTN Count,
> + IN CONST UINTN ElementSize,
> + IN SORT_COMPARE CompareFunction,
> + IN VOID *Buffer
> + )
> +{
> + VOID *Pivot;
> + UINTN LoopCount;
> + UINTN NextSwapLocation;
> +
> + ASSERT(BufferToSort != NULL);
> + ASSERT(CompareFunction != NULL);
> + ASSERT(Buffer != NULL);
> +
> + if (Count < 2 || ElementSize < 1) {
> + return;
> + }
> +
> + NextSwapLocation = 0;
> +
> + //
> + // Pick a pivot (we choose last element)
> + //
> + Pivot = ((UINT8 *)BufferToSort + ((Count - 1) * ElementSize));
> +
> + //
> + // Now get the pivot such that all on "left" are below it
> + // and everything "right" are above it
> + //
> + for (LoopCount = 0; LoopCount < Count - 1; LoopCount++)
> + {
> + //
> + // If the element is less than the pivot
> + //
> + if (CompareFunction ((VOID *)((UINT8 *)BufferToSort + ((LoopCount) * ElementSize)), Pivot) <= 0) {
> + //
> + // Swap
> + //
> + CopyMem (Buffer, (UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), ElementSize);
> + CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), (UINT8 *)BufferToSort + ((LoopCount) *
> ElementSize), ElementSize);
> + CopyMem ((UINT8 *)BufferToSort + ((LoopCount) * ElementSize), Buffer, ElementSize);
> +
> + //
> + // Increment NextSwapLocation
> + //
> + NextSwapLocation++;
> + }
> + }
> + //
> + // Swap pivot to it's final position (NextSwapLocaiton)
> + //
> + CopyMem (Buffer, Pivot, ElementSize);
> + CopyMem (Pivot, (UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), ElementSize);
> + CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), Buffer, ElementSize);
> +
> + //
> + // Now recurse on 2 paritial lists. Neither of these will have the 'pivot' element.
> + // IE list is sorted left half, pivot element, sorted right half...
> + //
> + QuickSortWorker (
> + BufferToSort,
> + NextSwapLocation,
> + ElementSize,
> + CompareFunction,
> + Buffer
> + );
> +
> + QuickSortWorker (
> + (UINT8 *)BufferToSort + (NextSwapLocation + 1) * ElementSize,
> + Count - NextSwapLocation - 1,
> + ElementSize,
> + CompareFunction,
> + Buffer
> + );
> +
> + return;
> +}
> +
> +/**
> + Performs a quick sort
> +**/
> +void qsort (void *base, size_t num, size_t width, int (*compare)(const void *, const void *))
> +{
> + VOID *Buffer;
> +
> + ASSERT (base != NULL);
> + ASSERT (compare != NULL);
> +
> + //
> + // Use CRT-style malloc to cover BS and RT memory allocation.
> + //
> + Buffer = malloc (width);
> + ASSERT (Buffer != NULL);
> +
> + //
> + // Re-use PerformQuickSort() function Implementation in EDKII BaseSortLib.
> + //
> + QuickSortWorker (base, (UINTN)num, (UINTN)width, (SORT_COMPARE)compare, Buffer);
> +
> + free (Buffer);
> + return;
> +}
> +
> +/**
> + Get character from stream, we don't support file operastion on edk2 JSON library.
> +
> + @return Returns the character currently pointed by the internal file position indicator of the specified stream
> +
> +**/
> +int fgetc(FILE * _File){
> + return 0;
> +}
> diff --git a/RedfishPkg/Library/CrtLib/CrtLib.inf b/RedfishPkg/Library/CrtLib/CrtLib.inf
> new file mode 100644
> index 0000000000..b514817cf4
> --- /dev/null
> +++ b/RedfishPkg/Library/CrtLib/CrtLib.inf
> @@ -0,0 +1,37 @@
> +## @file
> +# EDK2 C Runtime Library for opensource project.
> +#
> +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +# (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x0001001b
> + BASE_NAME = CrtLib
> + FILE_GUID = 8263B8AC-D021-425D-B337-3EC96F5DC19B
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = CrtLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION
> UEFI_DRIVER
> +
> +#
> +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64
> +#
> +
> +[Sources]
> + CrtLib.c
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> + MemoryAllocationLib
> + UefiRuntimeServicesTableLib
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + RedfishPkg/RedfishPkg.dec
> +
> +
> diff --git a/RedfishPkg/RedfishLibs.dsc.inc b/RedfishPkg/RedfishLibs.dsc.inc
> index d4c08e18ac..2a951bd8fa 100644
> --- a/RedfishPkg/RedfishLibs.dsc.inc
> +++ b/RedfishPkg/RedfishLibs.dsc.inc
> @@ -12,5 +12,6 @@
> ##
> !if $(REDFISH_ENABLE) == TRUE
> Ucs2Utf8Lib|RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> + CrtLib|RedfishPkg/Library/CrtLib/CrtLib.inf
> !endif
>
> diff --git a/RedfishPkg/RedfishPkg.ci.yaml b/RedfishPkg/RedfishPkg.ci.yaml
> index 20c297ad22..9895fdac99 100644
> --- a/RedfishPkg/RedfishPkg.ci.yaml
> +++ b/RedfishPkg/RedfishPkg.ci.yaml
> @@ -17,6 +17,25 @@
> ],
> ## Both file path and directory path are accepted.
> "IgnoreFiles": [
> + ## Below are files incorporated with open source which are
> + ## not edk2 coding standard compliant.
> + ##
> + ## EDK2 CRT library which is not edk2 coding
> + ## standard compliant.
> + ## C runtime library for EDKII JsonLib.
> + "Include/Crt/sys",
> + "Include/Crt/assert.h",
> + "Include/Crt/errno.h",
> + "Include/Crt/limits.h",
> + "Include/Crt/math.h",
> + "Include/Crt/stdarg.h",
> + "Include/Crt/stddef.h",
> + "Include/Crt/stdio.h",
> + "Include/Crt/stdlib.h",
> + "Include/Crt/string.h",
> + "Include/Crt/time.h",
> + "Include/Library/CrtLib.h",
> + "Library/CrtLib/CrtLib.c"
> ]
> },
> "CompilerPlugin": {
> diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec
> index aecc1f4a3a..2142b43640 100644
> --- a/RedfishPkg/RedfishPkg.dec
> +++ b/RedfishPkg/RedfishPkg.dec
> @@ -15,16 +15,24 @@
>
> [Includes]
> Include
> + Include/Crt # Header files for C RTL.
>
> [LibraryClasses]
> ## @libraryclass Platform Redfish Host Interface Library
> # Platform implementation-specific Redfish Host Interface.
> RedfishPlatformHostInterfaceLib|Include/Library/RedfishHostInterfaceLib.h
> +
> ## @libraryclass This library provides UCS2 to UTF8 manipulation
> # functions.
> #
> Ucs2Utf8Lib|Include/Library/BaseUcs2Utf8Lib.h
>
> + ## @libraryclass Provides the C runtime library functions
> + # CRT library is currently used by edk2 JsonLib (open source
> + # jansson project) and edk2 RedfishLib (libredfish open source
> + # project).
> + CrtLib|Include/Library/CrtLib.h
> +
> [Protocols]
> ## Include/Protocol/RedfishDiscover.h
> gEfiRedfishDiscoverProtocolGuid = { 0x5db12509, 0x4550, 0x4347, { 0x96, 0xb3, 0x73, 0xc0, 0xff, 0x6e, 0x86, 0x9f
> }}
> diff --git a/RedfishPkg/RedfishPkg.dsc b/RedfishPkg/RedfishPkg.dsc
> index 3639b620e6..aa1ccd5a95 100644
> --- a/RedfishPkg/RedfishPkg.dsc
> +++ b/RedfishPkg/RedfishPkg.dsc
> @@ -48,5 +48,6 @@
> [Components]
> RedfishPkg/Library/PlatformHostInterfaceLibNull/PlatformHostInterfaceLibNull.inf
> RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> + RedfishPkg/Library/CrtLib/CrtLib.inf
>
> !include RedfishPkg/Redfish.dsc.inc
> --
> 2.17.1
>
>
>
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime library
2020-12-15 0:19 ` Michael D Kinney
@ 2020-12-16 4:38 ` Abner Chang
[not found] ` <CS1PR8401MB1144B554CE75DDDA5E4C1ECEFFC50@CS1PR8401MB1144.NAMPRD84.PROD.OUTLOOK.COM>
1 sibling, 0 replies; 15+ messages in thread
From: Abner Chang @ 2020-12-16 4:38 UTC (permalink / raw)
To: Kinney, Michael D, devel@edk2.groups.io
Cc: Leif Lindholm, Wang, Nickle (HPS SW), O'Hanley, Peter (EXL)
> -----Original Message-----
> From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> Sent: Tuesday, December 15, 2020 8:20 AM
> To: devel@edk2.groups.io; Chang, Abner (HPS SW/FW Technologist)
> <abner.chang@hpe.com>; Kinney, Michael D <michael.d.kinney@intel.com>
> Cc: Leif Lindholm <leif@nuviainc.com>; Wang, Nickle (HPS SW)
> <nickle.wang@hpe.com>; O'Hanley, Peter (EXL) <peter.ohanley@hpe.com>
> Subject: RE: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime library
>
> Hi Abner,
>
> I see what appears to be some duplication of the qsort source code.
>
> Can you use the PerformQuickSort() API from the QsortLib in the
> MdeModulePkg?
Done thanks!
>
> Thanks,
>
> Mike
>
> > -----Original Message-----
> > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Abner
> > Chang
> > Sent: Sunday, December 13, 2020 7:53 PM
> > To: devel@edk2.groups.io
> > Cc: Leif Lindholm <leif@nuviainc.com>; Nickle Wang
> > <nickle.wang@hpe.com>; Peter O'Hanley <peter.ohanley@hpe.com>
> > Subject: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime
> > library
> >
> > CRT library is currently used by edk2 JsonLib (open source jansson
> > project) and edk2 RedfishLib (libredfish open source project). CrtLib
> > library provides the necessary C runtime equivalent edk2 functions for
> > open source projects.
> >
> > Signed-off-by: Abner Chang <abner.chang@hpe.com>
> >
> > Cc: Leif Lindholm <leif@nuviainc.com>
> > Cc: Nickle Wang <nickle.wang@hpe.com>
> > Cc: Peter O'Hanley <peter.ohanley@hpe.com>
> > ---
> > RedfishPkg/Include/Crt/assert.h | 16 +
> > RedfishPkg/Include/Crt/errno.h | 16 +
> > RedfishPkg/Include/Crt/limits.h | 16 +
> > RedfishPkg/Include/Crt/math.h | 16 +
> > RedfishPkg/Include/Crt/stdarg.h | 15 +
> > RedfishPkg/Include/Crt/stddef.h | 16 +
> > RedfishPkg/Include/Crt/stdio.h | 15 +
> > RedfishPkg/Include/Crt/stdlib.h | 16 +
> > RedfishPkg/Include/Crt/string.h | 16 +
> > RedfishPkg/Include/Crt/sys/time.h | 15 +
> > RedfishPkg/Include/Crt/sys/types.h | 15 +
> > RedfishPkg/Include/Crt/time.h | 15 +
> > RedfishPkg/Include/Library/CrtLib.h | 195 ++++++++
> > RedfishPkg/Library/CrtLib/CrtLib.c | 705
> +++++++++++++++++++++++++++
> > RedfishPkg/Library/CrtLib/CrtLib.inf | 37 ++
> > RedfishPkg/RedfishLibs.dsc.inc | 1 +
> > RedfishPkg/RedfishPkg.ci.yaml | 19 +
> > RedfishPkg/RedfishPkg.dec | 8 +
> > RedfishPkg/RedfishPkg.dsc | 1 +
> > 19 files changed, 1153 insertions(+)
> > create mode 100644 RedfishPkg/Include/Crt/assert.h create mode
> > 100644 RedfishPkg/Include/Crt/errno.h create mode 100644
> > RedfishPkg/Include/Crt/limits.h create mode 100644
> > RedfishPkg/Include/Crt/math.h create mode 100644
> > RedfishPkg/Include/Crt/stdarg.h create mode 100644
> > RedfishPkg/Include/Crt/stddef.h create mode 100644
> > RedfishPkg/Include/Crt/stdio.h create mode 100644
> > RedfishPkg/Include/Crt/stdlib.h create mode 100644
> > RedfishPkg/Include/Crt/string.h create mode 100644
> > RedfishPkg/Include/Crt/sys/time.h create mode 100644
> > RedfishPkg/Include/Crt/sys/types.h
> > create mode 100644 RedfishPkg/Include/Crt/time.h create mode 100644
> > RedfishPkg/Include/Library/CrtLib.h
> > create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.c
> > create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.inf
> >
> > diff --git a/RedfishPkg/Include/Crt/assert.h
> > b/RedfishPkg/Include/Crt/assert.h new file mode 100644 index
> > 0000000000..f9ab7ef9ca
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/assert.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_ASSERT_H_
> > +#define CRT_ASSERT_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/errno.h
> > b/RedfishPkg/Include/Crt/errno.h new file mode 100644 index
> > 0000000000..d30aee14de
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/errno.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_ERRNO_H_
> > +#define CRT_ERRNO_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/limits.h
> > b/RedfishPkg/Include/Crt/limits.h new file mode 100644 index
> > 0000000000..f3bdd33f2a
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/limits.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_LIMITS_H_
> > +#define CRT_LIMITS_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/math.h
> > b/RedfishPkg/Include/Crt/math.h new file mode 100644 index
> > 0000000000..984c0ccc21
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/math.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_MATH_H_
> > +#define CRT_MATH_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/stdarg.h
> > b/RedfishPkg/Include/Crt/stdarg.h new file mode 100644 index
> > 0000000000..d5a314ad3b
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/stdarg.h
> > @@ -0,0 +1,15 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#ifndef CRT_STDARG_H_
> > +#define CRT_STDARG_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/stddef.h
> > b/RedfishPkg/Include/Crt/stddef.h new file mode 100644 index
> > 0000000000..15a37bf50e
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/stddef.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_STDDEF_H_
> > +#define CRT_STDDEF_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/stdio.h
> > b/RedfishPkg/Include/Crt/stdio.h new file mode 100644 index
> > 0000000000..25e610be10
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/stdio.h
> > @@ -0,0 +1,15 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#ifndef CRT_STDIO_H_
> > +#define CRT_STDIO_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/stdlib.h
> > b/RedfishPkg/Include/Crt/stdlib.h new file mode 100644 index
> > 0000000000..5b3dd273c8
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/stdlib.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_STDLIB_H_
> > +#define CRT_STDLIB_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/string.h
> > b/RedfishPkg/Include/Crt/string.h new file mode 100644 index
> > 0000000000..f60b87ccd2
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/string.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_STRING_H_
> > +#define CRT_STRING_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/sys/time.h
> > b/RedfishPkg/Include/Crt/sys/time.h
> > new file mode 100644
> > index 0000000000..4ced176cda
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/sys/time.h
> > @@ -0,0 +1,15 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#ifndef CRT_SYS_TIME_H_
> > +#define CRT_SYS_TIME_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/sys/types.h
> > b/RedfishPkg/Include/Crt/sys/types.h
> > new file mode 100644
> > index 0000000000..c4f807214c
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/sys/types.h
> > @@ -0,0 +1,15 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#ifndef CRT_SYS_TYPES_H_
> > +#define CRT_SYS_TYPES_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Crt/time.h
> > b/RedfishPkg/Include/Crt/time.h new file mode 100644 index
> > 0000000000..ca04ac8730
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Crt/time.h
> > @@ -0,0 +1,15 @@
> > +/** @file
> > + Include file to support building the third-party jansson library.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#ifndef CRT_TIME_H_
> > +#define CRT_TIME_H_
> > +
> > +#include <Library/CrtLib.h>
> > +
> > +#endif
> > diff --git a/RedfishPkg/Include/Library/CrtLib.h
> > b/RedfishPkg/Include/Library/CrtLib.h
> > new file mode 100644
> > index 0000000000..8c7484e75b
> > --- /dev/null
> > +++ b/RedfishPkg/Include/Library/CrtLib.h
> > @@ -0,0 +1,195 @@
> > +/** @file
> > + CRT wrapper head functions for jansson system call.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef CRT_LIB_H_
> > +#define CRT_LIB_H_
> > +
> > +#include <Library/BaseLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/PrintLib.h>
> > +
> > +#define MAX_STRING_SIZE 0x10000000
> > +
> > +// Minimum value for an object of type long long int.
> > +#define LLONG_MIN MIN_INT64
> > +
> > +// Maximum value for an object of type long long int.
> > +#define LLONG_MAX MAX_INT64
> > +
> > +// We dont support double on edk2
> > +#define HUGE_VAL 0
> > +
> > +#if defined(MDE_CPU_X64) || defined(MDE_CPU_AARCH64) ||
> > +defined(MDE_CPU_IA64) || defined(MDE_CPU_RISCV64) // // With GCC
> we
> > +would normally use SIXTY_FOUR_BIT_LONG, but MSVC needs //
> > +SIXTY_FOUR_BIT, because 'long' is 32-bit and only 'long long' is //
> > +64-bit. Since using 'long long' works fine on GCC too, just do that.
> > +//
> > +#define SIXTY_FOUR_BIT
> > +#elif defined(MDE_CPU_IA32) || defined(MDE_CPU_ARM) ||
> > +defined(MDE_CPU_EBC) #define THIRTY_TWO_BIT #endif
> > +
> > +//
> > +// Map all va_xxxx elements to VA_xxx defined in
> > +MdePkg/Include/Base.h // #if !defined(__CC_ARM) // if va_list is not
> > +already defined
> > +#define va_list VA_LIST
> > +#define va_arg VA_ARG
> > +#define va_start VA_START
> > +#define va_end VA_END
> > +#else // __CC_ARM
> > +#define va_start(Marker, Parameter) __va_start(Marker, Parameter)
> > +#define va_arg(Marker, TYPE) __va_arg(Marker, TYPE)
> > +#define va_end(Marker) ((void)0)
> > +#endif
> > +
> > +//
> > +// Definitions for global constants used by CRT library routines //
> > +#define INT_MAX MAX_INT32 /* Maximum (signed) int value */
> > +#define LONG_MAX 0X7FFFFFFFL /* max value for a long */
> > +#define LONG_MIN (-LONG_MAX-1) /* min value for a long */
> > +#define ULONG_MAX 0xFFFFFFFF /* Maximum unsigned long value
> */
> > +#define CHAR_BIT 8 /* Number of bits in a char */
> > +
> > +// Maximum value for an object of type unsigned long long int.
> > +#define ULLONG_MAX 0xFFFFFFFFFFFFFFFFULL // 2^64 - 1 // Maximum
> > +value for an object of type unsigned char.
> > +#define UCHAR_MAX 255 // 2^8 - 1
> > +
> > +//
> > +// Basic types mapping
> > +//
> > +typedef UINTN size_t;
> > +typedef INTN ssize_t;
> > +typedef INT32 time_t;
> > +typedef UINT8 __uint8_t;
> > +typedef UINT8 sa_family_t;
> > +typedef UINT32 uid_t;
> > +typedef UINT32 gid_t;
> > +typedef INT32 int32_t;
> > +typedef UINT32 uint32_t;
> > +typedef UINT16 uint16_t;
> > +typedef UINT8 uint8_t;
> > +typedef enum {false, true} bool;
> > +
> > +//
> > +// File operations are not required for EFI building, // so FILE is
> > +mapped to VOID * to pass build // typedef VOID *FILE;
> > +
> > +//
> > +// Global variables
> > +//
> > +extern int errno;
> > +extern FILE *stderr;
> > +
> > +//
> > +// Function prototypes of CRT Library routines //
> > +void *malloc (size_t);
> > +void *realloc (void *, size_t);
> > +void *calloc (size_t Num, size_t Size);
> > +void free (void *);
> > +void *memset (void *, int, size_t);
> > +int memcmp (const void *, const void *, size_t);
> > +int isdigit (int);
> > +int isspace (int);
> > +int tolower (int);
> > +int isupper (int);
> > +int isxdigit (int);
> > +int isalnum (int);
> > +void *memcpy (void *, const void *, size_t);
> > +void *memset (void *, int, size_t);
> > +void *memchr (const void *, int, size_t);
> > +int memcmp (const void *, const void *, size_t);
> > +void *memmove (void *, const void *, size_t);
> > +int strcmp (const char *, const char *);
> > +int strncmp (const char *, const char *, size_t);
> > +char *strcpy (char *, const char *);
> > +size_t strlen (const char *);
> > +char *strcat (char *, const char *);
> > +char *strchr (const char *, int);
> > +int strcasecmp (const char *, const char *);
> > +int strncasecmp (const char *, const char *, size_t);
> > +char *strncpy (char *, size_t, const char *, size_t);
> > +int strncmp (const char *, const char *, size_t);
> > +char *strrchr (const char *, int);
> > +unsigned long strtoul (const char *, char **, int);
> > +char * strstr (const char *s1 , const char *s2);
> > +long strtol (const char *, char **, int);
> > +char *strerror (int);
> > +size_t strspn (const char *, const char *);
> > +char * strdup (const char *str);
> > +char * strpbrk (const char *s1, const char *s2);
> > +unsigned long long strtoull(const char * nptr, char ** endptr, int base);
> > +long long strtoll (const char * nptr, char ** endptr, int base);
> > +long strtol (const char * nptr, char ** endptr, int base);
> > +double strtod (const char * __restrict nptr, char ** __restrict
> endptr);
> > +size_t strcspn (const char *, const char *);
> > +int printf (const char *, ...);
> > +int sscanf (const char *, const char *, ...);
> > +FILE *fopen (const char *, const char *);
> > +size_t fread (void *, size_t, size_t, FILE *);
> > +size_t fwrite (const void *, size_t, size_t, FILE *);
> > +int fclose (FILE *);
> > +int fprintf (FILE *, const char *, ...);
> > +int fgetc (FILE * _File);
> > +uid_t getuid (void);
> > +uid_t geteuid (void);
> > +gid_t getgid (void);
> > +gid_t getegid (void);
> > +void qsort (void *, size_t, size_t, int (*)(const void *, const void
> *));
> > +char *getenv (const char *);
> > +#if defined(__GNUC__) && (__GNUC__ >= 2)
> > +void abort (void) __attribute__((__noreturn__));
> > +#else
> > +void abort (void);
> > +#endif
> > +int toupper (int);
> > +int Digit2Val (int);
> > +time_t time (time_t *);
> > +
> > +//
> > +// Macros that directly map functions to BaseLib, BaseMemoryLib, and
> > +DebugLib functions //
> > +#define strcmp AsciiStrCmp
> > +#define memcpy(dest,source,count)
> CopyMem(dest,source,(UINTN)(count))
> > +#define memset(dest,ch,count)
> SetMem(dest,(UINTN)(count),(UINT8)(ch))
> > +#define memchr(buf,ch,count)
> ScanMem8(buf,(UINTN)(count),(UINT8)ch)
> > +#define memcmp(buf1,buf2,count)
> (int)(CompareMem(buf1,buf2,(UINTN)(count)))
> > +#define memmove(dest,source,count)
> CopyMem(dest,source,(UINTN)(count))
> > +#define strlen(str)
> (size_t)(AsciiStrnLenS(str,MAX_STRING_SIZE))
> > +#define strcpy(strDest,strSource)
> AsciiStrCpyS(strDest,(strlen(strSource)+1),strSource)
> > +#define strncpy(strDest,strSource,count)
> > +AsciiStrnCpyS(strDest,(UINTN)count,strSource,(UINTN)count)
> > +#define strncpys(strDest, DestLen, strSource,count)
> AsciiStrnCpyS(strDest,DestLen,strSource,(UINTN)count)
> > +#define strcat(strDest,strSource)
> AsciiStrCatS(strDest,(strlen(strSource)+strlen(strDest)+1),strSource)
> > +#define strchr(str,ch) ScanMem8((VOID
> *)(str),AsciiStrSize(str),(UINT8)ch)
> > +#define strncmp(string1,string2,count)
> (int)(AsciiStrnCmp(string1,string2,(UINTN)(count)))
> > +#define strcasecmp(str1,str2) (int)AsciiStriCmp(str1,str2)
> > +#define strstr(s1,s2) AsciiStrStr(s1,s2)
> > +#define sprintf(buf,...)
> AsciiSPrint(buf,MAX_STRING_SIZE,__VA_ARGS__)
> > +#define snprintf(buf,len,...) AsciiSPrint(buf,len,__VA_ARGS__)
> > +#define vsnprintf(buf,len,format,marker)
> AsciiVSPrint((buf),(len),(format),(marker))
> > +#define assert(expression) ASSERT(expression)
> > +#define atoi(nptr) AsciiStrDecimalToUintn(nptr)
> > +#define fabs(x) (((x) < 0.0)? (-x): (x))
> > +#define offsetof(type,member) OFFSET_OF(type,member)
> > +
> > +#define EOF (-1)
> > +
> > +extern int errno;
> > +
> > +#define ERANGE 34 /* 34 Result too large */
> > +
> > +#endif
> > diff --git a/RedfishPkg/Library/CrtLib/CrtLib.c
> > b/RedfishPkg/Library/CrtLib/CrtLib.c
> > new file mode 100644
> > index 0000000000..1ff4023dbe
> > --- /dev/null
> > +++ b/RedfishPkg/Library/CrtLib/CrtLib.c
> > @@ -0,0 +1,705 @@
> > +/** @file
> > + CRT wrapper functions for system call.
> > +
> > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#include <Uefi.h>
> > +#include <Library/CrtLib.h>
> > +#include <Library/MemoryAllocationLib.h> #include
> > +<Library/UefiRuntimeServicesTableLib.h>
> > +
> > +int errno = 0;
> > +
> > +/**
> > + Determine if a particular character is an alphanumeric character
> > + @return Returns 1 if c is an alphanumeric character, otherwise returns 0.
> > +**/
> > +int isalnum (int c)
> > +{
> > + //
> > + // <alnum> ::= [0-9] | [a-z] | [A-Z]
> > + //
> > + return ((('0' <= (c)) && ((c) <= '9')) ||
> > + (('a' <= (c)) && ((c) <= 'z')) ||
> > + (('A' <= (c)) && ((c) <= 'Z'))); }
> > +
> > +/**
> > + Determine if a particular character is a digital character
> > +
> > + @return Returns 1 if c is an digital character, otherwise returns 0.
> > +**/
> > +int isdchar (int c)
> > +{
> > + //
> > + // [0-9] | [e +-.]
> > + //
> > + return ((('0' <= (c)) && ((c) <= '9')) ||
> > + (c == 'e') || (c == 'E') ||
> > + (c == '+') || (c == '-') ||
> > + (c == '.'));
> > +}
> > +
> > +/**
> > + Determine if a particular character is a space character
> > +
> > + @return Returns 1 if c is a space character **/ int isspace (int
> > +c) {
> > + //
> > + // <space> ::= [ ]
> > + //
> > + return ((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) ==
> > +'\n') || ((c) == '\v') || ((c) == '\f'); }
> > +
> > +/**
> > + Allocates memory blocks
> > +*/
> > +void *malloc (size_t size)
> > +{
> > + return AllocatePool ((UINTN) size); }
> > +
> > +/**
> > + De-allocates or frees a memory block */ void free (void *ptr) {
> > + //
> > + // In Standard C, free() handles a null pointer argument
> > +transparently. This
> > + // is not true of FreePool() below, so protect it.
> > + //
> > + if (ptr != NULL) {
> > + FreePool (ptr);
> > + }
> > +}
> > +
> > +/**
> > + NetBSD Compatibility Function strdup creates a duplicate copy of a string.
> > +
> > + @return Returns the pointer to duplicated string.
> > +**/
> > +char * strdup(const char *str)
> > +{
> > + size_t len;
> > + char *copy;
> > +
> > + len = strlen(str) + 1;
> > + if ((copy = malloc(len)) == NULL)
> > + return (NULL);
> > + memcpy(copy, str, len);
> > + return (copy);
> > +}
> > +
> > +/** The toupper function converts a lowercase letter to a corresponding
> > + uppercase letter.
> > +
> > + @param[in] c The character to be converted.
> > +
> > + @return If the argument is a character for which islower is true and
> > + there are one or more corresponding characters, as specified by
> > + the current locale, for which isupper is true, the toupper
> > + function returns one of the corresponding characters (always the
> > + same one for any given locale); otherwise, the argument is
> > + returned unchanged.
> > +**/
> > +int
> > +toupper(
> > + IN int c
> > + )
> > +{
> > + if ( (c >= 'a') && (c <= 'z') ) {
> > + c = c - ('a' - 'A');
> > + }
> > + return c;
> > +}
> > +
> > +/**
> > + Digit to a value.
> > +
> > + @return Returns the value of digit.
> > +**/
> > +int
> > +Digit2Val( int c)
> > +{
> > + if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))) { /* If c is one of [A-
> Za-z]... */
> > + c = toupper(c) - 7; // Adjust so 'A' is ('9' + 1)
> > + }
> > + return c - '0'; // Value returned is between 0 and 35, inclusive.
> > +}
> > +
> > +
> > +/** The strtoll function converts the initial portion of the string pointed to
> > + by nptr to long long int representation.
> > +
> > + See the description for strtol for more information.
> > +
> > + @return The strtoll function returns the converted value, if any. If no
> > + conversion could be performed, zero is returned. If the correct
> > + value is outside the range of representable values, LLONG_MIN or
> > + LLONG_MAX is returned (according to the sign of the value, if any),
> > + and the value of the macro ERANGE is stored in errno.
> > +**/
> > +long long
> > +strtoll(const char * nptr, char ** endptr, int base) {
> > + const char *pEnd;
> > + long long Result = 0;
> > + long long Previous;
> > + int temp;
> > + BOOLEAN Negative = FALSE;
> > +
> > + pEnd = nptr;
> > +
> > + if((base < 0) || (base == 1) || (base > 36)) {
> > + if(endptr != NULL) {
> > + *endptr = NULL;
> > + }
> > + return 0;
> > + }
> > + // Skip leading spaces.
> > + while(isspace(*nptr)) ++nptr;
> > +
> > + // Process Subject sequence: optional sign followed by digits.
> > + if(*nptr == '+') {
> > + Negative = FALSE;
> > + ++nptr;
> > + }
> > + else if(*nptr == '-') {
> > + Negative = TRUE;
> > + ++nptr;
> > + }
> > +
> > + if(*nptr == '0') { /* Might be Octal or Hex */
> > + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> > + if((base == 0) || (base == 16)) {
> > + nptr += 2; /* Skip the "0X" */
> > + base = 16; /* In case base was 0 */
> > + }
> > + }
> > + else { /* Looks like Octal */
> > + if((base == 0) || (base == 8)) {
> > + ++nptr; /* Skip the leading "0" */
> > + base = 8; /* In case base was 0 */
> > + }
> > + }
> > + }
> > + if(base == 0) { /* If still zero then must be decimal */
> > + base = 10;
> > + }
> > + if(*nptr == '0') {
> > + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> > + pEnd = nptr;
> > + }
> > +
> > + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> > + Previous = Result;
> > + Result = MultS64x64 (Result, base) + (long long int)temp;
> > + if( Result <= Previous) { // Detect Overflow
> > + if(Negative) {
> > + Result = LLONG_MIN;
> > + }
> > + else {
> > + Result = LLONG_MAX;
> > + }
> > + Negative = FALSE;
> > + errno = ERANGE;
> > + break;
> > + }
> > + pEnd = ++nptr;
> > + }
> > + if(Negative) {
> > + Result = -Result;
> > + }
> > +
> > + // Save pointer to final sequence
> > + if(endptr != NULL) {
> > + *endptr = (char *)pEnd;
> > + }
> > + return Result;
> > +}
> > +
> > +/** The strtol, strtoll, strtoul, and strtoull functions convert the initial
> > + portion of the string pointed to by nptr to long int, long long int,
> > + unsigned long int, and unsigned long long int representation,
> respectively.
> > + First, they decompose the input string into three parts: an initial,
> > + possibly empty, sequence of white-space characters (as specified by
> the
> > + isspace function), a subject sequence resembling an integer
> represented in
> > + some radix determined by the value of base, and a final string of one or
> > + more unrecognized characters, including the terminating null character
> of
> > + the input string. Then, they attempt to convert the subject sequence to
> an
> > + integer, and return the result.
> > +
> > + If the value of base is zero, the expected form of the subject sequence
> is
> > + that of an integer constant, optionally preceded
> > + by a plus or minus sign, but not including an integer suffix. If the value
> > + of base is between 2 and 36 (inclusive), the expected form of the
> subject
> > + sequence is a sequence of letters and digits representing an integer
> with
> > + the radix specified by base, optionally preceded by a plus or minus sign,
> > + but not including an integer suffix. The letters from a (or A) through z
> > + (or Z) are ascribed the values 10 through 35; only letters and digits
> whose
> > + ascribed values are less than that of base are permitted. If the value of
> > + base is 16, the characters 0x or 0X may optionally precede the sequence
> of
> > + letters and digits, following the sign if present.
> > +
> > + The subject sequence is defined as the longest initial subsequence of
> the
> > + input string, starting with the first non-white-space character, that is of
> > + the expected form. The subject sequence contains no characters if the
> input
> > + string is empty or consists entirely of white space, or if the first
> > + non-white-space character is other than a sign or a permissible letter or
> digit.
> > +
> > + If the subject sequence has the expected form and the value of base is
> > + zero, the sequence of characters starting with the first digit is
> > + interpreted as an integer constant. If the subject sequence has the
> > + expected form and the value of base is between 2 and 36, it is used as
> the
> > + base for conversion, ascribing to each letter its value as given above. If
> > + the subject sequence begins with a minus sign, the value resulting from
> the
> > + conversion is negated (in the return type). A pointer to the final string
> > + is stored in the object pointed to by endptr, provided that endptr is
> > + not a null pointer.
> > +
> > + In other than the "C" locale, additional locale-specific subject sequence
> > + forms may be accepted.
> > +
> > + If the subject sequence is empty or does not have the expected form,
> no
> > + conversion is performed; the value of nptr is stored in the object
> pointed
> > + to by endptr, provided that endptr is not a null pointer.
> > +
> > + @return The strtol, strtoll, strtoul, and strtoull functions return the
> > + converted value, if any. If no conversion could be performed, zero
> > + is returned. If the correct value is outside the range of
> > + representable values, LONG_MIN, LONG_MAX, LLONG_MIN,
> LLONG_MAX,
> > + ULONG_MAX, or ULLONG_MAX is returned (according to the return
> type
> > + and sign of the value, if any), and the value of the macro ERANGE
> > + is stored in errno.
> > +**/
> > +long
> > +strtol(const char * nptr, char ** endptr, int base) {
> > + const char *pEnd;
> > + long Result = 0;
> > + long Previous;
> > + int temp;
> > + BOOLEAN Negative = FALSE;
> > +
> > + pEnd = nptr;
> > +
> > + if((base < 0) || (base == 1) || (base > 36)) {
> > + if(endptr != NULL) {
> > + *endptr = NULL;
> > + }
> > + return 0;
> > + }
> > + // Skip leading spaces.
> > + while(isspace(*nptr)) ++nptr;
> > +
> > + // Process Subject sequence: optional sign followed by digits.
> > + if(*nptr == '+') {
> > + Negative = FALSE;
> > + ++nptr;
> > + }
> > + else if(*nptr == '-') {
> > + Negative = TRUE;
> > + ++nptr;
> > + }
> > +
> > + if(*nptr == '0') { /* Might be Octal or Hex */
> > + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> > + if((base == 0) || (base == 16)) {
> > + nptr += 2; /* Skip the "0X" */
> > + base = 16; /* In case base was 0 */
> > + }
> > + }
> > + else { /* Looks like Octal */
> > + if((base == 0) || (base == 8)) {
> > + ++nptr; /* Skip the leading "0" */
> > + base = 8; /* In case base was 0 */
> > + }
> > + }
> > + }
> > + if(base == 0) { /* If still zero then must be decimal */
> > + base = 10;
> > + }
> > + if(*nptr == '0') {
> > + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> > + pEnd = nptr;
> > + }
> > +
> > + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> > + Previous = Result;
> > + Result = (Result * base) + (long int)temp;
> > + if( Result <= Previous) { // Detect Overflow
> > + if(Negative) {
> > + Result = LONG_MIN;
> > + }
> > + else {
> > + Result = LONG_MAX;
> > + }
> > + Negative = FALSE;
> > + errno = ERANGE;
> > + break;
> > + }
> > + pEnd = ++nptr;
> > + }
> > + if(Negative) {
> > + Result = -Result;
> > + }
> > +
> > + // Save pointer to final sequence
> > + if(endptr != NULL) {
> > + *endptr = (char *)pEnd;
> > + }
> > + return Result;
> > +}
> > +
> > +/** The strtoull function converts the initial portion of the string pointed
> to
> > + by nptr to unsigned long long int representation.
> > +
> > + See the description for strtol for more information.
> > +
> > + @return The strtoull function returns the converted value, if any. If no
> > + conversion could be performed, zero is returned. If the correct
> > + value is outside the range of representable values, ULLONG_MAX is
> > + returned and the value of the macro ERANGE is stored in errno.
> > +**/
> > +unsigned long long
> > +strtoull(const char * nptr, char ** endptr, int base) {
> > + const char *pEnd;
> > + unsigned long long Result = 0;
> > + unsigned long long Previous;
> > + int temp;
> > +
> > + pEnd = nptr;
> > +
> > + if((base < 0) || (base == 1) || (base > 36)) {
> > + if(endptr != NULL) {
> > + *endptr = NULL;
> > + }
> > + return 0;
> > + }
> > + // Skip leading spaces.
> > + while(isspace(*nptr)) ++nptr;
> > +
> > + // Process Subject sequence: optional + sign followed by digits.
> > + if(*nptr == '+') {
> > + ++nptr;
> > + }
> > +
> > + if(*nptr == '0') { /* Might be Octal or Hex */
> > + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> > + if((base == 0) || (base == 16)) {
> > + nptr += 2; /* Skip the "0X" */
> > + base = 16; /* In case base was 0 */
> > + }
> > + }
> > + else { /* Looks like Octal */
> > + if((base == 0) || (base == 8)) {
> > + ++nptr; /* Skip the leading "0" */
> > + base = 8; /* In case base was 0 */
> > + }
> > + }
> > + }
> > + if(base == 0) { /* If still zero then must be decimal */
> > + base = 10;
> > + }
> > + if(*nptr == '0') {
> > + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> > + pEnd = nptr;
> > + }
> > +
> > + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> > + Previous = Result;
> > + Result = DivU64x32 (Result, base) + (unsigned long long)temp;
> > + if( Result < Previous) { // If we overflowed
> > + Result = ULLONG_MAX;
> > + errno = ERANGE;
> > + break;
> > + }
> > + pEnd = ++nptr;
> > + }
> > +
> > + // Save pointer to final sequence
> > + if(endptr != NULL) {
> > + *endptr = (char *)pEnd;
> > + }
> > + return Result;
> > +}
> > +
> > +/**
> > + edk2 Jansson port does not support doubles, simply return 0.
> > +
> > + These conversion functions convert the initial portion of the
> > + string pointed to by nptr to double, float, and long double
> > + representation, respectively.
> > +
> > + The strtod(), strtof(), and strtold() functions return the
> > + converted value, if any.
> > +
> > + If endptr is not NULL, a pointer to the character after the last
> > + charac- ter used in the conversion is stored in the location
> > + referenced by endptr.
> > +
> > + If no conversion is performed, zero is returned and the value of
> > + nptr is stored in the location referenced by endptr.
> > +
> > + If the correct value would cause overflow, plus or minus HUGE_VAL,
> > + HUGE_VALF, or HUGE_VALL is returned (according to the sign and type
> > + of the return value), and ERANGE is stored in errno. If the
> > + correct value would cause underflow, zero is returned and ERANGE is
> stored in errno.
> > +
> > + @return Return 0.
> > +**/
> > +double
> > +strtod (const char * __restrict nptr, char ** __restrict endptr) {
> > + if(endptr)
> > + *endptr = (char *)(nptr + strlen(nptr));
> > +
> > + return (double)0;
> > +}
> > +
> > +/**
> > + Allocate and zero-initialize array.
> > +**/
> > +void *
> > +calloc(size_t Num, size_t Size)
> > +{
> > + void *RetVal;
> > + size_t NumSize;
> > +
> > + NumSize = Num * Size;
> > + RetVal = NULL;
> > + if (NumSize != 0) {
> > + RetVal = malloc(NumSize);
> > + if( RetVal != NULL) {
> > + (VOID)ZeroMem( RetVal, NumSize);
> > + }
> > + }
> > + DEBUG((DEBUG_POOL, "0x%p = calloc(%d, %d)\n", RetVal, Num, Size));
> > +
> > + return RetVal;
> > +}
> > +
> > +//
> > +// The arrays give the cumulative number of days up to the first of
> > +the // month number used as the index (1 -> 12) for regular and leap
> years.
> > +// The value at index 13 is for the whole year.
> > +//
> > +UINTN CumulativeDays[2][14] = {
> > + {
> > + 0,
> > + 0,
> > + 31,
> > + 31 + 28,
> > + 31 + 28 + 31,
> > + 31 + 28 + 31 + 30,
> > + 31 + 28 + 31 + 30 + 31,
> > + 31 + 28 + 31 + 30 + 31 + 30,
> > + 31 + 28 + 31 + 30 + 31 + 30 + 31,
> > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
> > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
> > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
> > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
> > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
> > + },
> > + {
> > + 0,
> > + 0,
> > + 31,
> > + 31 + 29,
> > + 31 + 29 + 31,
> > + 31 + 29 + 31 + 30,
> > + 31 + 29 + 31 + 30 + 31,
> > + 31 + 29 + 31 + 30 + 31 + 30,
> > + 31 + 29 + 31 + 30 + 31 + 30 + 31,
> > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,
> > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
> > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
> > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
> > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
> > + }
> > +};
> > +
> > +#define IsLeap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
> > +#define SECSPERMIN (60)
> > +#define SECSPERHOUR (60 * 60)
> > +#define SECSPERDAY (24 * SECSPERHOUR)
> > +
> > +/**
> > + Get the system time as seconds elapsed since midnight, January 1, 1970.
> > +**/
> > +time_t time (time_t *timer)
> > +{
> > + EFI_TIME Time;
> > + time_t CalTime;
> > + UINTN Year;
> > +
> > + //
> > + // Get the current time and date information // gRT->GetTime
> > + (&Time, NULL);
> > +
> > + //
> > + // Years Handling
> > + // UTime should now be set to 00:00:00 on Jan 1 of the current year.
> > + //
> > + for (Year = 1970, CalTime = 0; Year != Time.Year; Year++) {
> > + CalTime = CalTime + (time_t)(CumulativeDays[IsLeap(Year)][13] *
> > + SECSPERDAY); }
> > +
> > + //
> > + // Add in number of seconds for current Month, Day, Hour, Minute,
> > + Seconds, and TimeZone adjustment // CalTime = CalTime +
> > + (time_t)((Time.TimeZone != EFI_UNSPECIFIED_TIMEZONE) ?
> (Time.TimeZone * 60) : 0) +
> > + (time_t)(CumulativeDays[IsLeap(Time.Year)][Time.Month] *
> SECSPERDAY) +
> > + (time_t)(((Time.Day > 0) ? Time.Day - 1 : 0) * SECSPERDAY) +
> > + (time_t)(Time.Hour * SECSPERHOUR) +
> > + (time_t)(Time.Minute * 60) +
> > + (time_t)Time.Second;
> > +
> > + if (timer != NULL) {
> > + *timer = CalTime;
> > + }
> > +
> > + return CalTime;
> > +}
> > +
> > +typedef
> > +int
> > +(*SORT_COMPARE)(
> > + IN VOID *Buffer1,
> > + IN VOID *Buffer2
> > + );
> > +
> > +/**
> > + Duplicated from EDKII BaseSortLib for qsort() wrapper
> > + @param[in, out] BufferToSort on call a Buffer of (possibly sorted)
> elements
> > + on return a buffer of sorted elements
> > + @param[in] Count the number of elements in the buffer to sort
> > + @param[in] ElementSize Size of an element in bytes
> > + @param[in] CompareFunction The function to call to perform the
> comparison
> > + of any 2 elements
> > + @param[in] Buffer Buffer of size ElementSize for use in swapping
> > +**/
> > +STATIC
> > +VOID
> > +QuickSortWorker (
> > + IN OUT VOID *BufferToSort,
> > + IN CONST UINTN Count,
> > + IN CONST UINTN ElementSize,
> > + IN SORT_COMPARE CompareFunction,
> > + IN VOID *Buffer
> > + )
> > +{
> > + VOID *Pivot;
> > + UINTN LoopCount;
> > + UINTN NextSwapLocation;
> > +
> > + ASSERT(BufferToSort != NULL);
> > + ASSERT(CompareFunction != NULL);
> > + ASSERT(Buffer != NULL);
> > +
> > + if (Count < 2 || ElementSize < 1) {
> > + return;
> > + }
> > +
> > + NextSwapLocation = 0;
> > +
> > + //
> > + // Pick a pivot (we choose last element) // Pivot = ((UINT8
> > + *)BufferToSort + ((Count - 1) * ElementSize));
> > +
> > + //
> > + // Now get the pivot such that all on "left" are below it // and
> > + everything "right" are above it // for (LoopCount = 0; LoopCount <
> > + Count - 1; LoopCount++) {
> > + //
> > + // If the element is less than the pivot
> > + //
> > + if (CompareFunction ((VOID *)((UINT8 *)BufferToSort + ((LoopCount) *
> ElementSize)), Pivot) <= 0) {
> > + //
> > + // Swap
> > + //
> > + CopyMem (Buffer, (UINT8 *)BufferToSort + (NextSwapLocation *
> ElementSize), ElementSize);
> > + CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation *
> > + ElementSize), (UINT8 *)BufferToSort + ((LoopCount) *
> > ElementSize), ElementSize);
> > + CopyMem ((UINT8 *)BufferToSort + ((LoopCount) * ElementSize),
> > + Buffer, ElementSize);
> > +
> > + //
> > + // Increment NextSwapLocation
> > + //
> > + NextSwapLocation++;
> > + }
> > + }
> > + //
> > + // Swap pivot to it's final position (NextSwapLocaiton) //
> > + CopyMem (Buffer, Pivot, ElementSize); CopyMem (Pivot, (UINT8
> > + *)BufferToSort + (NextSwapLocation * ElementSize), ElementSize);
> > + CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation * ElementSize),
> > + Buffer, ElementSize);
> > +
> > + //
> > + // Now recurse on 2 paritial lists. Neither of these will have the 'pivot'
> element.
> > + // IE list is sorted left half, pivot element, sorted right half...
> > + //
> > + QuickSortWorker (
> > + BufferToSort,
> > + NextSwapLocation,
> > + ElementSize,
> > + CompareFunction,
> > + Buffer
> > + );
> > +
> > + QuickSortWorker (
> > + (UINT8 *)BufferToSort + (NextSwapLocation + 1) * ElementSize,
> > + Count - NextSwapLocation - 1,
> > + ElementSize,
> > + CompareFunction,
> > + Buffer
> > + );
> > +
> > + return;
> > +}
> > +
> > +/**
> > + Performs a quick sort
> > +**/
> > +void qsort (void *base, size_t num, size_t width, int
> > +(*compare)(const void *, const void *)) {
> > + VOID *Buffer;
> > +
> > + ASSERT (base != NULL);
> > + ASSERT (compare != NULL);
> > +
> > + //
> > + // Use CRT-style malloc to cover BS and RT memory allocation.
> > + //
> > + Buffer = malloc (width);
> > + ASSERT (Buffer != NULL);
> > +
> > + //
> > + // Re-use PerformQuickSort() function Implementation in EDKII
> BaseSortLib.
> > + //
> > + QuickSortWorker (base, (UINTN)num, (UINTN)width,
> > + (SORT_COMPARE)compare, Buffer);
> > +
> > + free (Buffer);
> > + return;
> > +}
> > +
> > +/**
> > + Get character from stream, we don't support file operastion on edk2
> JSON library.
> > +
> > + @return Returns the character currently pointed by the internal
> > + file position indicator of the specified stream
> > +
> > +**/
> > +int fgetc(FILE * _File){
> > + return 0;
> > +}
> > diff --git a/RedfishPkg/Library/CrtLib/CrtLib.inf
> > b/RedfishPkg/Library/CrtLib/CrtLib.inf
> > new file mode 100644
> > index 0000000000..b514817cf4
> > --- /dev/null
> > +++ b/RedfishPkg/Library/CrtLib/CrtLib.inf
> > @@ -0,0 +1,37 @@
> > +## @file
> > +# EDK2 C Runtime Library for opensource project.
> > +#
> > +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> #
> > +(C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR> #
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > + INF_VERSION = 0x0001001b
> > + BASE_NAME = CrtLib
> > + FILE_GUID = 8263B8AC-D021-425D-B337-3EC96F5DC19B
> > + MODULE_TYPE = DXE_DRIVER
> > + VERSION_STRING = 1.0
> > + LIBRARY_CLASS = CrtLib|DXE_CORE DXE_DRIVER
> DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION
> > UEFI_DRIVER
> > +
> > +#
> > +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64
> > +#
> > +
> > +[Sources]
> > + CrtLib.c
> > +
> > +[LibraryClasses]
> > + BaseLib
> > + DebugLib
> > + MemoryAllocationLib
> > + UefiRuntimeServicesTableLib
> > +
> > +[Packages]
> > + MdePkg/MdePkg.dec
> > + MdeModulePkg/MdeModulePkg.dec
> > + RedfishPkg/RedfishPkg.dec
> > +
> > +
> > diff --git a/RedfishPkg/RedfishLibs.dsc.inc
> > b/RedfishPkg/RedfishLibs.dsc.inc index d4c08e18ac..2a951bd8fa 100644
> > --- a/RedfishPkg/RedfishLibs.dsc.inc
> > +++ b/RedfishPkg/RedfishLibs.dsc.inc
> > @@ -12,5 +12,6 @@
> > ##
> > !if $(REDFISH_ENABLE) == TRUE
> > Ucs2Utf8Lib|RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > + CrtLib|RedfishPkg/Library/CrtLib/CrtLib.inf
> > !endif
> >
> > diff --git a/RedfishPkg/RedfishPkg.ci.yaml
> > b/RedfishPkg/RedfishPkg.ci.yaml index 20c297ad22..9895fdac99 100644
> > --- a/RedfishPkg/RedfishPkg.ci.yaml
> > +++ b/RedfishPkg/RedfishPkg.ci.yaml
> > @@ -17,6 +17,25 @@
> > ],
> > ## Both file path and directory path are accepted.
> > "IgnoreFiles": [
> > + ## Below are files incorporated with open source which are
> > + ## not edk2 coding standard compliant.
> > + ##
> > + ## EDK2 CRT library which is not edk2 coding
> > + ## standard compliant.
> > + ## C runtime library for EDKII JsonLib.
> > + "Include/Crt/sys",
> > + "Include/Crt/assert.h",
> > + "Include/Crt/errno.h",
> > + "Include/Crt/limits.h",
> > + "Include/Crt/math.h",
> > + "Include/Crt/stdarg.h",
> > + "Include/Crt/stddef.h",
> > + "Include/Crt/stdio.h",
> > + "Include/Crt/stdlib.h",
> > + "Include/Crt/string.h",
> > + "Include/Crt/time.h",
> > + "Include/Library/CrtLib.h",
> > + "Library/CrtLib/CrtLib.c"
> > ]
> > },
> > "CompilerPlugin": {
> > diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec
> > index aecc1f4a3a..2142b43640 100644
> > --- a/RedfishPkg/RedfishPkg.dec
> > +++ b/RedfishPkg/RedfishPkg.dec
> > @@ -15,16 +15,24 @@
> >
> > [Includes]
> > Include
> > + Include/Crt # Header files for C RTL.
> >
> > [LibraryClasses]
> > ## @libraryclass Platform Redfish Host Interface Library
> > # Platform implementation-specific Redfish Host Interface.
> >
> > RedfishPlatformHostInterfaceLib|Include/Library/RedfishHostInterfaceLi
> > b.h
> > +
> > ## @libraryclass This library provides UCS2 to UTF8 manipulation
> > # functions.
> > #
> > Ucs2Utf8Lib|Include/Library/BaseUcs2Utf8Lib.h
> >
> > + ## @libraryclass Provides the C runtime library functions
> > + # CRT library is currently used by edk2 JsonLib (open source
> > + # jansson project) and edk2 RedfishLib (libredfish open source
> > + # project).
> > + CrtLib|Include/Library/CrtLib.h
> > +
> > [Protocols]
> > ## Include/Protocol/RedfishDiscover.h
> > gEfiRedfishDiscoverProtocolGuid = { 0x5db12509, 0x4550, 0x4347, { 0x96,
> 0xb3, 0x73, 0xc0, 0xff, 0x6e, 0x86, 0x9f
> > }}
> > diff --git a/RedfishPkg/RedfishPkg.dsc b/RedfishPkg/RedfishPkg.dsc
> > index 3639b620e6..aa1ccd5a95 100644
> > --- a/RedfishPkg/RedfishPkg.dsc
> > +++ b/RedfishPkg/RedfishPkg.dsc
> > @@ -48,5 +48,6 @@
> > [Components]
> >
> RedfishPkg/Library/PlatformHostInterfaceLibNull/PlatformHostInterfaceLibN
> ull.inf
> > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > + RedfishPkg/Library/CrtLib/CrtLib.inf
> >
> > !include RedfishPkg/Redfish.dsc.inc
> > --
> > 2.17.1
> >
> >
> >
> >
> >
^ permalink raw reply [flat|nested] 15+ messages in thread
[parent not found: <CS1PR8401MB1144B554CE75DDDA5E4C1ECEFFC50@CS1PR8401MB1144.NAMPRD84.PROD.OUTLOOK.COM>]
* Re: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime library
[not found] ` <CS1PR8401MB1144B554CE75DDDA5E4C1ECEFFC50@CS1PR8401MB1144.NAMPRD84.PROD.OUTLOOK.COM>
@ 2020-12-16 15:36 ` Abner Chang
0 siblings, 0 replies; 15+ messages in thread
From: Abner Chang @ 2020-12-16 15:36 UTC (permalink / raw)
To: Kinney, Michael D, devel@edk2.groups.io
Cc: Leif Lindholm, Wang, Nickle (HPS SW), O'Hanley, Peter (EXL)
Mike, you can take a look on v7 for the changes.
> -----Original Message-----
> From: Chang, Abner (HPS SW/FW Technologist)
> Sent: Wednesday, December 16, 2020 12:38 PM
> To: Kinney, Michael D <michael.d.kinney@intel.com>; devel@edk2.groups.io
> Cc: Leif Lindholm <leif@nuviainc.com>; Wang, Nickle (HPS SW)
> <nickle.wang@hpe.com>; O'Hanley, Peter (EXL) <peter.ohanley@hpe.com>
> Subject: RE: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime library
>
> > -----Original Message-----
> > From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> > Sent: Tuesday, December 15, 2020 8:20 AM
> > To: devel@edk2.groups.io; Chang, Abner (HPS SW/FW Technologist)
> > <abner.chang@hpe.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> > Cc: Leif Lindholm <leif@nuviainc.com>; Wang, Nickle (HPS SW)
> > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> <peter.ohanley@hpe.com>
> > Subject: RE: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime
> > library
> >
> > Hi Abner,
> >
> > I see what appears to be some duplication of the qsort source code.
> >
> > Can you use the PerformQuickSort() API from the QsortLib in the
> > MdeModulePkg?
> Done thanks!
> >
> > Thanks,
> >
> > Mike
> >
> > > -----Original Message-----
> > > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
> Abner
> > > Chang
> > > Sent: Sunday, December 13, 2020 7:53 PM
> > > To: devel@edk2.groups.io
> > > Cc: Leif Lindholm <leif@nuviainc.com>; Nickle Wang
> > > <nickle.wang@hpe.com>; Peter O'Hanley <peter.ohanley@hpe.com>
> > > Subject: [edk2-devel] [PATCH v6 3/6] RedfishPkg/CrtLib: C runtime
> > > library
> > >
> > > CRT library is currently used by edk2 JsonLib (open source jansson
> > > project) and edk2 RedfishLib (libredfish open source project).
> > > CrtLib library provides the necessary C runtime equivalent edk2
> > > functions for open source projects.
> > >
> > > Signed-off-by: Abner Chang <abner.chang@hpe.com>
> > >
> > > Cc: Leif Lindholm <leif@nuviainc.com>
> > > Cc: Nickle Wang <nickle.wang@hpe.com>
> > > Cc: Peter O'Hanley <peter.ohanley@hpe.com>
> > > ---
> > > RedfishPkg/Include/Crt/assert.h | 16 +
> > > RedfishPkg/Include/Crt/errno.h | 16 +
> > > RedfishPkg/Include/Crt/limits.h | 16 +
> > > RedfishPkg/Include/Crt/math.h | 16 +
> > > RedfishPkg/Include/Crt/stdarg.h | 15 +
> > > RedfishPkg/Include/Crt/stddef.h | 16 +
> > > RedfishPkg/Include/Crt/stdio.h | 15 +
> > > RedfishPkg/Include/Crt/stdlib.h | 16 +
> > > RedfishPkg/Include/Crt/string.h | 16 +
> > > RedfishPkg/Include/Crt/sys/time.h | 15 +
> > > RedfishPkg/Include/Crt/sys/types.h | 15 +
> > > RedfishPkg/Include/Crt/time.h | 15 +
> > > RedfishPkg/Include/Library/CrtLib.h | 195 ++++++++
> > > RedfishPkg/Library/CrtLib/CrtLib.c | 705
> > +++++++++++++++++++++++++++
> > > RedfishPkg/Library/CrtLib/CrtLib.inf | 37 ++
> > > RedfishPkg/RedfishLibs.dsc.inc | 1 +
> > > RedfishPkg/RedfishPkg.ci.yaml | 19 +
> > > RedfishPkg/RedfishPkg.dec | 8 +
> > > RedfishPkg/RedfishPkg.dsc | 1 +
> > > 19 files changed, 1153 insertions(+) create mode 100644
> > > RedfishPkg/Include/Crt/assert.h create mode
> > > 100644 RedfishPkg/Include/Crt/errno.h create mode 100644
> > > RedfishPkg/Include/Crt/limits.h create mode 100644
> > > RedfishPkg/Include/Crt/math.h create mode 100644
> > > RedfishPkg/Include/Crt/stdarg.h create mode 100644
> > > RedfishPkg/Include/Crt/stddef.h create mode 100644
> > > RedfishPkg/Include/Crt/stdio.h create mode 100644
> > > RedfishPkg/Include/Crt/stdlib.h create mode 100644
> > > RedfishPkg/Include/Crt/string.h create mode 100644
> > > RedfishPkg/Include/Crt/sys/time.h create mode 100644
> > > RedfishPkg/Include/Crt/sys/types.h
> > > create mode 100644 RedfishPkg/Include/Crt/time.h create mode
> > > 100644 RedfishPkg/Include/Library/CrtLib.h
> > > create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.c
> > > create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.inf
> > >
> > > diff --git a/RedfishPkg/Include/Crt/assert.h
> > > b/RedfishPkg/Include/Crt/assert.h new file mode 100644 index
> > > 0000000000..f9ab7ef9ca
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/assert.h
> > > @@ -0,0 +1,16 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +#ifndef CRT_ASSERT_H_
> > > +#define CRT_ASSERT_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/errno.h
> > > b/RedfishPkg/Include/Crt/errno.h new file mode 100644 index
> > > 0000000000..d30aee14de
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/errno.h
> > > @@ -0,0 +1,16 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +#ifndef CRT_ERRNO_H_
> > > +#define CRT_ERRNO_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/limits.h
> > > b/RedfishPkg/Include/Crt/limits.h new file mode 100644 index
> > > 0000000000..f3bdd33f2a
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/limits.h
> > > @@ -0,0 +1,16 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +#ifndef CRT_LIMITS_H_
> > > +#define CRT_LIMITS_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/math.h
> > > b/RedfishPkg/Include/Crt/math.h new file mode 100644 index
> > > 0000000000..984c0ccc21
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/math.h
> > > @@ -0,0 +1,16 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +#ifndef CRT_MATH_H_
> > > +#define CRT_MATH_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/stdarg.h
> > > b/RedfishPkg/Include/Crt/stdarg.h new file mode 100644 index
> > > 0000000000..d5a314ad3b
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/stdarg.h
> > > @@ -0,0 +1,15 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +#ifndef CRT_STDARG_H_
> > > +#define CRT_STDARG_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/stddef.h
> > > b/RedfishPkg/Include/Crt/stddef.h new file mode 100644 index
> > > 0000000000..15a37bf50e
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/stddef.h
> > > @@ -0,0 +1,16 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +#ifndef CRT_STDDEF_H_
> > > +#define CRT_STDDEF_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/stdio.h
> > > b/RedfishPkg/Include/Crt/stdio.h new file mode 100644 index
> > > 0000000000..25e610be10
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/stdio.h
> > > @@ -0,0 +1,15 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +#ifndef CRT_STDIO_H_
> > > +#define CRT_STDIO_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/stdlib.h
> > > b/RedfishPkg/Include/Crt/stdlib.h new file mode 100644 index
> > > 0000000000..5b3dd273c8
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/stdlib.h
> > > @@ -0,0 +1,16 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +#ifndef CRT_STDLIB_H_
> > > +#define CRT_STDLIB_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/string.h
> > > b/RedfishPkg/Include/Crt/string.h new file mode 100644 index
> > > 0000000000..f60b87ccd2
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/string.h
> > > @@ -0,0 +1,16 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +#ifndef CRT_STRING_H_
> > > +#define CRT_STRING_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/sys/time.h
> > > b/RedfishPkg/Include/Crt/sys/time.h
> > > new file mode 100644
> > > index 0000000000..4ced176cda
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/sys/time.h
> > > @@ -0,0 +1,15 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +#ifndef CRT_SYS_TIME_H_
> > > +#define CRT_SYS_TIME_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/sys/types.h
> > > b/RedfishPkg/Include/Crt/sys/types.h
> > > new file mode 100644
> > > index 0000000000..c4f807214c
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/sys/types.h
> > > @@ -0,0 +1,15 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +#ifndef CRT_SYS_TYPES_H_
> > > +#define CRT_SYS_TYPES_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Crt/time.h
> > > b/RedfishPkg/Include/Crt/time.h new file mode 100644 index
> > > 0000000000..ca04ac8730
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Crt/time.h
> > > @@ -0,0 +1,15 @@
> > > +/** @file
> > > + Include file to support building the third-party jansson library.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +#ifndef CRT_TIME_H_
> > > +#define CRT_TIME_H_
> > > +
> > > +#include <Library/CrtLib.h>
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Include/Library/CrtLib.h
> > > b/RedfishPkg/Include/Library/CrtLib.h
> > > new file mode 100644
> > > index 0000000000..8c7484e75b
> > > --- /dev/null
> > > +++ b/RedfishPkg/Include/Library/CrtLib.h
> > > @@ -0,0 +1,195 @@
> > > +/** @file
> > > + CRT wrapper head functions for jansson system call.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +#ifndef CRT_LIB_H_
> > > +#define CRT_LIB_H_
> > > +
> > > +#include <Library/BaseLib.h>
> > > +#include <Library/BaseMemoryLib.h>
> > > +#include <Library/DebugLib.h>
> > > +#include <Library/PrintLib.h>
> > > +
> > > +#define MAX_STRING_SIZE 0x10000000
> > > +
> > > +// Minimum value for an object of type long long int.
> > > +#define LLONG_MIN MIN_INT64
> > > +
> > > +// Maximum value for an object of type long long int.
> > > +#define LLONG_MAX MAX_INT64
> > > +
> > > +// We dont support double on edk2
> > > +#define HUGE_VAL 0
> > > +
> > > +#if defined(MDE_CPU_X64) || defined(MDE_CPU_AARCH64) ||
> > > +defined(MDE_CPU_IA64) || defined(MDE_CPU_RISCV64) // // With
> GCC
> > we
> > > +would normally use SIXTY_FOUR_BIT_LONG, but MSVC needs //
> > > +SIXTY_FOUR_BIT, because 'long' is 32-bit and only 'long long' is //
> > > +64-bit. Since using 'long long' works fine on GCC too, just do that.
> > > +//
> > > +#define SIXTY_FOUR_BIT
> > > +#elif defined(MDE_CPU_IA32) || defined(MDE_CPU_ARM) ||
> > > +defined(MDE_CPU_EBC) #define THIRTY_TWO_BIT #endif
> > > +
> > > +//
> > > +// Map all va_xxxx elements to VA_xxx defined in
> > > +MdePkg/Include/Base.h // #if !defined(__CC_ARM) // if va_list is
> > > +not already defined
> > > +#define va_list VA_LIST
> > > +#define va_arg VA_ARG
> > > +#define va_start VA_START
> > > +#define va_end VA_END
> > > +#else // __CC_ARM
> > > +#define va_start(Marker, Parameter) __va_start(Marker, Parameter)
> > > +#define va_arg(Marker, TYPE) __va_arg(Marker, TYPE)
> > > +#define va_end(Marker) ((void)0)
> > > +#endif
> > > +
> > > +//
> > > +// Definitions for global constants used by CRT library routines //
> > > +#define INT_MAX MAX_INT32 /* Maximum (signed) int value */
> > > +#define LONG_MAX 0X7FFFFFFFL /* max value for a long */
> > > +#define LONG_MIN (-LONG_MAX-1) /* min value for a long */
> > > +#define ULONG_MAX 0xFFFFFFFF /* Maximum unsigned long
> value
> > */
> > > +#define CHAR_BIT 8 /* Number of bits in a char */
> > > +
> > > +// Maximum value for an object of type unsigned long long int.
> > > +#define ULLONG_MAX 0xFFFFFFFFFFFFFFFFULL // 2^64 - 1 // Maximum
> > > +value for an object of type unsigned char.
> > > +#define UCHAR_MAX 255 // 2^8 - 1
> > > +
> > > +//
> > > +// Basic types mapping
> > > +//
> > > +typedef UINTN size_t;
> > > +typedef INTN ssize_t;
> > > +typedef INT32 time_t;
> > > +typedef UINT8 __uint8_t;
> > > +typedef UINT8 sa_family_t;
> > > +typedef UINT32 uid_t;
> > > +typedef UINT32 gid_t;
> > > +typedef INT32 int32_t;
> > > +typedef UINT32 uint32_t;
> > > +typedef UINT16 uint16_t;
> > > +typedef UINT8 uint8_t;
> > > +typedef enum {false, true} bool;
> > > +
> > > +//
> > > +// File operations are not required for EFI building, // so FILE is
> > > +mapped to VOID * to pass build // typedef VOID *FILE;
> > > +
> > > +//
> > > +// Global variables
> > > +//
> > > +extern int errno;
> > > +extern FILE *stderr;
> > > +
> > > +//
> > > +// Function prototypes of CRT Library routines //
> > > +void *malloc (size_t);
> > > +void *realloc (void *, size_t);
> > > +void *calloc (size_t Num, size_t Size);
> > > +void free (void *);
> > > +void *memset (void *, int, size_t);
> > > +int memcmp (const void *, const void *, size_t);
> > > +int isdigit (int);
> > > +int isspace (int);
> > > +int tolower (int);
> > > +int isupper (int);
> > > +int isxdigit (int);
> > > +int isalnum (int);
> > > +void *memcpy (void *, const void *, size_t);
> > > +void *memset (void *, int, size_t);
> > > +void *memchr (const void *, int, size_t);
> > > +int memcmp (const void *, const void *, size_t);
> > > +void *memmove (void *, const void *, size_t);
> > > +int strcmp (const char *, const char *);
> > > +int strncmp (const char *, const char *, size_t);
> > > +char *strcpy (char *, const char *);
> > > +size_t strlen (const char *);
> > > +char *strcat (char *, const char *);
> > > +char *strchr (const char *, int);
> > > +int strcasecmp (const char *, const char *);
> > > +int strncasecmp (const char *, const char *, size_t);
> > > +char *strncpy (char *, size_t, const char *, size_t);
> > > +int strncmp (const char *, const char *, size_t);
> > > +char *strrchr (const char *, int);
> > > +unsigned long strtoul (const char *, char **, int);
> > > +char * strstr (const char *s1 , const char *s2);
> > > +long strtol (const char *, char **, int);
> > > +char *strerror (int);
> > > +size_t strspn (const char *, const char *);
> > > +char * strdup (const char *str);
> > > +char * strpbrk (const char *s1, const char *s2);
> > > +unsigned long long strtoull(const char * nptr, char ** endptr, int base);
> > > +long long strtoll (const char * nptr, char ** endptr, int base);
> > > +long strtol (const char * nptr, char ** endptr, int base);
> > > +double strtod (const char * __restrict nptr, char ** __restrict
> > endptr);
> > > +size_t strcspn (const char *, const char *);
> > > +int printf (const char *, ...);
> > > +int sscanf (const char *, const char *, ...);
> > > +FILE *fopen (const char *, const char *);
> > > +size_t fread (void *, size_t, size_t, FILE *);
> > > +size_t fwrite (const void *, size_t, size_t, FILE *);
> > > +int fclose (FILE *);
> > > +int fprintf (FILE *, const char *, ...);
> > > +int fgetc (FILE * _File);
> > > +uid_t getuid (void);
> > > +uid_t geteuid (void);
> > > +gid_t getgid (void);
> > > +gid_t getegid (void);
> > > +void qsort (void *, size_t, size_t, int (*)(const void *, const void
> > *));
> > > +char *getenv (const char *);
> > > +#if defined(__GNUC__) && (__GNUC__ >= 2)
> > > +void abort (void) __attribute__((__noreturn__));
> > > +#else
> > > +void abort (void);
> > > +#endif
> > > +int toupper (int);
> > > +int Digit2Val (int);
> > > +time_t time (time_t *);
> > > +
> > > +//
> > > +// Macros that directly map functions to BaseLib, BaseMemoryLib,
> > > +and DebugLib functions //
> > > +#define strcmp AsciiStrCmp
> > > +#define memcpy(dest,source,count)
> > CopyMem(dest,source,(UINTN)(count))
> > > +#define memset(dest,ch,count)
> > SetMem(dest,(UINTN)(count),(UINT8)(ch))
> > > +#define memchr(buf,ch,count)
> > ScanMem8(buf,(UINTN)(count),(UINT8)ch)
> > > +#define memcmp(buf1,buf2,count)
> > (int)(CompareMem(buf1,buf2,(UINTN)(count)))
> > > +#define memmove(dest,source,count)
> > CopyMem(dest,source,(UINTN)(count))
> > > +#define strlen(str)
> > (size_t)(AsciiStrnLenS(str,MAX_STRING_SIZE))
> > > +#define strcpy(strDest,strSource)
> > AsciiStrCpyS(strDest,(strlen(strSource)+1),strSource)
> > > +#define strncpy(strDest,strSource,count)
> > > +AsciiStrnCpyS(strDest,(UINTN)count,strSource,(UINTN)count)
> > > +#define strncpys(strDest, DestLen, strSource,count)
> > AsciiStrnCpyS(strDest,DestLen,strSource,(UINTN)count)
> > > +#define strcat(strDest,strSource)
> > AsciiStrCatS(strDest,(strlen(strSource)+strlen(strDest)+1),strSource)
> > > +#define strchr(str,ch) ScanMem8((VOID
> > *)(str),AsciiStrSize(str),(UINT8)ch)
> > > +#define strncmp(string1,string2,count)
> > (int)(AsciiStrnCmp(string1,string2,(UINTN)(count)))
> > > +#define strcasecmp(str1,str2) (int)AsciiStriCmp(str1,str2)
> > > +#define strstr(s1,s2) AsciiStrStr(s1,s2)
> > > +#define sprintf(buf,...)
> > AsciiSPrint(buf,MAX_STRING_SIZE,__VA_ARGS__)
> > > +#define snprintf(buf,len,...) AsciiSPrint(buf,len,__VA_ARGS__)
> > > +#define vsnprintf(buf,len,format,marker)
> > AsciiVSPrint((buf),(len),(format),(marker))
> > > +#define assert(expression) ASSERT(expression)
> > > +#define atoi(nptr) AsciiStrDecimalToUintn(nptr)
> > > +#define fabs(x) (((x) < 0.0)? (-x): (x))
> > > +#define offsetof(type,member) OFFSET_OF(type,member)
> > > +
> > > +#define EOF (-1)
> > > +
> > > +extern int errno;
> > > +
> > > +#define ERANGE 34 /* 34 Result too large */
> > > +
> > > +#endif
> > > diff --git a/RedfishPkg/Library/CrtLib/CrtLib.c
> > > b/RedfishPkg/Library/CrtLib/CrtLib.c
> > > new file mode 100644
> > > index 0000000000..1ff4023dbe
> > > --- /dev/null
> > > +++ b/RedfishPkg/Library/CrtLib/CrtLib.c
> > > @@ -0,0 +1,705 @@
> > > +/** @file
> > > + CRT wrapper functions for system call.
> > > +
> > > + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> > > +
> > > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +#include <Uefi.h>
> > > +#include <Library/CrtLib.h>
> > > +#include <Library/MemoryAllocationLib.h> #include
> > > +<Library/UefiRuntimeServicesTableLib.h>
> > > +
> > > +int errno = 0;
> > > +
> > > +/**
> > > + Determine if a particular character is an alphanumeric character
> > > + @return Returns 1 if c is an alphanumeric character, otherwise returns
> 0.
> > > +**/
> > > +int isalnum (int c)
> > > +{
> > > + //
> > > + // <alnum> ::= [0-9] | [a-z] | [A-Z]
> > > + //
> > > + return ((('0' <= (c)) && ((c) <= '9')) ||
> > > + (('a' <= (c)) && ((c) <= 'z')) ||
> > > + (('A' <= (c)) && ((c) <= 'Z'))); }
> > > +
> > > +/**
> > > + Determine if a particular character is a digital character
> > > +
> > > + @return Returns 1 if c is an digital character, otherwise returns 0.
> > > +**/
> > > +int isdchar (int c)
> > > +{
> > > + //
> > > + // [0-9] | [e +-.]
> > > + //
> > > + return ((('0' <= (c)) && ((c) <= '9')) ||
> > > + (c == 'e') || (c == 'E') ||
> > > + (c == '+') || (c == '-') ||
> > > + (c == '.'));
> > > +}
> > > +
> > > +/**
> > > + Determine if a particular character is a space character
> > > +
> > > + @return Returns 1 if c is a space character **/ int isspace (int
> > > +c) {
> > > + //
> > > + // <space> ::= [ ]
> > > + //
> > > + return ((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) ==
> > > +'\n') || ((c) == '\v') || ((c) == '\f'); }
> > > +
> > > +/**
> > > + Allocates memory blocks
> > > +*/
> > > +void *malloc (size_t size)
> > > +{
> > > + return AllocatePool ((UINTN) size); }
> > > +
> > > +/**
> > > + De-allocates or frees a memory block */ void free (void *ptr) {
> > > + //
> > > + // In Standard C, free() handles a null pointer argument
> > > +transparently. This
> > > + // is not true of FreePool() below, so protect it.
> > > + //
> > > + if (ptr != NULL) {
> > > + FreePool (ptr);
> > > + }
> > > +}
> > > +
> > > +/**
> > > + NetBSD Compatibility Function strdup creates a duplicate copy of a
> string.
> > > +
> > > + @return Returns the pointer to duplicated string.
> > > +**/
> > > +char * strdup(const char *str)
> > > +{
> > > + size_t len;
> > > + char *copy;
> > > +
> > > + len = strlen(str) + 1;
> > > + if ((copy = malloc(len)) == NULL)
> > > + return (NULL);
> > > + memcpy(copy, str, len);
> > > + return (copy);
> > > +}
> > > +
> > > +/** The toupper function converts a lowercase letter to a corresponding
> > > + uppercase letter.
> > > +
> > > + @param[in] c The character to be converted.
> > > +
> > > + @return If the argument is a character for which islower is true and
> > > + there are one or more corresponding characters, as specified by
> > > + the current locale, for which isupper is true, the toupper
> > > + function returns one of the corresponding characters (always the
> > > + same one for any given locale); otherwise, the argument is
> > > + returned unchanged.
> > > +**/
> > > +int
> > > +toupper(
> > > + IN int c
> > > + )
> > > +{
> > > + if ( (c >= 'a') && (c <= 'z') ) {
> > > + c = c - ('a' - 'A');
> > > + }
> > > + return c;
> > > +}
> > > +
> > > +/**
> > > + Digit to a value.
> > > +
> > > + @return Returns the value of digit.
> > > +**/
> > > +int
> > > +Digit2Val( int c)
> > > +{
> > > + if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))) {
> > > +/* If c is one of [A-
> > Za-z]... */
> > > + c = toupper(c) - 7; // Adjust so 'A' is ('9' + 1)
> > > + }
> > > + return c - '0'; // Value returned is between 0 and 35, inclusive.
> > > +}
> > > +
> > > +
> > > +/** The strtoll function converts the initial portion of the string pointed
> to
> > > + by nptr to long long int representation.
> > > +
> > > + See the description for strtol for more information.
> > > +
> > > + @return The strtoll function returns the converted value, if any. If no
> > > + conversion could be performed, zero is returned. If the correct
> > > + value is outside the range of representable values, LLONG_MIN or
> > > + LLONG_MAX is returned (according to the sign of the value, if any),
> > > + and the value of the macro ERANGE is stored in errno.
> > > +**/
> > > +long long
> > > +strtoll(const char * nptr, char ** endptr, int base) {
> > > + const char *pEnd;
> > > + long long Result = 0;
> > > + long long Previous;
> > > + int temp;
> > > + BOOLEAN Negative = FALSE;
> > > +
> > > + pEnd = nptr;
> > > +
> > > + if((base < 0) || (base == 1) || (base > 36)) {
> > > + if(endptr != NULL) {
> > > + *endptr = NULL;
> > > + }
> > > + return 0;
> > > + }
> > > + // Skip leading spaces.
> > > + while(isspace(*nptr)) ++nptr;
> > > +
> > > + // Process Subject sequence: optional sign followed by digits.
> > > + if(*nptr == '+') {
> > > + Negative = FALSE;
> > > + ++nptr;
> > > + }
> > > + else if(*nptr == '-') {
> > > + Negative = TRUE;
> > > + ++nptr;
> > > + }
> > > +
> > > + if(*nptr == '0') { /* Might be Octal or Hex */
> > > + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> > > + if((base == 0) || (base == 16)) {
> > > + nptr += 2; /* Skip the "0X" */
> > > + base = 16; /* In case base was 0 */
> > > + }
> > > + }
> > > + else { /* Looks like Octal */
> > > + if((base == 0) || (base == 8)) {
> > > + ++nptr; /* Skip the leading "0" */
> > > + base = 8; /* In case base was 0 */
> > > + }
> > > + }
> > > + }
> > > + if(base == 0) { /* If still zero then must be decimal */
> > > + base = 10;
> > > + }
> > > + if(*nptr == '0') {
> > > + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> > > + pEnd = nptr;
> > > + }
> > > +
> > > + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> > > + Previous = Result;
> > > + Result = MultS64x64 (Result, base) + (long long int)temp;
> > > + if( Result <= Previous) { // Detect Overflow
> > > + if(Negative) {
> > > + Result = LLONG_MIN;
> > > + }
> > > + else {
> > > + Result = LLONG_MAX;
> > > + }
> > > + Negative = FALSE;
> > > + errno = ERANGE;
> > > + break;
> > > + }
> > > + pEnd = ++nptr;
> > > + }
> > > + if(Negative) {
> > > + Result = -Result;
> > > + }
> > > +
> > > + // Save pointer to final sequence
> > > + if(endptr != NULL) {
> > > + *endptr = (char *)pEnd;
> > > + }
> > > + return Result;
> > > +}
> > > +
> > > +/** The strtol, strtoll, strtoul, and strtoull functions convert the initial
> > > + portion of the string pointed to by nptr to long int, long long int,
> > > + unsigned long int, and unsigned long long int representation,
> > respectively.
> > > + First, they decompose the input string into three parts: an initial,
> > > + possibly empty, sequence of white-space characters (as
> > > + specified by
> > the
> > > + isspace function), a subject sequence resembling an integer
> > represented in
> > > + some radix determined by the value of base, and a final string of one
> or
> > > + more unrecognized characters, including the terminating null
> > > + character
> > of
> > > + the input string. Then, they attempt to convert the subject
> > > + sequence to
> > an
> > > + integer, and return the result.
> > > +
> > > + If the value of base is zero, the expected form of the subject
> > > + sequence
> > is
> > > + that of an integer constant, optionally preceded
> > > + by a plus or minus sign, but not including an integer suffix. If the value
> > > + of base is between 2 and 36 (inclusive), the expected form of
> > > + the
> > subject
> > > + sequence is a sequence of letters and digits representing an
> > > + integer
> > with
> > > + the radix specified by base, optionally preceded by a plus or minus
> sign,
> > > + but not including an integer suffix. The letters from a (or A) through z
> > > + (or Z) are ascribed the values 10 through 35; only letters and
> > > + digits
> > whose
> > > + ascribed values are less than that of base are permitted. If the value
> of
> > > + base is 16, the characters 0x or 0X may optionally precede the
> > > + sequence
> > of
> > > + letters and digits, following the sign if present.
> > > +
> > > + The subject sequence is defined as the longest initial
> > > + subsequence of
> > the
> > > + input string, starting with the first non-white-space character, that is
> of
> > > + the expected form. The subject sequence contains no characters
> > > + if the
> > input
> > > + string is empty or consists entirely of white space, or if the first
> > > + non-white-space character is other than a sign or a permissible
> > > + letter or
> > digit.
> > > +
> > > + If the subject sequence has the expected form and the value of base
> is
> > > + zero, the sequence of characters starting with the first digit is
> > > + interpreted as an integer constant. If the subject sequence has the
> > > + expected form and the value of base is between 2 and 36, it is
> > > + used as
> > the
> > > + base for conversion, ascribing to each letter its value as given above. If
> > > + the subject sequence begins with a minus sign, the value
> > > + resulting from
> > the
> > > + conversion is negated (in the return type). A pointer to the final string
> > > + is stored in the object pointed to by endptr, provided that endptr is
> > > + not a null pointer.
> > > +
> > > + In other than the "C" locale, additional locale-specific subject
> sequence
> > > + forms may be accepted.
> > > +
> > > + If the subject sequence is empty or does not have the expected
> > > + form,
> > no
> > > + conversion is performed; the value of nptr is stored in the
> > > + object
> > pointed
> > > + to by endptr, provided that endptr is not a null pointer.
> > > +
> > > + @return The strtol, strtoll, strtoul, and strtoull functions return the
> > > + converted value, if any. If no conversion could be performed, zero
> > > + is returned. If the correct value is outside the range of
> > > + representable values, LONG_MIN, LONG_MAX, LLONG_MIN,
> > LLONG_MAX,
> > > + ULONG_MAX, or ULLONG_MAX is returned (according to the
> > > + return
> > type
> > > + and sign of the value, if any), and the value of the macro ERANGE
> > > + is stored in errno.
> > > +**/
> > > +long
> > > +strtol(const char * nptr, char ** endptr, int base) {
> > > + const char *pEnd;
> > > + long Result = 0;
> > > + long Previous;
> > > + int temp;
> > > + BOOLEAN Negative = FALSE;
> > > +
> > > + pEnd = nptr;
> > > +
> > > + if((base < 0) || (base == 1) || (base > 36)) {
> > > + if(endptr != NULL) {
> > > + *endptr = NULL;
> > > + }
> > > + return 0;
> > > + }
> > > + // Skip leading spaces.
> > > + while(isspace(*nptr)) ++nptr;
> > > +
> > > + // Process Subject sequence: optional sign followed by digits.
> > > + if(*nptr == '+') {
> > > + Negative = FALSE;
> > > + ++nptr;
> > > + }
> > > + else if(*nptr == '-') {
> > > + Negative = TRUE;
> > > + ++nptr;
> > > + }
> > > +
> > > + if(*nptr == '0') { /* Might be Octal or Hex */
> > > + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> > > + if((base == 0) || (base == 16)) {
> > > + nptr += 2; /* Skip the "0X" */
> > > + base = 16; /* In case base was 0 */
> > > + }
> > > + }
> > > + else { /* Looks like Octal */
> > > + if((base == 0) || (base == 8)) {
> > > + ++nptr; /* Skip the leading "0" */
> > > + base = 8; /* In case base was 0 */
> > > + }
> > > + }
> > > + }
> > > + if(base == 0) { /* If still zero then must be decimal */
> > > + base = 10;
> > > + }
> > > + if(*nptr == '0') {
> > > + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> > > + pEnd = nptr;
> > > + }
> > > +
> > > + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> > > + Previous = Result;
> > > + Result = (Result * base) + (long int)temp;
> > > + if( Result <= Previous) { // Detect Overflow
> > > + if(Negative) {
> > > + Result = LONG_MIN;
> > > + }
> > > + else {
> > > + Result = LONG_MAX;
> > > + }
> > > + Negative = FALSE;
> > > + errno = ERANGE;
> > > + break;
> > > + }
> > > + pEnd = ++nptr;
> > > + }
> > > + if(Negative) {
> > > + Result = -Result;
> > > + }
> > > +
> > > + // Save pointer to final sequence
> > > + if(endptr != NULL) {
> > > + *endptr = (char *)pEnd;
> > > + }
> > > + return Result;
> > > +}
> > > +
> > > +/** The strtoull function converts the initial portion of the
> > > +string pointed
> > to
> > > + by nptr to unsigned long long int representation.
> > > +
> > > + See the description for strtol for more information.
> > > +
> > > + @return The strtoull function returns the converted value, if any. If no
> > > + conversion could be performed, zero is returned. If the correct
> > > + value is outside the range of representable values, ULLONG_MAX
> is
> > > + returned and the value of the macro ERANGE is stored in errno.
> > > +**/
> > > +unsigned long long
> > > +strtoull(const char * nptr, char ** endptr, int base) {
> > > + const char *pEnd;
> > > + unsigned long long Result = 0;
> > > + unsigned long long Previous;
> > > + int temp;
> > > +
> > > + pEnd = nptr;
> > > +
> > > + if((base < 0) || (base == 1) || (base > 36)) {
> > > + if(endptr != NULL) {
> > > + *endptr = NULL;
> > > + }
> > > + return 0;
> > > + }
> > > + // Skip leading spaces.
> > > + while(isspace(*nptr)) ++nptr;
> > > +
> > > + // Process Subject sequence: optional + sign followed by digits.
> > > + if(*nptr == '+') {
> > > + ++nptr;
> > > + }
> > > +
> > > + if(*nptr == '0') { /* Might be Octal or Hex */
> > > + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */
> > > + if((base == 0) || (base == 16)) {
> > > + nptr += 2; /* Skip the "0X" */
> > > + base = 16; /* In case base was 0 */
> > > + }
> > > + }
> > > + else { /* Looks like Octal */
> > > + if((base == 0) || (base == 8)) {
> > > + ++nptr; /* Skip the leading "0" */
> > > + base = 8; /* In case base was 0 */
> > > + }
> > > + }
> > > + }
> > > + if(base == 0) { /* If still zero then must be decimal */
> > > + base = 10;
> > > + }
> > > + if(*nptr == '0') {
> > > + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */
> > > + pEnd = nptr;
> > > + }
> > > +
> > > + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
> > > + Previous = Result;
> > > + Result = DivU64x32 (Result, base) + (unsigned long long)temp;
> > > + if( Result < Previous) { // If we overflowed
> > > + Result = ULLONG_MAX;
> > > + errno = ERANGE;
> > > + break;
> > > + }
> > > + pEnd = ++nptr;
> > > + }
> > > +
> > > + // Save pointer to final sequence
> > > + if(endptr != NULL) {
> > > + *endptr = (char *)pEnd;
> > > + }
> > > + return Result;
> > > +}
> > > +
> > > +/**
> > > + edk2 Jansson port does not support doubles, simply return 0.
> > > +
> > > + These conversion functions convert the initial portion of the
> > > + string pointed to by nptr to double, float, and long double
> > > + representation, respectively.
> > > +
> > > + The strtod(), strtof(), and strtold() functions return the
> > > + converted value, if any.
> > > +
> > > + If endptr is not NULL, a pointer to the character after the last
> > > + charac- ter used in the conversion is stored in the location
> > > + referenced by endptr.
> > > +
> > > + If no conversion is performed, zero is returned and the value of
> > > + nptr is stored in the location referenced by endptr.
> > > +
> > > + If the correct value would cause overflow, plus or minus
> > > + HUGE_VAL, HUGE_VALF, or HUGE_VALL is returned (according to the
> > > + sign and type of the return value), and ERANGE is stored in
> > > + errno. If the correct value would cause underflow, zero is
> > > + returned and ERANGE is
> > stored in errno.
> > > +
> > > + @return Return 0.
> > > +**/
> > > +double
> > > +strtod (const char * __restrict nptr, char ** __restrict endptr) {
> > > + if(endptr)
> > > + *endptr = (char *)(nptr + strlen(nptr));
> > > +
> > > + return (double)0;
> > > +}
> > > +
> > > +/**
> > > + Allocate and zero-initialize array.
> > > +**/
> > > +void *
> > > +calloc(size_t Num, size_t Size)
> > > +{
> > > + void *RetVal;
> > > + size_t NumSize;
> > > +
> > > + NumSize = Num * Size;
> > > + RetVal = NULL;
> > > + if (NumSize != 0) {
> > > + RetVal = malloc(NumSize);
> > > + if( RetVal != NULL) {
> > > + (VOID)ZeroMem( RetVal, NumSize); } } DEBUG((DEBUG_POOL,
> > > + "0x%p = calloc(%d, %d)\n", RetVal, Num, Size));
> > > +
> > > + return RetVal;
> > > +}
> > > +
> > > +//
> > > +// The arrays give the cumulative number of days up to the first
> > > +of the // month number used as the index (1 -> 12) for regular and
> > > +leap
> > years.
> > > +// The value at index 13 is for the whole year.
> > > +//
> > > +UINTN CumulativeDays[2][14] = {
> > > + {
> > > + 0,
> > > + 0,
> > > + 31,
> > > + 31 + 28,
> > > + 31 + 28 + 31,
> > > + 31 + 28 + 31 + 30,
> > > + 31 + 28 + 31 + 30 + 31,
> > > + 31 + 28 + 31 + 30 + 31 + 30,
> > > + 31 + 28 + 31 + 30 + 31 + 30 + 31,
> > > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
> > > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
> > > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
> > > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
> > > + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
> > > + },
> > > + {
> > > + 0,
> > > + 0,
> > > + 31,
> > > + 31 + 29,
> > > + 31 + 29 + 31,
> > > + 31 + 29 + 31 + 30,
> > > + 31 + 29 + 31 + 30 + 31,
> > > + 31 + 29 + 31 + 30 + 31 + 30,
> > > + 31 + 29 + 31 + 30 + 31 + 30 + 31,
> > > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,
> > > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
> > > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
> > > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
> > > + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
> > > + }
> > > +};
> > > +
> > > +#define IsLeap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) ==
> 0))
> > > +#define SECSPERMIN (60)
> > > +#define SECSPERHOUR (60 * 60)
> > > +#define SECSPERDAY (24 * SECSPERHOUR)
> > > +
> > > +/**
> > > + Get the system time as seconds elapsed since midnight, January 1,
> 1970.
> > > +**/
> > > +time_t time (time_t *timer)
> > > +{
> > > + EFI_TIME Time;
> > > + time_t CalTime;
> > > + UINTN Year;
> > > +
> > > + //
> > > + // Get the current time and date information // gRT->GetTime
> > > + (&Time, NULL);
> > > +
> > > + //
> > > + // Years Handling
> > > + // UTime should now be set to 00:00:00 on Jan 1 of the current year.
> > > + //
> > > + for (Year = 1970, CalTime = 0; Year != Time.Year; Year++) {
> > > + CalTime = CalTime + (time_t)(CumulativeDays[IsLeap(Year)][13] *
> > > + SECSPERDAY); }
> > > +
> > > + //
> > > + // Add in number of seconds for current Month, Day, Hour, Minute,
> > > + Seconds, and TimeZone adjustment // CalTime = CalTime +
> > > + (time_t)((Time.TimeZone != EFI_UNSPECIFIED_TIMEZONE) ?
> > (Time.TimeZone * 60) : 0) +
> > > + (time_t)(CumulativeDays[IsLeap(Time.Year)][Time.Month]
> > > + *
> > SECSPERDAY) +
> > > + (time_t)(((Time.Day > 0) ? Time.Day - 1 : 0) * SECSPERDAY) +
> > > + (time_t)(Time.Hour * SECSPERHOUR) +
> > > + (time_t)(Time.Minute * 60) +
> > > + (time_t)Time.Second;
> > > +
> > > + if (timer != NULL) {
> > > + *timer = CalTime;
> > > + }
> > > +
> > > + return CalTime;
> > > +}
> > > +
> > > +typedef
> > > +int
> > > +(*SORT_COMPARE)(
> > > + IN VOID *Buffer1,
> > > + IN VOID *Buffer2
> > > + );
> > > +
> > > +/**
> > > + Duplicated from EDKII BaseSortLib for qsort() wrapper
> > > + @param[in, out] BufferToSort on call a Buffer of (possibly sorted)
> > elements
> > > + on return a buffer of sorted elements
> > > + @param[in] Count the number of elements in the buffer to sort
> > > + @param[in] ElementSize Size of an element in bytes
> > > + @param[in] CompareFunction The function to call to perform the
> > comparison
> > > + of any 2 elements
> > > + @param[in] Buffer Buffer of size ElementSize for use in
> swapping
> > > +**/
> > > +STATIC
> > > +VOID
> > > +QuickSortWorker (
> > > + IN OUT VOID *BufferToSort,
> > > + IN CONST UINTN Count,
> > > + IN CONST UINTN ElementSize,
> > > + IN SORT_COMPARE CompareFunction,
> > > + IN VOID *Buffer
> > > + )
> > > +{
> > > + VOID *Pivot;
> > > + UINTN LoopCount;
> > > + UINTN NextSwapLocation;
> > > +
> > > + ASSERT(BufferToSort != NULL);
> > > + ASSERT(CompareFunction != NULL);
> > > + ASSERT(Buffer != NULL);
> > > +
> > > + if (Count < 2 || ElementSize < 1) {
> > > + return;
> > > + }
> > > +
> > > + NextSwapLocation = 0;
> > > +
> > > + //
> > > + // Pick a pivot (we choose last element) // Pivot = ((UINT8
> > > + *)BufferToSort + ((Count - 1) * ElementSize));
> > > +
> > > + //
> > > + // Now get the pivot such that all on "left" are below it // and
> > > + everything "right" are above it // for (LoopCount = 0; LoopCount
> > > + < Count - 1; LoopCount++) {
> > > + //
> > > + // If the element is less than the pivot
> > > + //
> > > + if (CompareFunction ((VOID *)((UINT8 *)BufferToSort +
> > > + ((LoopCount) *
> > ElementSize)), Pivot) <= 0) {
> > > + //
> > > + // Swap
> > > + //
> > > + CopyMem (Buffer, (UINT8 *)BufferToSort + (NextSwapLocation *
> > ElementSize), ElementSize);
> > > + CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation *
> > > + ElementSize), (UINT8 *)BufferToSort + ((LoopCount) *
> > > ElementSize), ElementSize);
> > > + CopyMem ((UINT8 *)BufferToSort + ((LoopCount) * ElementSize),
> > > + Buffer, ElementSize);
> > > +
> > > + //
> > > + // Increment NextSwapLocation
> > > + //
> > > + NextSwapLocation++;
> > > + }
> > > + }
> > > + //
> > > + // Swap pivot to it's final position (NextSwapLocaiton) //
> > > + CopyMem (Buffer, Pivot, ElementSize); CopyMem (Pivot, (UINT8
> > > + *)BufferToSort + (NextSwapLocation * ElementSize), ElementSize);
> > > + CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation * ElementSize),
> > > + Buffer, ElementSize);
> > > +
> > > + //
> > > + // Now recurse on 2 paritial lists. Neither of these will have the 'pivot'
> > element.
> > > + // IE list is sorted left half, pivot element, sorted right half...
> > > + //
> > > + QuickSortWorker (
> > > + BufferToSort,
> > > + NextSwapLocation,
> > > + ElementSize,
> > > + CompareFunction,
> > > + Buffer
> > > + );
> > > +
> > > + QuickSortWorker (
> > > + (UINT8 *)BufferToSort + (NextSwapLocation + 1) * ElementSize,
> > > + Count - NextSwapLocation - 1,
> > > + ElementSize,
> > > + CompareFunction,
> > > + Buffer
> > > + );
> > > +
> > > + return;
> > > +}
> > > +
> > > +/**
> > > + Performs a quick sort
> > > +**/
> > > +void qsort (void *base, size_t num, size_t width, int
> > > +(*compare)(const void *, const void *)) {
> > > + VOID *Buffer;
> > > +
> > > + ASSERT (base != NULL);
> > > + ASSERT (compare != NULL);
> > > +
> > > + //
> > > + // Use CRT-style malloc to cover BS and RT memory allocation.
> > > + //
> > > + Buffer = malloc (width);
> > > + ASSERT (Buffer != NULL);
> > > +
> > > + //
> > > + // Re-use PerformQuickSort() function Implementation in EDKII
> > BaseSortLib.
> > > + //
> > > + QuickSortWorker (base, (UINTN)num, (UINTN)width,
> > > + (SORT_COMPARE)compare, Buffer);
> > > +
> > > + free (Buffer);
> > > + return;
> > > +}
> > > +
> > > +/**
> > > + Get character from stream, we don't support file operastion on
> > > +edk2
> > JSON library.
> > > +
> > > + @return Returns the character currently pointed by the internal
> > > + file position indicator of the specified stream
> > > +
> > > +**/
> > > +int fgetc(FILE * _File){
> > > + return 0;
> > > +}
> > > diff --git a/RedfishPkg/Library/CrtLib/CrtLib.inf
> > > b/RedfishPkg/Library/CrtLib/CrtLib.inf
> > > new file mode 100644
> > > index 0000000000..b514817cf4
> > > --- /dev/null
> > > +++ b/RedfishPkg/Library/CrtLib/CrtLib.inf
> > > @@ -0,0 +1,37 @@
> > > +## @file
> > > +# EDK2 C Runtime Library for opensource project.
> > > +#
> > > +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> #
> > > +(C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR> #
> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +#
> > > +##
> > > +
> > > +[Defines]
> > > + INF_VERSION = 0x0001001b
> > > + BASE_NAME = CrtLib
> > > + FILE_GUID = 8263B8AC-D021-425D-B337-3EC96F5DC19B
> > > + MODULE_TYPE = DXE_DRIVER
> > > + VERSION_STRING = 1.0
> > > + LIBRARY_CLASS = CrtLib|DXE_CORE DXE_DRIVER
> > DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION
> > > UEFI_DRIVER
> > > +
> > > +#
> > > +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64
> > > +#
> > > +
> > > +[Sources]
> > > + CrtLib.c
> > > +
> > > +[LibraryClasses]
> > > + BaseLib
> > > + DebugLib
> > > + MemoryAllocationLib
> > > + UefiRuntimeServicesTableLib
> > > +
> > > +[Packages]
> > > + MdePkg/MdePkg.dec
> > > + MdeModulePkg/MdeModulePkg.dec
> > > + RedfishPkg/RedfishPkg.dec
> > > +
> > > +
> > > diff --git a/RedfishPkg/RedfishLibs.dsc.inc
> > > b/RedfishPkg/RedfishLibs.dsc.inc index d4c08e18ac..2a951bd8fa 100644
> > > --- a/RedfishPkg/RedfishLibs.dsc.inc
> > > +++ b/RedfishPkg/RedfishLibs.dsc.inc
> > > @@ -12,5 +12,6 @@
> > > ##
> > > !if $(REDFISH_ENABLE) == TRUE
> > >
> > > Ucs2Utf8Lib|RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > > + CrtLib|RedfishPkg/Library/CrtLib/CrtLib.inf
> > > !endif
> > >
> > > diff --git a/RedfishPkg/RedfishPkg.ci.yaml
> > > b/RedfishPkg/RedfishPkg.ci.yaml index 20c297ad22..9895fdac99 100644
> > > --- a/RedfishPkg/RedfishPkg.ci.yaml
> > > +++ b/RedfishPkg/RedfishPkg.ci.yaml
> > > @@ -17,6 +17,25 @@
> > > ],
> > > ## Both file path and directory path are accepted.
> > > "IgnoreFiles": [
> > > + ## Below are files incorporated with open source which are
> > > + ## not edk2 coding standard compliant.
> > > + ##
> > > + ## EDK2 CRT library which is not edk2 coding
> > > + ## standard compliant.
> > > + ## C runtime library for EDKII JsonLib.
> > > + "Include/Crt/sys",
> > > + "Include/Crt/assert.h",
> > > + "Include/Crt/errno.h",
> > > + "Include/Crt/limits.h",
> > > + "Include/Crt/math.h",
> > > + "Include/Crt/stdarg.h",
> > > + "Include/Crt/stddef.h",
> > > + "Include/Crt/stdio.h",
> > > + "Include/Crt/stdlib.h",
> > > + "Include/Crt/string.h",
> > > + "Include/Crt/time.h",
> > > + "Include/Library/CrtLib.h",
> > > + "Library/CrtLib/CrtLib.c"
> > > ]
> > > },
> > > "CompilerPlugin": {
> > > diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec
> > > index aecc1f4a3a..2142b43640 100644
> > > --- a/RedfishPkg/RedfishPkg.dec
> > > +++ b/RedfishPkg/RedfishPkg.dec
> > > @@ -15,16 +15,24 @@
> > >
> > > [Includes]
> > > Include
> > > + Include/Crt # Header files for C RTL.
> > >
> > > [LibraryClasses]
> > > ## @libraryclass Platform Redfish Host Interface Library
> > > # Platform implementation-specific Redfish Host Interface.
> > >
> > > RedfishPlatformHostInterfaceLib|Include/Library/RedfishHostInterface
> > > RedfishPlatformHostInterfaceLib|Li
> > > b.h
> > > +
> > > ## @libraryclass This library provides UCS2 to UTF8 manipulation
> > > # functions.
> > > #
> > > Ucs2Utf8Lib|Include/Library/BaseUcs2Utf8Lib.h
> > >
> > > + ## @libraryclass Provides the C runtime library functions
> > > + # CRT library is currently used by edk2 JsonLib (open source
> > > + # jansson project) and edk2 RedfishLib (libredfish open source
> > > + # project).
> > > + CrtLib|Include/Library/CrtLib.h
> > > +
> > > [Protocols]
> > > ## Include/Protocol/RedfishDiscover.h
> > > gEfiRedfishDiscoverProtocolGuid = { 0x5db12509, 0x4550, 0x4347,
> { 0x96,
> > 0xb3, 0x73, 0xc0, 0xff, 0x6e, 0x86, 0x9f
> > > }}
> > > diff --git a/RedfishPkg/RedfishPkg.dsc b/RedfishPkg/RedfishPkg.dsc
> > > index 3639b620e6..aa1ccd5a95 100644
> > > --- a/RedfishPkg/RedfishPkg.dsc
> > > +++ b/RedfishPkg/RedfishPkg.dsc
> > > @@ -48,5 +48,6 @@
> > > [Components]
> > >
> > RedfishPkg/Library/PlatformHostInterfaceLibNull/PlatformHostInterfaceL
> > ibN
> > ull.inf
> > > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > > + RedfishPkg/Library/CrtLib/CrtLib.inf
> > >
> > > !include RedfishPkg/Redfish.dsc.inc
> > > --
> > > 2.17.1
> > >
> > >
> > >
> > >
> > >
^ permalink raw reply [flat|nested] 15+ messages in thread