GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)

This commit is contained in:
lai
2026-09-06 03:52:57 +08:00
commit b1928b41c0
21813 changed files with 4413081 additions and 0 deletions
@@ -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);
}