mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2026-05-04 09:54:52 +00:00
hv: lib: Add several missing standard string/memory APIs
Integrating libfdt requires the presence of these APIs. Tracked-On: #8838 Signed-off-by: Yifan Liu <yifan1.liu@intel.com> Acked-by: Wang Yu1 <yu1.wang@intel.com>
This commit is contained in:
@@ -32,6 +32,8 @@ void memcpy_backwards(void *d, const void *s, size_t slen);
|
||||
#endif
|
||||
|
||||
int32_t memcpy_s(void *d, size_t dmax, const void *s, size_t slen);
|
||||
|
||||
int memcmp(const void *s1, const void *s2, size_t count);
|
||||
void *memmove(void *d, const void *s, size_t slen);
|
||||
void *memchr(const void *s, int c, size_t slen);
|
||||
|
||||
#endif /* MEMORY_LIB_H */
|
||||
|
||||
@@ -38,11 +38,16 @@ static inline bool is_eol(char c)
|
||||
int32_t strcmp(const char *s1_arg, const char *s2_arg);
|
||||
int32_t strncmp(const char *s1_arg, const char *s2_arg, size_t n_arg);
|
||||
int32_t strncpy_s(char *d, size_t dmax, const char *s, size_t slen);
|
||||
char *strchr(char *s_arg, char ch);
|
||||
char *strchr(const char *s_arg, char ch);
|
||||
size_t strnlen_s(const char *str_arg, size_t maxlen_arg);
|
||||
int64_t strtol_deci(const char *nptr);
|
||||
uint64_t strtoul_hex(const char *nptr);
|
||||
uint64_t strtoul(const char * nptr, char **endptr, int base);
|
||||
char *strstr_s(const char *str1, size_t maxlen1, const char *str2, size_t maxlen2);
|
||||
int32_t strncat_s(char *dest, size_t dmax, const char *src, size_t slen);
|
||||
size_t strlen(const char *str);
|
||||
size_t strnlen(const char *str, size_t count);
|
||||
char *strrchr(const char *s, char ch);
|
||||
char *strcpy(char *d, const char *s);
|
||||
|
||||
#endif /* RTL_H */
|
||||
|
||||
@@ -24,6 +24,7 @@ typedef unsigned short uint16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned long uint64_t;
|
||||
typedef unsigned long uintptr_t;
|
||||
typedef signed long int64_t;
|
||||
typedef unsigned int size_t;
|
||||
typedef __builtin_va_list va_list;
|
||||
|
||||
@@ -66,3 +66,61 @@ int32_t memcpy_s(void *d, size_t dmax, const void *s, size_t slen)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int memcmp(const void *s1, const void *s2, size_t count)
|
||||
{
|
||||
const char *t1 = s1;
|
||||
const char *t2 = s2;
|
||||
int ret = 0;
|
||||
|
||||
for (; count > 0 && (*t1 == *t2); count--) {
|
||||
t1++;
|
||||
t2++;
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
ret = *(unsigned char *)t1 - *(unsigned char *)t2;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *memmove(void *d, const void *s, size_t slen)
|
||||
{
|
||||
char *t1 = (char *)d;
|
||||
const char *t2 = (char *)s;
|
||||
|
||||
if (d == s) {
|
||||
/* do nothing */
|
||||
} else if (d < s) {
|
||||
while (slen > 0) {
|
||||
*t1++ = *t2++;
|
||||
slen--;
|
||||
}
|
||||
} else {
|
||||
t1 = (char *)d + slen - 1;
|
||||
t2 = (char *)s + slen - 1;
|
||||
|
||||
while (slen > 0) {
|
||||
*t1-- = *t2--;
|
||||
slen--;
|
||||
}
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
void *memchr(const void *s, int c, size_t slen)
|
||||
{
|
||||
void *ret = NULL;
|
||||
const unsigned char *t;
|
||||
|
||||
for (t = s; slen > 0; slen--) {
|
||||
if ((unsigned char)c == *t++) {
|
||||
ret = (void *)(t - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -6,19 +6,81 @@
|
||||
#include <rtl.h>
|
||||
#include <logmsg.h>
|
||||
|
||||
static inline char hex_digit_value(char ch)
|
||||
uint64_t strtoul(const char * nptr, char **endptr, int base)
|
||||
{
|
||||
char c;
|
||||
if (('0' <= ch) && (ch <= '9')) {
|
||||
c = ch - '0';
|
||||
} else if (('a' <= ch) && (ch <= 'f')) {
|
||||
c = ch - 'a' + 10;
|
||||
} else if (('A' <= ch) && (ch <= 'F')) {
|
||||
c = ch - 'A' + 10;
|
||||
const char *s;
|
||||
unsigned long acc, cutoff;
|
||||
int c;
|
||||
int neg, any, cutlim;
|
||||
|
||||
/*
|
||||
* See strtol for comments as to the logic used.
|
||||
*/
|
||||
s = nptr;
|
||||
do {
|
||||
c = (unsigned char) *s++;
|
||||
} while (is_space(c));
|
||||
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else {
|
||||
c = -1;
|
||||
neg = 0;
|
||||
if (c == '+')
|
||||
c = *s++;
|
||||
}
|
||||
return c;
|
||||
|
||||
if ((base == 0 || base == 16) &&
|
||||
c == '0' && (*s == 'x' || *s == 'X')) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
|
||||
if (base == 0) {
|
||||
base = c == '0' ? 8 : 10;
|
||||
}
|
||||
|
||||
cutoff = ULONG_MAX / (unsigned long)base;
|
||||
cutlim = ULONG_MAX % (unsigned long)base;
|
||||
|
||||
for (acc = 0, any = 0;; c = (unsigned char) *s++) {
|
||||
if (c >= '0' && c <= '9') {
|
||||
c -= '0';
|
||||
} else if (c >= 'A' && c <= 'Z') {
|
||||
c -= 'A' - 10;
|
||||
} else if (c >= 'a' && c <= 'z') {
|
||||
c -= 'a' - 10;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
if (c >= base) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (any < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (acc > cutoff || (acc == cutoff && c > cutlim)) {
|
||||
any = -1;
|
||||
acc = ULONG_MAX;
|
||||
} else {
|
||||
any = 1;
|
||||
acc *= (unsigned long)base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
|
||||
if (neg && any > 0) {
|
||||
acc = -acc;
|
||||
}
|
||||
|
||||
if (endptr != 0) {
|
||||
*endptr = (char *) (any ? s - 1 : nptr);
|
||||
}
|
||||
|
||||
return (acc);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -26,58 +88,56 @@ static inline char hex_digit_value(char ch)
|
||||
*/
|
||||
uint64_t strtoul_hex(const char *nptr)
|
||||
{
|
||||
const char *s = nptr;
|
||||
char c, digit;
|
||||
uint64_t acc, cutoff, cutlim;
|
||||
uint64_t base = 16UL;
|
||||
int32_t any;
|
||||
|
||||
/*
|
||||
* See strtol for comments as to the logic used.
|
||||
*/
|
||||
do {
|
||||
c = *s;
|
||||
s++;
|
||||
} while (is_space(c));
|
||||
|
||||
if ((c == '0') && ((*s == 'x') || (*s == 'X'))) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
}
|
||||
|
||||
cutoff = ULONG_MAX / base;
|
||||
cutlim = ULONG_MAX % base;
|
||||
acc = 0UL;
|
||||
any = 0;
|
||||
digit = hex_digit_value(c);
|
||||
while (digit >= 0) {
|
||||
if ((acc > cutoff) || ((acc == cutoff) && ((uint64_t)digit > cutlim))) {
|
||||
any = -1;
|
||||
break;
|
||||
} else {
|
||||
acc *= base;
|
||||
acc += (uint64_t)digit;
|
||||
}
|
||||
|
||||
c = *s;
|
||||
s++;
|
||||
digit = hex_digit_value(c);
|
||||
}
|
||||
|
||||
if (any < 0) {
|
||||
acc = ULONG_MAX;
|
||||
}
|
||||
return acc;
|
||||
return strtoul(nptr, NULL, 16);
|
||||
}
|
||||
|
||||
char *strchr(char *s_arg, char ch)
|
||||
char *strchr(const char *s_arg, char ch)
|
||||
{
|
||||
char *s = s_arg;
|
||||
const char *s = s_arg;
|
||||
while ((*s != '\0') && (*s != ch)) {
|
||||
++s;
|
||||
}
|
||||
|
||||
return ((*s) != '\0') ? s : NULL;
|
||||
return ((*s) != '\0') ? (char *)s : NULL;
|
||||
}
|
||||
|
||||
size_t strlen(const char *str)
|
||||
{
|
||||
unsigned long ret;
|
||||
|
||||
for (ret = 0; *str != '\0'; str++) {
|
||||
ret++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t strnlen(const char *str, size_t count)
|
||||
{
|
||||
unsigned long ret;
|
||||
|
||||
for (ret = 0; (*str != '\0') && (ret < count); str++) {
|
||||
ret++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *strrchr(const char *s, char ch)
|
||||
{
|
||||
const char *last = s + strlen(s);
|
||||
while (last > s && *last != ch) {
|
||||
last--;
|
||||
}
|
||||
|
||||
return (*last != ch) ? NULL : (char *)last;
|
||||
}
|
||||
|
||||
char *strcpy(char *d, const char *s)
|
||||
{
|
||||
char *ret = d;
|
||||
while ((*d++ = *s++) != '\0') { }
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user