GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <asm_macros.S>
|
||||
|
||||
.syntax unified
|
||||
.global memset
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
* void *memset(void *dst, int val, size_t count)
|
||||
*
|
||||
* Copy the value of 'val' (converted to an unsigned char) into
|
||||
* each of the first 'count' characters of the object pointed to by 'dst'.
|
||||
*
|
||||
* Returns the value of 'dst'.
|
||||
* -----------------------------------------------------------------------
|
||||
*/
|
||||
func memset
|
||||
mov r12, r0 /* keep r0 */
|
||||
tst r0, #3
|
||||
beq aligned /* 4-bytes aligned */
|
||||
|
||||
/* Unaligned 'dst' */
|
||||
unaligned:
|
||||
subs r2, r2, #1
|
||||
strbhs r1, [r12], #1
|
||||
bxls lr /* return if 0 */
|
||||
tst r12, #3
|
||||
bne unaligned /* continue while unaligned */
|
||||
|
||||
/* 4-bytes aligned */
|
||||
aligned:bfi r1, r1, #8, #8 /* propagate 'val' */
|
||||
bfi r1, r1, #16, #16
|
||||
|
||||
mov r3, r1
|
||||
|
||||
cmp r2, #16
|
||||
blo less_16 /* < 16 */
|
||||
|
||||
push {r4, lr}
|
||||
mov r4, r1
|
||||
mov lr, r1
|
||||
|
||||
write_32:
|
||||
subs r2, r2, #32
|
||||
stmiahs r12!, {r1, r3, r4, lr}
|
||||
stmiahs r12!, {r1, r3, r4, lr}
|
||||
bhi write_32 /* write 32 bytes in a loop */
|
||||
popeq {r4, pc} /* return if 0 */
|
||||
lsls r2, r2, #28 /* C = r2[4]; N = r2[3]; Z = r2[3:0] */
|
||||
stmiacs r12!, {r1, r3, r4, lr} /* write 16 bytes */
|
||||
popeq {r4, pc} /* return if 16 */
|
||||
stmiami r12!, {r1, r3} /* write 8 bytes */
|
||||
lsls r2, r2, #2 /* C = r2[2]; N = r2[1]; Z = r2[1:0] */
|
||||
strcs r1, [r12], #4 /* write 4 bytes */
|
||||
popeq {r4, pc} /* return if 8 or 4 */
|
||||
strhmi r1, [r12], #2 /* write 2 bytes */
|
||||
lsls r2, r2, #1 /* N = Z = r2[0] */
|
||||
strbmi r1, [r12] /* write 1 byte */
|
||||
pop {r4, pc}
|
||||
|
||||
less_16:lsls r2, r2, #29 /* C = r2[3]; N = r2[2]; Z = r2[2:0] */
|
||||
stmiacs r12!, {r1, r3} /* write 8 bytes */
|
||||
bxeq lr /* return if 8 */
|
||||
strmi r1, [r12], #4 /* write 4 bytes */
|
||||
lsls r2, r2, #2 /* C = r2[1]; N = Z = r2[0] */
|
||||
strhcs r1, [r12], #2 /* write 2 bytes */
|
||||
strbmi r1, [r12] /* write 1 byte */
|
||||
bx lr
|
||||
|
||||
endfunc memset
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <asm_macros.S>
|
||||
|
||||
.global memset
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
* void *memset(void *dst, int val, size_t count)
|
||||
*
|
||||
* Copy the value of 'val' (converted to an unsigned char) into
|
||||
* each of the first 'count' characters of the object pointed to by 'dst'.
|
||||
*
|
||||
* Returns the value of 'dst'.
|
||||
* -----------------------------------------------------------------------
|
||||
*/
|
||||
func memset
|
||||
cbz x2, exit /* exit if 'count' = 0 */
|
||||
mov x3, x0 /* keep x0 */
|
||||
tst x0, #7
|
||||
b.eq aligned /* 8-bytes aligned */
|
||||
|
||||
/* Unaligned 'dst' */
|
||||
unaligned:
|
||||
strb w1, [x3], #1
|
||||
subs x2, x2, #1
|
||||
b.eq exit /* exit if 0 */
|
||||
tst x3, #7
|
||||
b.ne unaligned /* continue while unaligned */
|
||||
|
||||
/* 8-bytes aligned */
|
||||
aligned:cbz x1, x1_zero
|
||||
bfi w1, w1, #8, #8 /* propagate 'val' */
|
||||
bfi w1, w1, #16, #16
|
||||
bfi x1, x1, #32, #32
|
||||
|
||||
x1_zero:ands x4, x2, #~0x3f
|
||||
b.eq less_64
|
||||
|
||||
write_64:
|
||||
.rept 4
|
||||
stp x1, x1, [x3], #16 /* write 64 bytes in a loop */
|
||||
.endr
|
||||
subs x4, x4, #64
|
||||
b.ne write_64
|
||||
less_64:tbz w2, #5, less_32 /* < 32 bytes */
|
||||
stp x1, x1, [x3], #16 /* write 32 bytes */
|
||||
stp x1, x1, [x3], #16
|
||||
less_32:tbz w2, #4, less_16 /* < 16 bytes */
|
||||
stp x1, x1, [x3], #16 /* write 16 bytes */
|
||||
less_16:tbz w2, #3, less_8 /* < 8 bytes */
|
||||
str x1, [x3], #8 /* write 8 bytes */
|
||||
less_8: tbz w2, #2, less_4 /* < 4 bytes */
|
||||
str w1, [x3], #4 /* write 4 bytes */
|
||||
less_4: tbz w2, #1, less_2 /* < 2 bytes */
|
||||
strh w1, [x3], #2 /* write 2 bytes */
|
||||
less_2: tbz w2, #0, exit
|
||||
strb w1, [x3] /* write 1 byte */
|
||||
exit: ret
|
||||
|
||||
endfunc memset
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <asm_macros.S>
|
||||
#include <assert_macros.S>
|
||||
#include <setjmp.h>
|
||||
|
||||
.globl setjmp
|
||||
.globl longjmp
|
||||
|
||||
/*
|
||||
* int setjmp(jmp_buf env);
|
||||
*/
|
||||
func setjmp
|
||||
mov x7, sp
|
||||
|
||||
stp x19, x20, [x0, #JMP_CTX_X19]
|
||||
stp x21, x22, [x0, #JMP_CTX_X21]
|
||||
stp x23, x24, [x0, #JMP_CTX_X23]
|
||||
stp x25, x26, [x0, #JMP_CTX_X25]
|
||||
stp x27, x28, [x0, #JMP_CTX_X27]
|
||||
stp x29, x30, [x0, #JMP_CTX_X29]
|
||||
stp x7, xzr, [x0, #JMP_CTX_SP]
|
||||
|
||||
mov x0, #0
|
||||
ret
|
||||
endfunc setjmp
|
||||
|
||||
|
||||
/*
|
||||
* void longjmp(jmp_buf env, int val);
|
||||
*/
|
||||
func longjmp
|
||||
ldp x7, xzr, [x0, #JMP_CTX_SP]
|
||||
|
||||
#if ENABLE_ASSERTIONS
|
||||
/*
|
||||
* Since we're unwinding the stack, assert that the stack being reset to
|
||||
* is shallower.
|
||||
*/
|
||||
mov x19, sp
|
||||
cmp x7, x19
|
||||
ASM_ASSERT(ge)
|
||||
#endif
|
||||
|
||||
ldp x19, x20, [x0, #JMP_CTX_X19]
|
||||
ldp x21, x22, [x0, #JMP_CTX_X21]
|
||||
ldp x23, x24, [x0, #JMP_CTX_X23]
|
||||
ldp x25, x26, [x0, #JMP_CTX_X25]
|
||||
ldp x27, x28, [x0, #JMP_CTX_X27]
|
||||
ldp x29, x30, [x0, #JMP_CTX_X29]
|
||||
|
||||
mov sp, x7
|
||||
|
||||
ands x0, x1, x1 /* Move val to x0 and set flags */
|
||||
cinc x0, x0, eq /* If val is 0, return 1 */
|
||||
ret
|
||||
endfunc longjmp
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
|
||||
void abort(void)
|
||||
{
|
||||
ERROR("ABORT\n");
|
||||
panic();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <cdefs.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/console.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
/*
|
||||
* Only print the output if PLAT_LOG_LEVEL_ASSERT is higher or equal to
|
||||
* LOG_LEVEL_INFO, which is the default value for builds with DEBUG=1.
|
||||
*/
|
||||
|
||||
#if PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO
|
||||
void __dead2 __assert(const char *file, unsigned int line)
|
||||
{
|
||||
printf("ASSERT: %s:%u\n", file, line);
|
||||
backtrace("assert");
|
||||
console_flush();
|
||||
plat_panic_handler();
|
||||
}
|
||||
#else
|
||||
void __dead2 __assert(void)
|
||||
{
|
||||
backtrace("assert");
|
||||
console_flush();
|
||||
plat_panic_handler();
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
static void (*exitfun)(void);
|
||||
|
||||
void exit(int status)
|
||||
{
|
||||
if (exitfun != NULL)
|
||||
(*exitfun)();
|
||||
for (;;)
|
||||
;
|
||||
}
|
||||
|
||||
int atexit(void (*fun)(void))
|
||||
{
|
||||
if (exitfun != NULL)
|
||||
return -1;
|
||||
exitfun = fun;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#
|
||||
# Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
LIBC_SRCS := $(addprefix lib/libc/, \
|
||||
abort.c \
|
||||
assert.c \
|
||||
exit.c \
|
||||
memchr.c \
|
||||
memcmp.c \
|
||||
memcpy.c \
|
||||
memmove.c \
|
||||
memrchr.c \
|
||||
memset.c \
|
||||
printf.c \
|
||||
putchar.c \
|
||||
puts.c \
|
||||
snprintf.c \
|
||||
strchr.c \
|
||||
strcmp.c \
|
||||
strlcat.c \
|
||||
strlcpy.c \
|
||||
strlen.c \
|
||||
strncmp.c \
|
||||
strnlen.c \
|
||||
strrchr.c \
|
||||
strtok.c \
|
||||
strtoul.c \
|
||||
strtoll.c \
|
||||
strtoull.c \
|
||||
strtol.c)
|
||||
|
||||
ifeq (${ARCH},aarch64)
|
||||
LIBC_SRCS += $(addprefix lib/libc/aarch64/, \
|
||||
setjmp.S)
|
||||
endif
|
||||
|
||||
INCLUDES += -Iinclude/lib/libc \
|
||||
-Iinclude/lib/libc/$(ARCH) \
|
||||
@@ -0,0 +1,44 @@
|
||||
#
|
||||
# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
LIBC_SRCS := $(addprefix lib/libc/, \
|
||||
abort.c \
|
||||
assert.c \
|
||||
exit.c \
|
||||
memchr.c \
|
||||
memcmp.c \
|
||||
memcpy.c \
|
||||
memmove.c \
|
||||
memrchr.c \
|
||||
printf.c \
|
||||
putchar.c \
|
||||
puts.c \
|
||||
snprintf.c \
|
||||
strchr.c \
|
||||
strcmp.c \
|
||||
strlcat.c \
|
||||
strlcpy.c \
|
||||
strlen.c \
|
||||
strncmp.c \
|
||||
strnlen.c \
|
||||
strrchr.c \
|
||||
strtok.c \
|
||||
strtoul.c \
|
||||
strtoll.c \
|
||||
strtoull.c \
|
||||
strtol.c)
|
||||
|
||||
ifeq (${ARCH},aarch64)
|
||||
LIBC_SRCS += $(addprefix lib/libc/aarch64/, \
|
||||
memset.S \
|
||||
setjmp.S)
|
||||
else
|
||||
LIBC_SRCS += $(addprefix lib/libc/aarch32/, \
|
||||
memset.S)
|
||||
endif
|
||||
|
||||
INCLUDES += -Iinclude/lib/libc \
|
||||
-Iinclude/lib/libc/$(ARCH) \
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
void *memchr(const void *src, int c, size_t len)
|
||||
{
|
||||
const unsigned char *s = src;
|
||||
|
||||
while (len--) {
|
||||
if (*s == (unsigned char)c)
|
||||
return (void *) s;
|
||||
s++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
int memcmp(const void *s1, const void *s2, size_t len)
|
||||
{
|
||||
const unsigned char *s = s1;
|
||||
const unsigned char *d = s2;
|
||||
unsigned char sc;
|
||||
unsigned char dc;
|
||||
|
||||
while (len--) {
|
||||
sc = *s++;
|
||||
dc = *d++;
|
||||
if (sc - dc)
|
||||
return (sc - dc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
void *memcpy(void *dst, const void *src, size_t len)
|
||||
{
|
||||
const char *s = src;
|
||||
char *d = dst;
|
||||
|
||||
while (len--)
|
||||
*d++ = *s++;
|
||||
|
||||
return dst;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
void *memmove(void *dst, const void *src, size_t len)
|
||||
{
|
||||
/*
|
||||
* The following test makes use of unsigned arithmetic overflow to
|
||||
* more efficiently test the condition !(src <= dst && dst < str+len).
|
||||
* It also avoids the situation where the more explicit test would give
|
||||
* incorrect results were the calculation str+len to overflow (though
|
||||
* that issue is probably moot as such usage is probably undefined
|
||||
* behaviour and a bug anyway.
|
||||
*/
|
||||
if ((size_t)dst - (size_t)src >= len) {
|
||||
/* destination not in source data, so can safely use memcpy */
|
||||
return memcpy(dst, src, len);
|
||||
} else {
|
||||
/* copy backwards... */
|
||||
const char *end = dst;
|
||||
const char *s = (const char *)src + len;
|
||||
char *d = (char *)dst + len;
|
||||
while (d != end)
|
||||
*--d = *--s;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#undef memrchr
|
||||
|
||||
void *memrchr(const void *src, int c, size_t len)
|
||||
{
|
||||
const unsigned char *s = src + (len - 1);
|
||||
|
||||
while (len--) {
|
||||
if (*s == (unsigned char)c) {
|
||||
return (void*) s;
|
||||
}
|
||||
|
||||
s--;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void *memset(void *dst, int val, size_t count)
|
||||
{
|
||||
uint8_t *ptr = dst;
|
||||
uint64_t *ptr64;
|
||||
uint64_t fill = (unsigned char)val;
|
||||
|
||||
/* Simplify code below by making sure we write at least one byte. */
|
||||
if (count == 0U) {
|
||||
return dst;
|
||||
}
|
||||
|
||||
/* Handle the first part, until the pointer becomes 64-bit aligned. */
|
||||
while (((uintptr_t)ptr & 7U) != 0U) {
|
||||
*ptr = (uint8_t)val;
|
||||
ptr++;
|
||||
if (--count == 0U) {
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
|
||||
/* Duplicate the fill byte to the rest of the 64-bit word. */
|
||||
fill |= fill << 8;
|
||||
fill |= fill << 16;
|
||||
fill |= fill << 32;
|
||||
|
||||
/* Use 64-bit writes for as long as possible. */
|
||||
ptr64 = (uint64_t *)ptr;
|
||||
for (; count >= 8U; count -= 8) {
|
||||
*ptr64 = fill;
|
||||
ptr64++;
|
||||
}
|
||||
|
||||
/* Handle the remaining part byte-per-byte. */
|
||||
ptr = (uint8_t *)ptr64;
|
||||
while (count-- > 0U) {
|
||||
*ptr = (uint8_t)val;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define get_num_va_args(_args, _lcount) \
|
||||
(((_lcount) > 1) ? va_arg(_args, long long int) : \
|
||||
(((_lcount) == 1) ? va_arg(_args, long int) : \
|
||||
va_arg(_args, int)))
|
||||
|
||||
#define get_unum_va_args(_args, _lcount) \
|
||||
(((_lcount) > 1) ? va_arg(_args, unsigned long long int) : \
|
||||
(((_lcount) == 1) ? va_arg(_args, unsigned long int) : \
|
||||
va_arg(_args, unsigned int)))
|
||||
|
||||
static int string_print(const char *str)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
assert(str != NULL);
|
||||
|
||||
for ( ; *str != '\0'; str++) {
|
||||
(void)putchar(*str);
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int unsigned_num_print(unsigned long long int unum, unsigned int radix,
|
||||
char padc, int padn)
|
||||
{
|
||||
/* Just need enough space to store 64 bit decimal integer */
|
||||
char num_buf[20];
|
||||
int i = 0, count = 0;
|
||||
unsigned int rem;
|
||||
|
||||
/* num_buf is only large enough for radix >= 10 */
|
||||
if (radix < 10) {
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
do {
|
||||
rem = unum % radix;
|
||||
if (rem < 0xa)
|
||||
num_buf[i] = '0' + rem;
|
||||
else
|
||||
num_buf[i] = 'a' + (rem - 0xa);
|
||||
i++;
|
||||
unum /= radix;
|
||||
} while (unum > 0U);
|
||||
|
||||
if (padn > 0) {
|
||||
while (i < padn) {
|
||||
(void)putchar(padc);
|
||||
count++;
|
||||
padn--;
|
||||
}
|
||||
}
|
||||
|
||||
while (--i >= 0) {
|
||||
(void)putchar(num_buf[i]);
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* Reduced format print for Trusted firmware.
|
||||
* The following type specifiers are supported by this print
|
||||
* %x - hexadecimal format
|
||||
* %s - string format
|
||||
* %d or %i - signed decimal format
|
||||
* %u - unsigned decimal format
|
||||
* %p - pointer format
|
||||
*
|
||||
* The following length specifiers are supported by this print
|
||||
* %l - long int (64-bit on AArch64)
|
||||
* %ll - long long int (64-bit on AArch64)
|
||||
* %z - size_t sized integer formats (64 bit on AArch64)
|
||||
*
|
||||
* The following padding specifiers are supported by this print
|
||||
* %0NN - Left-pad the number with 0s (NN is a decimal number)
|
||||
*
|
||||
* The print exits on all other formats specifiers other than valid
|
||||
* combinations of the above specifiers.
|
||||
*******************************************************************/
|
||||
int vprintf(const char *fmt, va_list args)
|
||||
{
|
||||
int l_count;
|
||||
long long int num;
|
||||
unsigned long long int unum;
|
||||
char *str;
|
||||
char padc = '\0'; /* Padding character */
|
||||
int padn; /* Number of characters to pad */
|
||||
int count = 0; /* Number of printed characters */
|
||||
|
||||
while (*fmt != '\0') {
|
||||
l_count = 0;
|
||||
padn = 0;
|
||||
|
||||
if (*fmt == '%') {
|
||||
fmt++;
|
||||
/* Check the format specifier */
|
||||
loop:
|
||||
switch (*fmt) {
|
||||
case '%':
|
||||
(void)putchar('%');
|
||||
break;
|
||||
case 'i': /* Fall through to next one */
|
||||
case 'd':
|
||||
num = get_num_va_args(args, l_count);
|
||||
if (num < 0) {
|
||||
(void)putchar('-');
|
||||
unum = (unsigned long long int)-num;
|
||||
padn--;
|
||||
} else
|
||||
unum = (unsigned long long int)num;
|
||||
|
||||
count += unsigned_num_print(unum, 10,
|
||||
padc, padn);
|
||||
break;
|
||||
case 's':
|
||||
str = va_arg(args, char *);
|
||||
count += string_print(str);
|
||||
break;
|
||||
case 'p':
|
||||
unum = (uintptr_t)va_arg(args, void *);
|
||||
if (unum > 0U) {
|
||||
count += string_print("0x");
|
||||
padn -= 2;
|
||||
}
|
||||
|
||||
count += unsigned_num_print(unum, 16,
|
||||
padc, padn);
|
||||
break;
|
||||
case 'x':
|
||||
unum = get_unum_va_args(args, l_count);
|
||||
count += unsigned_num_print(unum, 16,
|
||||
padc, padn);
|
||||
break;
|
||||
case 'z':
|
||||
if (sizeof(size_t) == 8U)
|
||||
l_count = 2;
|
||||
|
||||
fmt++;
|
||||
goto loop;
|
||||
case 'l':
|
||||
l_count++;
|
||||
fmt++;
|
||||
goto loop;
|
||||
case 'u':
|
||||
unum = get_unum_va_args(args, l_count);
|
||||
count += unsigned_num_print(unum, 10,
|
||||
padc, padn);
|
||||
break;
|
||||
case '0':
|
||||
padc = '0';
|
||||
padn = 0;
|
||||
fmt++;
|
||||
|
||||
for (;;) {
|
||||
char ch = *fmt;
|
||||
if ((ch < '0') || (ch > '9')) {
|
||||
goto loop;
|
||||
}
|
||||
padn = (padn * 10) + (ch - '0');
|
||||
fmt++;
|
||||
}
|
||||
assert(0); /* Unreachable */
|
||||
default:
|
||||
/* Exit on any other format specifier */
|
||||
return -1;
|
||||
}
|
||||
fmt++;
|
||||
continue;
|
||||
}
|
||||
(void)putchar(*fmt);
|
||||
fmt++;
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int printf(const char *fmt, ...)
|
||||
{
|
||||
int count;
|
||||
va_list va;
|
||||
|
||||
va_start(va, fmt);
|
||||
count = vprintf(fmt, va);
|
||||
va_end(va);
|
||||
|
||||
return count;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int __putchar(int c)
|
||||
{
|
||||
return c;
|
||||
}
|
||||
|
||||
int putchar(int c) __attribute__((weak,alias("__putchar")));
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int puts(const char *s)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
while (*s != '\0') {
|
||||
if (putchar(*s) == EOF)
|
||||
return EOF;
|
||||
s++;
|
||||
count++;
|
||||
}
|
||||
|
||||
if (putchar('\n') == EOF)
|
||||
return EOF;
|
||||
|
||||
return count + 1;
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define get_num_va_args(_args, _lcount) \
|
||||
(((_lcount) > 1) ? va_arg(_args, long long int) : \
|
||||
(((_lcount) == 1) ? va_arg(_args, long int) : \
|
||||
va_arg(_args, int)))
|
||||
|
||||
#define get_unum_va_args(_args, _lcount) \
|
||||
(((_lcount) > 1) ? va_arg(_args, unsigned long long int) : \
|
||||
(((_lcount) == 1) ? va_arg(_args, unsigned long int) : \
|
||||
va_arg(_args, unsigned int)))
|
||||
|
||||
#define CHECK_AND_PUT_CHAR(buf, size, chars_printed, ch) \
|
||||
do { \
|
||||
if ((chars_printed) < (size)) { \
|
||||
*(buf) = (ch); \
|
||||
(buf)++; \
|
||||
} \
|
||||
(chars_printed)++; \
|
||||
} while (false)
|
||||
|
||||
static void string_print(char **s, size_t n, size_t *chars_printed,
|
||||
const char *str)
|
||||
{
|
||||
while (*str != '\0') {
|
||||
CHECK_AND_PUT_CHAR(*s, n, *chars_printed, *str);
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
static void unsigned_num_print(char **s, size_t n, size_t *chars_printed,
|
||||
unsigned long long int unum,
|
||||
unsigned int radix, char padc, int padn,
|
||||
bool capitalise)
|
||||
{
|
||||
/* Just need enough space to store 64 bit decimal integer */
|
||||
char num_buf[20];
|
||||
int i = 0;
|
||||
int width;
|
||||
unsigned int rem;
|
||||
char ascii_a = capitalise ? 'A' : 'a';
|
||||
|
||||
/* num_buf is only large enough for radix >= 10 */
|
||||
if (radix < 10) {
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
rem = unum % radix;
|
||||
if (rem < 10U) {
|
||||
num_buf[i] = '0' + rem;
|
||||
} else {
|
||||
num_buf[i] = ascii_a + (rem - 10U);
|
||||
}
|
||||
i++;
|
||||
unum /= radix;
|
||||
} while (unum > 0U);
|
||||
|
||||
width = i;
|
||||
for (i = padn - width; i > 0; i--) {
|
||||
CHECK_AND_PUT_CHAR(*s, n, *chars_printed, padc);
|
||||
}
|
||||
for (i = width; i > 0; i--) {
|
||||
CHECK_AND_PUT_CHAR(*s, n, *chars_printed, num_buf[i - 1]);
|
||||
}
|
||||
for (i = width + padn; i < 0; i++) {
|
||||
CHECK_AND_PUT_CHAR(*s, n, *chars_printed, padc);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* Reduced vsnprintf to be used for Trusted firmware.
|
||||
* The following type specifiers are supported:
|
||||
*
|
||||
* %x (or %X) - hexadecimal format
|
||||
* %d or %i - signed decimal format
|
||||
* %s - string format
|
||||
* %u - unsigned decimal format
|
||||
* %p - pointer format
|
||||
*
|
||||
* The following length specifiers are supported by this print
|
||||
* %l - long int
|
||||
* %ll - long long int
|
||||
* %z - size_t sized integer formats
|
||||
*
|
||||
* The following padding specifiers are supported by this print
|
||||
* %0NN - Left-pad the number with 0s (NN is a decimal number)
|
||||
* %NN - Left-pad the number or string with spaces (NN is a decimal number)
|
||||
* %-NN - Right-pad the number or string with spaces (NN is a decimal number)
|
||||
*
|
||||
* The function panics on all other formats specifiers.
|
||||
*
|
||||
* It returns the number of characters that would be written if the
|
||||
* buffer was big enough. If it returns a value lower than n, the
|
||||
* whole string has been written.
|
||||
*******************************************************************/
|
||||
int vsnprintf(char *s, size_t n, const char *fmt, va_list args)
|
||||
{
|
||||
int num;
|
||||
unsigned long long int unum;
|
||||
char *str;
|
||||
char padc; /* Padding character */
|
||||
int padn; /* Number of characters to pad */
|
||||
bool left;
|
||||
bool capitalise;
|
||||
size_t chars_printed = 0U;
|
||||
unsigned int l_count;
|
||||
|
||||
if (n == 0U) {
|
||||
/* There isn't space for anything. */
|
||||
} else if (n == 1U) {
|
||||
/* Buffer is too small to actually write anything else. */
|
||||
*s = '\0';
|
||||
n = 0U;
|
||||
} else {
|
||||
/* Reserve space for the terminator character. */
|
||||
n--;
|
||||
}
|
||||
|
||||
while (*fmt != '\0') {
|
||||
left = false;
|
||||
padc ='\0';
|
||||
padn = 0;
|
||||
capitalise = false;
|
||||
l_count = 0;
|
||||
|
||||
if (*fmt == '%') {
|
||||
fmt++;
|
||||
/* Check the format specifier. */
|
||||
loop:
|
||||
switch (*fmt) {
|
||||
case '%':
|
||||
CHECK_AND_PUT_CHAR(s, n, chars_printed, '%');
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
padc = (*fmt == '0') ? '0' : ' ';
|
||||
for (padn = 0; *fmt >= '0' && *fmt <= '9'; fmt++) {
|
||||
padn = (padn * 10) + (*fmt - '0');
|
||||
}
|
||||
if (left) {
|
||||
padn = -padn;
|
||||
}
|
||||
goto loop;
|
||||
case '-':
|
||||
left = true;
|
||||
fmt++;
|
||||
goto loop;
|
||||
|
||||
case 'i':
|
||||
case 'd':
|
||||
num = get_num_va_args(args, l_count);
|
||||
|
||||
if (num < 0) {
|
||||
CHECK_AND_PUT_CHAR(s, n, chars_printed,
|
||||
'-');
|
||||
unum = (unsigned int)-num;
|
||||
} else {
|
||||
unum = (unsigned int)num;
|
||||
}
|
||||
|
||||
unsigned_num_print(&s, n, &chars_printed,
|
||||
unum, 10, padc, padn, false);
|
||||
break;
|
||||
case 's':
|
||||
str = va_arg(args, char *);
|
||||
string_print(&s, n, &chars_printed, str);
|
||||
break;
|
||||
case 'u':
|
||||
unum = get_unum_va_args(args, l_count);
|
||||
unsigned_num_print(&s, n, &chars_printed,
|
||||
unum, 10, padc, padn, false);
|
||||
break;
|
||||
case 'z':
|
||||
l_count = 1;
|
||||
fmt++;
|
||||
goto loop;
|
||||
case 'l':
|
||||
l_count++;
|
||||
fmt++;
|
||||
goto loop;
|
||||
case 'p':
|
||||
unum = (uintptr_t)va_arg(args, void *);
|
||||
if (unum > 0U) {
|
||||
string_print(&s, n, &chars_printed, "0x");
|
||||
padn -= 2;
|
||||
}
|
||||
unsigned_num_print(&s, n, &chars_printed,
|
||||
unum, 16, padc, padn, false);
|
||||
break;
|
||||
case 'X':
|
||||
capitalise = true;
|
||||
case 'x':
|
||||
unum = get_unum_va_args(args, l_count);
|
||||
unsigned_num_print(&s, n, &chars_printed,
|
||||
unum, 16, padc, padn,
|
||||
capitalise);
|
||||
break;
|
||||
|
||||
default:
|
||||
CHECK_AND_PUT_CHAR(s, n, chars_printed, '%');
|
||||
CHECK_AND_PUT_CHAR(s, n, chars_printed, *fmt);
|
||||
}
|
||||
fmt++;
|
||||
continue;
|
||||
}
|
||||
|
||||
CHECK_AND_PUT_CHAR(s, n, chars_printed, *fmt);
|
||||
|
||||
fmt++;
|
||||
}
|
||||
|
||||
if (n > 0U) {
|
||||
*s = '\0';
|
||||
}
|
||||
|
||||
return (int)chars_printed;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* Reduced snprintf to be used for Trusted firmware.
|
||||
* The following type specifiers are supported:
|
||||
*
|
||||
* %x (or %X) - hexadecimal format
|
||||
* %d or %i - signed decimal format
|
||||
* %s - string format
|
||||
* %u - unsigned decimal format
|
||||
* %p - pointer format
|
||||
*
|
||||
* The following padding specifiers are supported by this print
|
||||
* %0NN - Left-pad the number with 0s (NN is a decimal number)
|
||||
* %NN - Left-pad the number or string with spaces (NN is a decimal number)
|
||||
* %-NN - Right-pad the number or string with spaces (NN is a decimal number)
|
||||
*
|
||||
* The function panics on all other formats specifiers.
|
||||
*
|
||||
* It returns the number of characters that would be written if the
|
||||
* buffer was big enough. If it returns a value lower than n, the
|
||||
* whole string has been written.
|
||||
*******************************************************************/
|
||||
int snprintf(char *s, size_t n, const char *fmt, ...)
|
||||
{
|
||||
int count;
|
||||
va_list all_args;
|
||||
|
||||
va_start(all_args, fmt);
|
||||
count = vsnprintf(s, n, fmt, all_args);
|
||||
va_end(all_args);
|
||||
|
||||
return count;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions copyright (c) 2018, ARM Limited and Contributors.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
char *
|
||||
strchr(const char *p, int ch)
|
||||
{
|
||||
char c;
|
||||
|
||||
c = ch;
|
||||
for (;; ++p) {
|
||||
if (*p == c)
|
||||
return ((char *)p);
|
||||
if (*p == '\0')
|
||||
return (NULL);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Chris Torek.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions copyright (c) 2018, ARM Limited and Contributors.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Compare strings.
|
||||
*/
|
||||
int
|
||||
strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
while (*s1 == *s2++)
|
||||
if (*s1++ == '\0')
|
||||
return (0);
|
||||
return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1));
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/* $OpenBSD: strlcat.c,v 1.15 2015/03/02 21:41:08 millert Exp $ */
|
||||
|
||||
/*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Appends src to string dst of size dsize (unlike strncat, dsize is the
|
||||
* full size of dst, not space left). At most dsize-1 characters
|
||||
* will be copied. Always NUL terminates (unless dsize <= strlen(dst)).
|
||||
* Returns strlen(src) + MIN(dsize, strlen(initial dst)).
|
||||
* If retval >= dsize, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcat(char * dst, const char * src, size_t dsize)
|
||||
{
|
||||
const char *odst = dst;
|
||||
const char *osrc = src;
|
||||
size_t n = dsize;
|
||||
size_t dlen;
|
||||
|
||||
/* Find the end of dst and adjust bytes left but don't go past end. */
|
||||
while (n-- != 0 && *dst != '\0')
|
||||
dst++;
|
||||
dlen = dst - odst;
|
||||
n = dsize - dlen;
|
||||
|
||||
if (n-- == 0)
|
||||
return(dlen + strlen(src));
|
||||
while (*src != '\0') {
|
||||
if (n != 0) {
|
||||
*dst++ = *src;
|
||||
n--;
|
||||
}
|
||||
src++;
|
||||
}
|
||||
*dst = '\0';
|
||||
|
||||
return(dlen + (src - osrc)); /* count does not include NUL */
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/* $OpenBSD: strlcpy.c,v 1.12 2015/01/15 03:54:12 millert Exp $ */
|
||||
|
||||
/*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Copy string src to buffer dst of size dsize. At most dsize-1
|
||||
* chars will be copied. Always NUL terminates (unless dsize == 0).
|
||||
* Returns strlen(src); if retval >= dsize, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcpy(char * dst, const char * src, size_t dsize)
|
||||
{
|
||||
const char *osrc = src;
|
||||
size_t nleft = dsize;
|
||||
|
||||
/* Copy as many bytes as will fit. */
|
||||
if (nleft != 0) {
|
||||
while (--nleft != 0) {
|
||||
if ((*dst++ = *src++) == '\0')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src. */
|
||||
if (nleft == 0) {
|
||||
if (dsize != 0)
|
||||
*dst = '\0'; /* NUL-terminate dst */
|
||||
while (*src++)
|
||||
;
|
||||
}
|
||||
|
||||
return(src - osrc - 1); /* count does not include NUL */
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
size_t strlen(const char *s)
|
||||
{
|
||||
const char *cursor = s;
|
||||
|
||||
while (*cursor)
|
||||
cursor++;
|
||||
|
||||
return cursor - s;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions copyright (c) 2018, ARM Limited and Contributors.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
strncmp(const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
|
||||
if (n == 0)
|
||||
return (0);
|
||||
do {
|
||||
if (*s1 != *s2++)
|
||||
return (*(const unsigned char *)s1 -
|
||||
*(const unsigned char *)(s2 - 1));
|
||||
if (*s1++ == '\0')
|
||||
break;
|
||||
} while (--n != 0);
|
||||
return (0);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
*
|
||||
* Copyright (c) 2009 David Schultz <das@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions copyright (c) 2018, ARM Limited and Contributors.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
size_t
|
||||
strnlen(const char *s, size_t maxlen)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
for (len = 0; len < maxlen; len++, s++) {
|
||||
if (!*s)
|
||||
break;
|
||||
}
|
||||
return (len);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
char *
|
||||
strrchr(const char *p, int ch)
|
||||
{
|
||||
char *save;
|
||||
char c;
|
||||
|
||||
c = ch;
|
||||
for (save = NULL;; ++p) {
|
||||
if (*p == c)
|
||||
save = (char *)p;
|
||||
if (*p == '\0')
|
||||
return (save);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright (c) 1998 Softweyr LLC. All rights reserved.
|
||||
*
|
||||
* strtok_r, from Berkeley strtok
|
||||
* Oct 13, 1998 by Wes Peters <wes@softweyr.com>
|
||||
*
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notices, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notices, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTWEYR LLC, THE
|
||||
* REGENTS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
char *
|
||||
strtok_r(char *s, const char *delim, char **last)
|
||||
{
|
||||
char *spanp, *tok;
|
||||
int c, sc;
|
||||
|
||||
if (s == NULL && (s = *last) == NULL)
|
||||
return (NULL);
|
||||
|
||||
/*
|
||||
* Skip (span) leading delimiters (s += strspn(s, delim), sort of).
|
||||
*/
|
||||
cont:
|
||||
c = *s++;
|
||||
for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
|
||||
if (c == sc)
|
||||
goto cont;
|
||||
}
|
||||
|
||||
if (c == 0) { /* no non-delimiter characters */
|
||||
*last = NULL;
|
||||
return (NULL);
|
||||
}
|
||||
tok = s - 1;
|
||||
|
||||
/*
|
||||
* Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
|
||||
* Note that delim must have one NUL; we stop if we see that, too.
|
||||
*/
|
||||
for (;;) {
|
||||
c = *s++;
|
||||
spanp = (char *)delim;
|
||||
do {
|
||||
if ((sc = *spanp++) == c) {
|
||||
if (c == 0)
|
||||
s = NULL;
|
||||
else
|
||||
s[-1] = '\0';
|
||||
*last = s;
|
||||
return (tok);
|
||||
}
|
||||
} while (sc != 0);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2011 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
* Portions of this software were developed by David Chisnall
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* Convert a string to a long integer.
|
||||
*
|
||||
* Assumes that the upper and lower case
|
||||
* alphabets and digits are each contiguous.
|
||||
*/
|
||||
long strtol(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
const char *s;
|
||||
unsigned long acc;
|
||||
char c;
|
||||
unsigned long cutoff;
|
||||
int neg, any, cutlim;
|
||||
|
||||
/*
|
||||
* Skip white space and pick up leading +/- sign if any.
|
||||
* If base is 0, allow 0x for hex and 0 for octal, else
|
||||
* assume decimal; if base is already 16, allow 0x.
|
||||
*/
|
||||
s = nptr;
|
||||
do {
|
||||
c = *s++;
|
||||
} while (isspace((unsigned char)c));
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else {
|
||||
neg = 0;
|
||||
if (c == '+')
|
||||
c = *s++;
|
||||
}
|
||||
if ((base == 0 || base == 16) &&
|
||||
c == '0' && (*s == 'x' || *s == 'X') &&
|
||||
((s[1] >= '0' && s[1] <= '9') ||
|
||||
(s[1] >= 'A' && s[1] <= 'F') ||
|
||||
(s[1] >= 'a' && s[1] <= 'f'))) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '0' ? 8 : 10;
|
||||
acc = any = 0;
|
||||
|
||||
/*
|
||||
* Compute the cutoff value between legal numbers and illegal
|
||||
* numbers. That is the largest legal value, divided by the
|
||||
* base. An input number that is greater than this value, if
|
||||
* followed by a legal input character, is too big. One that
|
||||
* is equal to this value may be valid or not; the limit
|
||||
* between valid and invalid numbers is then based on the last
|
||||
* digit. For instance, if the range for longs is
|
||||
* [-2147483648..2147483647] and the input base is 10,
|
||||
* cutoff will be set to 214748364 and cutlim to either
|
||||
* 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
|
||||
* a value > 214748364, or equal but the next digit is > 7 (or 8),
|
||||
* the number is too big, and we will return a range error.
|
||||
*
|
||||
* Set 'any' if any `digits' consumed; make it negative to indicate
|
||||
* overflow.
|
||||
*/
|
||||
cutoff = neg ? (unsigned long)-(LONG_MIN + LONG_MAX) + LONG_MAX
|
||||
: LONG_MAX;
|
||||
cutlim = cutoff % base;
|
||||
cutoff /= base;
|
||||
for ( ; ; c = *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 || acc > cutoff || (acc == cutoff && c > cutlim))
|
||||
any = -1;
|
||||
else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
if (any < 0) {
|
||||
acc = neg ? LONG_MIN : LONG_MAX;
|
||||
} else if (neg)
|
||||
acc = -acc;
|
||||
if (endptr != NULL)
|
||||
*endptr = (char *)(any ? s - 1 : nptr);
|
||||
return (acc);
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2011 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
* Portions of this software were developed by David Chisnall
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* Convert a string to a long long integer.
|
||||
*
|
||||
* Assumes that the upper and lower case
|
||||
* alphabets and digits are each contiguous.
|
||||
*/
|
||||
long long strtoll(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
const char *s;
|
||||
unsigned long long acc;
|
||||
char c;
|
||||
unsigned long long cutoff;
|
||||
int neg, any, cutlim;
|
||||
|
||||
/*
|
||||
* Skip white space and pick up leading +/- sign if any.
|
||||
* If base is 0, allow 0x for hex and 0 for octal, else
|
||||
* assume decimal; if base is already 16, allow 0x.
|
||||
*/
|
||||
s = nptr;
|
||||
do {
|
||||
c = *s++;
|
||||
} while (isspace((unsigned char)c));
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else {
|
||||
neg = 0;
|
||||
if (c == '+')
|
||||
c = *s++;
|
||||
}
|
||||
if ((base == 0 || base == 16) &&
|
||||
c == '0' && (*s == 'x' || *s == 'X') &&
|
||||
((s[1] >= '0' && s[1] <= '9') ||
|
||||
(s[1] >= 'A' && s[1] <= 'F') ||
|
||||
(s[1] >= 'a' && s[1] <= 'f'))) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '0' ? 8 : 10;
|
||||
acc = any = 0;
|
||||
|
||||
/*
|
||||
* Compute the cutoff value between legal numbers and illegal
|
||||
* numbers. That is the largest legal value, divided by the
|
||||
* base. An input number that is greater than this value, if
|
||||
* followed by a legal input character, is too big. One that
|
||||
* is equal to this value may be valid or not; the limit
|
||||
* between valid and invalid numbers is then based on the last
|
||||
* digit. For instance, if the range for quads is
|
||||
* [-9223372036854775808..9223372036854775807] and the input base
|
||||
* is 10, cutoff will be set to 922337203685477580 and cutlim to
|
||||
* either 7 (neg==0) or 8 (neg==1), meaning that if we have
|
||||
* accumulated a value > 922337203685477580, or equal but the
|
||||
* next digit is > 7 (or 8), the number is too big, and we will
|
||||
* return a range error.
|
||||
*
|
||||
* Set 'any' if any `digits' consumed; make it negative to indicate
|
||||
* overflow.
|
||||
*/
|
||||
cutoff = neg ? (unsigned long long)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX
|
||||
: LLONG_MAX;
|
||||
cutlim = cutoff % base;
|
||||
cutoff /= base;
|
||||
for ( ; ; c = *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 || acc > cutoff || (acc == cutoff && c > cutlim))
|
||||
any = -1;
|
||||
else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
if (any < 0) {
|
||||
acc = neg ? LLONG_MIN : LLONG_MAX;
|
||||
} else if (neg)
|
||||
acc = -acc;
|
||||
if (endptr != NULL)
|
||||
*endptr = (char *)(any ? s - 1 : nptr);
|
||||
return (acc);
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2011 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
* Portions of this software were developed by David Chisnall
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* Convert a string to an unsigned long integer.
|
||||
*
|
||||
* Assumes that the upper and lower case
|
||||
* alphabets and digits are each contiguous.
|
||||
*/
|
||||
unsigned long strtoul(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
const char *s;
|
||||
unsigned long acc;
|
||||
char c;
|
||||
unsigned long cutoff;
|
||||
int neg, any, cutlim;
|
||||
|
||||
/*
|
||||
* See strtol for comments as to the logic used.
|
||||
*/
|
||||
s = nptr;
|
||||
do {
|
||||
c = *s++;
|
||||
} while (isspace((unsigned char)c));
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else {
|
||||
neg = 0;
|
||||
if (c == '+')
|
||||
c = *s++;
|
||||
}
|
||||
if ((base == 0 || base == 16) &&
|
||||
c == '0' && (*s == 'x' || *s == 'X') &&
|
||||
((s[1] >= '0' && s[1] <= '9') ||
|
||||
(s[1] >= 'A' && s[1] <= 'F') ||
|
||||
(s[1] >= 'a' && s[1] <= 'f'))) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '0' ? 8 : 10;
|
||||
acc = any = 0;
|
||||
|
||||
cutoff = ULONG_MAX / base;
|
||||
cutlim = ULONG_MAX % base;
|
||||
for ( ; ; c = *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 || acc > cutoff || (acc == cutoff && c > cutlim))
|
||||
any = -1;
|
||||
else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
if (any < 0) {
|
||||
acc = ULONG_MAX;
|
||||
} else if (neg)
|
||||
acc = -acc;
|
||||
if (endptr != NULL)
|
||||
*endptr = (char *)(any ? s - 1 : nptr);
|
||||
return (acc);
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2011 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
* Portions of this software were developed by David Chisnall
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* Convert a string to an unsigned long long integer.
|
||||
*
|
||||
* Assumes that the upper and lower case
|
||||
* alphabets and digits are each contiguous.
|
||||
*/
|
||||
unsigned long long strtoull(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
const char *s;
|
||||
unsigned long long acc;
|
||||
char c;
|
||||
unsigned long long cutoff;
|
||||
int neg, any, cutlim;
|
||||
|
||||
/*
|
||||
* See strtoq for comments as to the logic used.
|
||||
*/
|
||||
s = nptr;
|
||||
do {
|
||||
c = *s++;
|
||||
} while (isspace((unsigned char)c));
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else {
|
||||
neg = 0;
|
||||
if (c == '+')
|
||||
c = *s++;
|
||||
}
|
||||
if ((base == 0 || base == 16) &&
|
||||
c == '0' && (*s == 'x' || *s == 'X') &&
|
||||
((s[1] >= '0' && s[1] <= '9') ||
|
||||
(s[1] >= 'A' && s[1] <= 'F') ||
|
||||
(s[1] >= 'a' && s[1] <= 'f'))) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '0' ? 8 : 10;
|
||||
acc = any = 0;
|
||||
|
||||
cutoff = ULLONG_MAX / base;
|
||||
cutlim = ULLONG_MAX % base;
|
||||
for ( ; ; c = *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 || acc > cutoff || (acc == cutoff && c > cutlim))
|
||||
any = -1;
|
||||
else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
if (any < 0) {
|
||||
acc = ULLONG_MAX;
|
||||
} else if (neg)
|
||||
acc = -acc;
|
||||
if (endptr != NULL)
|
||||
*endptr = (char *)(any ? s - 1 : nptr);
|
||||
return (acc);
|
||||
}
|
||||
Reference in New Issue
Block a user