From d6d9316269f5ab77251cfafbfeeb341bbcbbaac7 Mon Sep 17 00:00:00 2001 From: a Date: Sun, 6 Jul 2025 23:49:35 -0400 Subject: [PATCH] git subrepo pull (merge) lib/n64-libc subrepo: subdir: "lib/n64-libc" merged: "d9eaca7e" upstream: origin: "https://gitlab.com/mpharoah/n64-libc" branch: "main" commit: "ef942de8" git-subrepo: version: "0.4.9" origin: "https://github.com/ingydotnet/git-subrepo" commit: "4f60dd7" --- lib/n64-libc/.gitrepo | 2 +- lib/n64-libc/n64-stdlib.c | 162 ++++++++++++++++++++++++++++++++++++++ lib/n64-libc/n64-stdlib.h | 30 +++++++ 3 files changed, 193 insertions(+), 1 deletion(-) diff --git a/lib/n64-libc/.gitrepo b/lib/n64-libc/.gitrepo index 59b5db03..34623334 100644 --- a/lib/n64-libc/.gitrepo +++ b/lib/n64-libc/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://gitlab.com/mpharoah/n64-libc branch = main - commit = 70270d60f9b13d3cd896eaa8aa0a043992a823fd + commit = ef942de8e17baf476212e9e07932dfc63e736112 parent = 4c89989f6f2ef03e71fc89e33e4e94fa067fda04 method = merge cmdver = 0.4.9 diff --git a/lib/n64-libc/n64-stdlib.c b/lib/n64-libc/n64-stdlib.c index 448f597a..654cea00 100644 --- a/lib/n64-libc/n64-stdlib.c +++ b/lib/n64-libc/n64-stdlib.c @@ -1,6 +1,9 @@ #include "n64-stdlib.h" +#include "n64-stdckdint.h" +#include "n64-stdbool.h" #include "n64-stddef.h" +#include "n64-ctype.h" #include "n64-util.h" typedef void(*memswp_func_t)( void*, void*, unsigned int ); @@ -103,6 +106,165 @@ void *n64_bsearch( const void *key, const void *ptr, unsigned int count, unsigne return NULL; } +int n64_atoi( const char *str ) { + int x = 0; + while( n64_isspace( *str ) ) str++; + const char sign = *str; + if( sign == '+' || sign == '-' ) str++; + while( n64_isdigit( *str ) ) { + x *= 10; + x += (int)(*str++ - '0'); + } + return (sign == '-') ? -x : x; +} + +long long n64_atoll( const char *str ) { + long long x = 0ll; + while( n64_isspace( *str ) ) str++; + const char sign = *str; + if( sign == '+' || sign == '-' ) str++; + while( n64_isdigit( *str ) ) { + x *= 10ll; + x += (long long)(*str++ - '0'); + } + return (sign == '-') ? -x : x; +} + +#define N64_STRTO_COMMON \ + n64_bool overflow = false;\ + n64_bool negative = false;\ +\ + while( n64_isspace( *str ) ) str++;\ + if( *str == '+' ) {\ + str++;\ + } else if( *str == '-' ) {\ + negative = true;\ + str++;\ + }\ +\ + if( *str == '0' ) {\ + str++;\ + if( *str == 'x' || *str == 'X' ) {\ + if( base == 0 ) {\ + base = 16;\ + str++;\ + } else if( base == 16 ) {\ + str++;\ + } else if( base < 34 ) {\ + if( str_end ) *str_end = (char*)str;\ + return 0;\ + }\ + } else if( base == 0 ) {\ + base = 8;\ + }\ + }\ +\ + if( base == 0 ) {\ + base = 10;\ + }\ +\ + while( true ) {\ + const char c = *str;\ +\ + if( n64_isdigit( c ) ) {\ + digit = (int)(c - '0');\ + } else if( n64_islower( c ) ) {\ + digit = 10 + (int)(c - 'a');\ + } else if( n64_isupper( c ) ) {\ + digit = 10 + (int)(c - 'A');\ + } else break;\ +\ + if( digit >= base ) break;\ +\ + if( overflow ) {\ + str++;\ + continue;\ + }\ +\ + if( n64_ckd_mul( &x, x, base ) ) {\ + overflow = true;\ + str++;\ + continue;\ + }\ +\ + overflow = n64_ckd_add( &x, x, digit );\ + str++;\ + } + +int n64_strtoi( const char *str, char **str_end, int base ) { + if( base < 0 || base > 36 ) { + if( str_end ) *str_end = (char*)str; + return 0; + } + + int x = 0; + int digit = 0; + + N64_STRTO_COMMON + + if( str_end ) *str_end = (char*)str; + if( overflow ) return negative ? -0x80000000 : 0x7fffffff; + return negative ? -x : x; +} + +__attribute__((always_inline)) +static inline unsigned int n64_strtoui_impl( const char *str, char **str_end, unsigned int base ) { + unsigned int x = 0; + unsigned int digit = 0; + + N64_STRTO_COMMON + + if( str_end ) *str_end = (char*)str; + if( overflow ) return 0x7fffffffu; + return negative ? -x : x; +} + +unsigned int n64_strtoui( const char *str, char **str_end, int base ) { + if( base < 0 || base > 36 ) { + if( str_end ) *str_end = (char*)str; + return 0u; + } + + return n64_strtoui_impl( str, str_end, (unsigned int)base ); +} + +long long n64_strtoll( const char *str, char **str_end, int base ) { + if( base < 0 || base > 36 ) { + if( str_end ) *str_end = (char*)str; + return 0; + } + + long long x = 0ll; + int digit = 0; + + N64_STRTO_COMMON + + if( str_end ) *str_end = (char*)str; + if( overflow ) return negative ? -0x8000000000000000ll : 0x7fffffffffffffffll; + return negative ? -x : x; +} + +__attribute__((always_inline)) +static inline unsigned long long n64_strtoull_impl( const char *str, char **str_end, unsigned int base ) { + unsigned long long x = 0; + unsigned int digit = 0; + + N64_STRTO_COMMON + + if( str_end ) *str_end = (char*)str; + if( overflow ) return 0x7fffffffffffffffu; + return negative ? -x : x; +} + +unsigned long long n64_strtoull( const char *str, char **str_end, int base ) { + if( base < 0 || base > 36 ) { + if( str_end ) *str_end = (char*)str; + return 0u; + } + + return n64_strtoull_impl( str, str_end, (unsigned int)base ); +} + static unsigned int g_randi = 24u; static unsigned int g_randv[32] = { 0xdb48f936u, 0x14898454u, 0x37ffd106u, 0xb58bff9cu, 0x59e17104u, 0xcf918a49u, 0x09378c83u, 0x52c7a471u, diff --git a/lib/n64-libc/n64-stdlib.h b/lib/n64-libc/n64-stdlib.h index 3a8c4a35..39e8d451 100644 --- a/lib/n64-libc/n64-stdlib.h +++ b/lib/n64-libc/n64-stdlib.h @@ -27,6 +27,36 @@ void n64_qsort( void *ptr, unsigned int count, unsigned int size, int(*comp)(con __attribute__((nonnull(2, 5), alloc_align(4), alloc_size(3, 4), warn_unused_result)) void *n64_bsearch( const void *key, const void *ptr, unsigned int count, unsigned int size, int(*comp)(const void*, const void*) ); +__attribute__((const, warn_unused_result, always_inline)) +static inline int n64_abs( int n ) { + return (n < 0) ? -n : n; +} + +__attribute__((const, warn_unused_result, always_inline)) +static inline long long n64_llabs( long long n ) { + return (n < 0ll) ? -n : n; +} + +__attribute__((pure, nonnull(1), warn_unused_result)) +int n64_atoi( const char *str ); + +__attribute__((pure, nonnull(1), warn_unused_result)) +long long n64_atoll( const char *str ); + +// Extension. Same as stroll, but returns an 32-bit int +__attribute__((pure, nonnull(1), access(read_write, 2))) +int n64_strtoi( const char *str, char **str_end, int base ); + +// Extension. Same as stroull, but returns an 32-bit unsigned int +__attribute__((pure, nonnull(1), access(read_write, 2))) +unsigned int n64_strtoui( const char *str, char **str_end, int base ); + +__attribute__((pure, nonnull(1), access(read_write, 2))) +long long n64_strtoll( const char *str, char **str_end, int base ); + +__attribute__((pure, nonnull(1), access(read_write, 2))) +unsigned long long n64_strtoull( const char *str, char **str_end, int base ); + __attribute__((flatten)) void n64_srand( unsigned int seed );