Copied Sortix' libc string implementation

This commit is contained in:
Thomas Oltmann 2025-03-16 00:38:26 +01:00
parent 3c732f27db
commit 510a18e123
49 changed files with 2051 additions and 10 deletions

View file

@ -1,14 +1,164 @@
#pragma once
/*
* Copyright (c) 2011, 2012, 2013, 2014, 2017, 2024 Jonas 'Sortie' Termansen.
*
* 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.
*
* string.h
* String operations.
*/
#ifndef _INCLUDE_STRING_H
#define _INCLUDE_STRING_H
#include <sys/cdefs.h>
#if __USE_SORTIX || __USE_POSIX
#include <sys/__/types.h>
#endif
#ifndef NULL
#define __need_NULL
#include <stddef.h>
#endif
char *strchr(const char *s, int c);
int strcmp(const char *s1, const char *s2);
char *strcpy(char *restrict d, const char *restrict s);
size_t strlen(const char *s);
size_t strspn(const char *s, const char *a);
char *strpbrk(const char *s, const char *a);
int strcoll(const char *s1, const char *s2);
#ifndef __size_t_defined
#define __size_t_defined
#define __need_size_t
#include <stddef.h>
#endif
void *memcpy(void *restrict dest, const void *restrict src, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
#if __USE_SORTIX || 2008 <= __USE_POSIX
#ifndef __locale_t_defined
#define __locale_t_defined
/* TODO: figure out what this does and typedef it properly. This is just a
temporary assignment. */
typedef int __locale_t;
typedef __locale_t locale_t;
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
void* memchr(const void*, int, size_t);
int memcmp(const void*, const void*, size_t);
void* memcpy(void* __restrict, const void* __restrict, size_t);
void* memmove(void*, const void*, size_t);
void* memset(void*, int, size_t);
char* strcat(char* __restrict, const char* __restrict);
char* strchr(const char*, int);
int strcmp(const char*, const char*);
int strcoll(const char*, const char*);
char* strcpy(char* __restrict, const char* __restrict);
size_t strcspn(const char*, const char*);
char* strerror(int errnum);
size_t strlen(const char*);
char* strncat(char* __restrict, const char* __restrict, size_t);
int strncmp(const char*, const char*, size_t);
char* strncpy(char* __restrict, const char* __restrict, size_t);
char* strpbrk(const char*, const char*);
char* strrchr(const char*, int);
size_t strspn(const char*, const char*);
char* strstr(const char*, const char*);
char* strtok(char* __restrict, const char* __restrict);
size_t strxfrm(char* __restrict, const char* __restrict, size_t);
/* Functions from early POSIX. */
#if __USE_SORTIX || __USE_POSIX
int strcasecmp(const char* a, const char* b);
int strncasecmp(const char* a, const char* b, size_t n);
#endif
/* Functions from early XOPEN. */
#if __USE_SORTIX || __USE_XOPEN
void* memccpy(void* __restrict, const void* __restrict, int, size_t);
int ffs(int);
#endif
/* Functions from XOPEN 420 gone into POSIX 2008. */
#if __USE_SORTIX || 420 <= __USE_XOPEN || 200809L <= __USE_POSIX
char* strdup(const char*);
#endif
/* Functions from POSIX 2001. */
#if __USE_SORTIX || 200112L <= __USE_POSIX
char* strerror_l(int, locale_t);
int strerror_r(int, char*, size_t);
char* strtok_r(char* __restrict, const char* __restrict, char** __restrict);
#endif
/* Functions from POSIX 2008. */
#if __USE_SORTIX || 200809L <= __USE_POSIX
char* stpcpy(char* __restrict, const char* __restrict);
char* stpncpy(char* __restrict, const char* __restrict, size_t);
int strcoll_l(const char*, const char*, locale_t);
char* strndup(const char*, size_t);
size_t strnlen(const char*, size_t);
char* strsignal(int signum);
size_t strxfrm_l(char* __restrict, const char* __restrict, size_t, locale_t);
#endif
/* Functions from POSIX 2024. */
#if __USE_SORTIX || 202405L <= __USE_POSIX
size_t strlcat(char* __restrict, const char* __restrict, size_t);
size_t strlcpy(char* __restrict, const char* __restrict, size_t);
#endif
#if __USE_SORTIX || 800 <= __USE_XOPEN
int ffsl(long int);
int ffsll(long long int);
#endif
/* Functions copied from elsewhere. */
#if __USE_SORTIX
void explicit_bzero(void*, size_t);
void* memrchr(const void*, int, size_t);
/* TODO: strcasecmp_l */
char* strchrnul(const char* str, int c);
char* stresep(char**, const char*, int);
/* TODO: strncasecmp_l */
char* strsep(char**, const char*);
int strverscmp(const char*, const char*);
int timingsafe_memcmp(const void*, const void*, size_t);
#endif
#if __USE_SORTIX
/* Duplicate S, returning an identical alloca'd string. */
#define strdupa(s) \
(__extension__ \
({ \
const char* __old = (s); \
size_t __len = strlen(__old) + 1; \
char* __new = (char*) __builtin_alloca(__len); \
(char*) memcpy(__new, __old, __len); \
}))
/* Return an alloca'd copy of at most N bytes of string. */
#define strndupa(s, n) \
(__extension__ \
({ \
__const char* __old = (s); \
size_t __len = strnlen(__old, (n)); \
char* __new = (char*) __builtin_alloca(__len + 1); \
__new[__len] = '\0'; \
(char*) memcpy(__new, __old, __len); \
}))
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/explicit_bzero.c
* Initializes a region of memory to a byte value in a manner that is not
* optimized away by the compiler.
*/
#include <string.h>
// TODO: Employ special compiler support to ensure this is not optimized away.
void explicit_bzero(void* dest_ptr, size_t size)
{
volatile unsigned char* dest = (volatile unsigned char*) dest_ptr;
for ( size_t i = 0; i < size; i++ )
dest[i] = 0;
}

25
libc/string/ffs.c Normal file
View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2013 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/ffs.c
* Returns the index of the first set bit.
*/
#include <string.h>
int ffs(int val)
{
return __builtin_ffs(val);
}

25
libc/string/ffsl.c Normal file
View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2013 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/ffsl.c
* Returns the index of the first set bit.
*/
#include <string.h>
int ffsl(long int val)
{
return __builtin_ffsl(val);
}

25
libc/string/ffsll.c Normal file
View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2013 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/ffsll.c
* Returns the index of the first set bit.
*/
#include <string.h>
int ffsll(long long int val)
{
return __builtin_ffsll(val);
}

33
libc/string/memccpy.c Normal file
View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/memccpy.c
* Copy memory until length is met or character is encountered.
*/
#include <stddef.h>
#include <string.h>
void* memccpy(void* dest_ptr, const void* src_ptr, int c, size_t n)
{
unsigned char* dest = (unsigned char*) dest_ptr;
const unsigned char* src = (const unsigned char*) src_ptr;
for ( size_t i = 0; i < n; i++ )
{
if ( (dest[i] = src[i]) == (unsigned char) c )
return dest + i + 1;
}
return NULL;
}

29
libc/string/memchr.c Normal file
View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/memchr.c
* Scans memory for a character.
*/
#include <string.h>
void* memchr(const void* s, int c, size_t size)
{
const unsigned char* buf = (const unsigned char*) s;
for ( size_t i = 0; i < size; i++ )
if ( buf[i] == (unsigned char) c )
return (void*) (buf + i);
return NULL;
}

34
libc/string/memcmp.c Normal file
View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/memcmp.c
* Compares two memory regions.
*/
#include <string.h>
int memcmp(const void* a_ptr, const void* b_ptr, size_t size)
{
const unsigned char* a = (const unsigned char*) a_ptr;
const unsigned char* b = (const unsigned char*) b_ptr;
for ( size_t i = 0; i < size; i++ )
{
if ( a[i] < b[i] )
return -1;
if ( a[i] > b[i] )
return +1;
}
return 0;
}

139
libc/string/memcpy.c Normal file
View file

@ -0,0 +1,139 @@
/*
* Copyright (c) 2011, 2012, 2014, 2015, 2016 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/memcpy.c
* Copy memory between non-overlapping regions.
*/
#include <scram.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#if defined(__is_sortix_libk)
#include <libk.h>
#endif
inline static
void* memcpy_slow(void* restrict dst_ptr,
const void* restrict src_ptr,
size_t size)
{
unsigned char* restrict dst = (unsigned char* restrict) dst_ptr;
const unsigned char* restrict src = (const unsigned char* restrict) src_ptr;
for ( size_t i = 0; i < size; i++ )
dst[i] = src[i];
return dst_ptr;
}
void* memcpy(void* restrict dst_ptr,
const void* restrict src_ptr,
size_t size)
{
if ( dst_ptr == src_ptr || !size )
return dst_ptr;
void* dst_end = (char*) dst_ptr + size;
const void* src_end = (const char*) src_ptr + size;
if ( (dst_ptr < src_ptr && src_ptr < dst_end) ||
(src_ptr < dst_ptr && dst_ptr < src_end) )
{
#if defined(__is_sortix_libk)
libk_overlapping_memcpy();
#else
struct scram_undefined_behavior info;
info.filename = __FILE__;
info.line = __LINE__;
info.column = 0;
info.violation = "overlapping memcpy";
scram(SCRAM_UNDEFINED_BEHAVIOR, &info);
#endif
}
#if 8 < __SIZEOF_LONG__
#warning "you should add support for your unexpectedly large unsigned long."
return memcpy_slow(dst_ptr, src_ptr, size);
#else
unsigned long unalign_mask = sizeof(unsigned long) - 1;
unsigned long src_unalign = (unsigned long) src_ptr & unalign_mask;
unsigned long dst_unalign = (unsigned long) dst_ptr & unalign_mask;
if ( src_unalign != dst_unalign )
return memcpy_slow(dst_ptr, src_ptr, size);
union
{
unsigned long srcval;
const unsigned char* restrict src8;
const uint16_t* restrict src16;
const uint32_t* restrict src32;
const uint64_t* restrict src64;
const unsigned long* restrict srcul;
} su;
su.srcval = (unsigned long) src_ptr;
union
{
unsigned long dstval;
unsigned char* restrict dst8;
uint16_t* restrict dst16;
uint32_t* restrict dst32;
uint64_t* restrict dst64;
unsigned long* restrict dstul;
} du;
du.dstval = (unsigned long) dst_ptr;
if ( dst_unalign )
{
if ( 1 <= size && !(du.dstval & (1-1)) && (du.dstval & (2-1)) )
*du.dst8++ = *su.src8++,
size -= 1;
if ( 2 <= size && !(du.dstval & (2-1)) && (du.dstval & (4-1)) )
*du.dst16++ = *su.src16++,
size -= 2;
#if 8 <= __SIZEOF_LONG__
if ( 4 <= size && !(du.dstval & (4-1)) && (du.dstval & (8-1)) )
*du.dst32++ = *su.src32++,
size -= 4;
#endif
}
size_t num_copies = size / sizeof(unsigned long);
for ( size_t i = 0; i < num_copies; i++ )
*du.dstul++ = *su.srcul++;
size -= num_copies * sizeof(unsigned long);
if ( size )
{
#if 8 <= __SIZEOF_LONG__
if ( 4 <= size )
*du.dst32++ = *su.src32++,
size -= 4;
#endif
if ( 2 <= size )
*du.dst16++ = *su.src16++,
size -= 2;
if ( 1 <= size )
*du.dst8++ = *su.src8++,
size -= 1;
}
return dst_ptr;
#endif
}

38
libc/string/memmove.c Normal file
View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2011, 2012, 2013, 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/memmove.c
* Copy memory between potentionally overlapping regions.
*/
#include <stdint.h>
#include <string.h>
void* memmove(void* dest_ptr, const void* src_ptr, size_t n)
{
unsigned char* dest = (unsigned char*) dest_ptr;
const unsigned char* src = (const unsigned char*) src_ptr;
if ( (uintptr_t) dest < (uintptr_t) src )
{
for ( size_t i = 0; i < n; i++ )
dest[i] = src[i];
}
else
{
for ( size_t i = 0; i < n; i++ )
dest[n-(i+1)] = src[n-(i+1)];
}
return dest_ptr;
}

30
libc/string/memrchr.c Normal file
View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/memrchr.c
* Scans memory in reverse directory for a character.
*/
#include <stdint.h>
#include <string.h>
void* memrchr(const void* ptr, int c, size_t n)
{
const unsigned char* buf = (const unsigned char*) ptr;
for ( size_t i = n; i != 0; i-- )
if ( buf[i-1] == (unsigned char) c )
return (void*) (buf + i-1);
return NULL;
}

59
libc/string/memset.c Normal file
View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/memset.c
* Initializes a region of memory to a byte value.
*/
#include <stdint.h>
#include <string.h>
#include <__/wordsize.h>
void* memset(void* dest_ptr, int value, size_t length)
{
unsigned char* dest = (unsigned char*) dest_ptr;
#if __WORDSIZE == 32 || __WORDSIZE == 64
if ( ((uintptr_t) dest_ptr & (sizeof(unsigned long) - 1)) == 0 )
{
unsigned long* ulong_dest = (unsigned long*) dest;
size_t ulong_length = length / sizeof(unsigned long);
#if __WORDSIZE == 32
unsigned long ulong_value =
(unsigned long) ((unsigned char) value) << 0 |
(unsigned long) ((unsigned char) value) << 8 |
(unsigned long) ((unsigned char) value) << 16 |
(unsigned long) ((unsigned char) value) << 24;
#elif __WORDSIZE == 64
unsigned long ulong_value =
(unsigned long) ((unsigned char) value) << 0 |
(unsigned long) ((unsigned char) value) << 8 |
(unsigned long) ((unsigned char) value) << 16 |
(unsigned long) ((unsigned char) value) << 24 |
(unsigned long) ((unsigned char) value) << 32 |
(unsigned long) ((unsigned char) value) << 40 |
(unsigned long) ((unsigned char) value) << 48 |
(unsigned long) ((unsigned char) value) << 56;
#endif
for ( size_t i = 0; i < ulong_length; i++ )
ulong_dest[i] = ulong_value;
dest += ulong_length * sizeof(unsigned long);
length -= ulong_length * sizeof(unsigned long);
}
#endif
for ( size_t i = 0; i < length; i++ )
dest[i] = (unsigned char) value;
return dest_ptr;
}

29
libc/string/stpcpy.c Normal file
View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/stpcpy.c
* Copy a string returning a pointer to its end.
*/
#include <string.h>
char* stpcpy(char* dest, const char* src)
{
size_t index;
for ( index = 0; src[index]; index++ )
dest[index] = src[index];
dest[index] = '\0';
return dest + index;
}

31
libc/string/stpncpy.c Normal file
View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2011, 2012 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/stpncpy.c
* Copies a string into a fixed size buffer and returns last byte.
*/
#include <string.h>
char* stpncpy(char* dest, const char* src, size_t n)
{
size_t i;
for ( i = 0; i < n && src[i] != '\0'; i++ )
dest[i] = src[i];
char* ret = dest + i;
for ( ; i < n; i++ )
dest[i] = '\0';
return ret;
}

37
libc/string/strcasecmp.c Normal file
View file

@ -0,0 +1,37 @@
/*
* Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strcasecmp.c
* Compares two strings ignoring case.
*/
#include <ctype.h>
#include <stdbool.h>
#include <string.h>
int strcasecmp(const char* a, const char* b)
{
for ( size_t i = 0; true; i++ )
{
unsigned char ac = (unsigned char) tolower((unsigned char) a[i]);
unsigned char bc = (unsigned char) tolower((unsigned char) b[i]);
if ( ac == '\0' && bc == '\0' )
return 0;
if ( ac < bc )
return -1;
if ( ac > bc )
return 1;
}
}

26
libc/string/strcat.c Normal file
View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2011, 2012 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strcat.c
* Appends a string onto another string.
*/
#include <string.h>
char* strcat(char* dest, const char* src)
{
strcpy(dest + strlen(dest), src);
return dest;
}

26
libc/string/strchr.c Normal file
View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2011, 2012, 2013, 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strchr.c
* Searches a string for a specific character.
*/
#include <string.h>
char* strchr(const char* str, int uc)
{
char* ret = strchrnul(str, uc);
return (unsigned char) uc == ((unsigned char*) ret)[0] ? ret : NULL;
}

29
libc/string/strchrnul.c Normal file
View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2011, 2012, 2013, 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strchrnul.c
* Searches a string for a specific character.
*/
#include <stdbool.h>
#include <string.h>
char* strchrnul(const char* str, int uc)
{
const unsigned char* ustr = (const unsigned char*) str;
for ( size_t i = 0; true; i++)
if ( ustr[i] == (unsigned char) uc || !ustr[i] )
return (char*) str + i;
}

36
libc/string/strcmp.c Normal file
View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strcmp.c
* Compares two strings.
*/
#include <stdbool.h>
#include <string.h>
int strcmp(const char* a, const char* b)
{
for ( size_t i = 0; true; i++ )
{
unsigned char ac = (unsigned char) a[i];
unsigned char bc = (unsigned char) b[i];
if ( ac == '\0' && bc == '\0' )
return 0;
if ( ac < bc )
return -1;
if ( ac > bc )
return 1;
}
}

26
libc/string/strcoll.c Normal file
View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2011, 2012 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strcoll.c
* Compare two strings using the current locale.
*/
#include <string.h>
int strcoll(const char* s1, const char* s2)
{
// TODO: Pay attention to locales.
return strcmp(s1, s2);
}

26
libc/string/strcoll_l.c Normal file
View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2013 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strcoll_l.c
* Compare two strings using the given locale.
*/
#include <string.h>
int strcoll_l(const char* s1, const char* s2, locale_t locale)
{
(void) locale;
return strcoll(s1, s2);
}

29
libc/string/strcpy.c Normal file
View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2011, 2012 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strcpy.c
* Copies a string and returns dest.
*/
#include <string.h>
char* strcpy(char* dest, const char* src)
{
size_t index;
for ( index = 0; src[index]; index++ )
dest[index] = src[index];
dest[index] = '\0';
return dest;
}

44
libc/string/strcspn.c Normal file
View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strcspn.c
* Search a string for a set of characters.
*/
#include <stdbool.h>
#include <string.h>
size_t strcspn(const char* str, const char* reject)
{
size_t reject_length = 0;
while ( reject[reject_length] )
reject_length++;
for ( size_t result = 0; true; result++ )
{
char c = str[result];
if ( !c )
return result;
bool matches = false;
for ( size_t i = 0; i < reject_length; i++ )
{
if ( str[result] != reject[i] )
continue;
matches = true;
break;
}
if ( matches )
return result;
}
}

31
libc/string/strdup.c Normal file
View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strdup.c
* Creates a copy of a string.
*/
#include <stdlib.h>
#include <string.h>
char* strdup(const char* input)
{
size_t input_length = strlen(input);
char* result = (char*) malloc(input_length + 1);
if ( !result )
return NULL;
memcpy(result, input, input_length + 1);
return result;
}

124
libc/string/strerror.c Normal file
View file

@ -0,0 +1,124 @@
/*
* Copyright (c) 2011-2016, 2020-2022, 2024 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strerror.c
* Convert error code to a string.
*/
#include <errno.h>
#include <string.h>
char* strerror(int errnum)
{
switch ( errnum )
{
case ENOTBLK: return "Block device required";
case ENODEV: return "No such device";
case EBADF: return "Bad file descriptor";
case EOVERFLOW: return "Value too large to be stored in data type";
case ENOENT: return "No such file or directory";
case ENOSPC: return "No space left on device";
case EEXIST: return "File exists";
case EROFS: return "Read-only file system";
case EINVAL: return "Invalid argument";
case ENOTDIR: return "Not a directory";
case ENOMEM: return "Not enough memory";
case ERANGE: return "Result too large";
case EISDIR: return "Is a directory";
case EPERM: return "Operation not permitted";
case EIO: return "Input/output error";
case ENOEXEC: return "Exec format error";
case EACCES: return "Permission denied";
case ESRCH: return "No such process";
case ENOTTY: return "Not a tty";
case ECHILD: return "No child processes";
case ENOSYS: return "Function not implemented";
case ENOTSUP: return "Operation not supported";
case EBLOCKING: return "Operation is blocking";
case EINTR: return "Interrupted function call";
case ENOTEMPTY: return "Directory not empty";
case EBUSY: return "Device or resource busy";
case EPIPE: return "Broken pipe";
case EILSEQ: return "Invalid byte sequence";
case ELAKE: return "Sit by a lake";
case EMFILE: return "Too many open files";
case EAGAIN: return "Resource temporarily unavailable";
case EEOF: return "End of file";
case EBOUND: return "Out of bounds";
case EINIT: return "Not initialized";
case ENODRV: return "No such driver";
case E2BIG: return "Argument list too long";
case EFBIG: return "File too large";
case EXDEV: return "Improper link";
case ESPIPE: return "Cannot seek on stream";
case ENAMETOOLONG: return "Filename too long";
case ELOOP: return "Too many levels of symbolic links";
case EMLINK: return "Too many links";
case ENXIO: return "No such device or address";
case EPROTONOSUPPORT: return "Protocol not supported";
case EAFNOSUPPORT: return "Address family not supported";
case ENOTSOCK: return "Not a socket";
case EADDRINUSE: return "Address already in use";
case ETIMEDOUT: return "Connection timed out";
case ECONNREFUSED: return "Connection refused";
case EDOM: return "Mathematics argument out of domain of function";
case EINPROGRESS: return "Operation in progress";
case EALREADY: return "Connection already in progress";
case ESHUTDOWN: return "Cannot send after transport endpoint shutdown";
case ECONNABORTED: return "Connection aborted";
case ECONNRESET: return "Connection reset";
case EADDRNOTAVAIL: return "Address not available";
case EISCONN: return "Socket is connected";
case EFAULT: return "Bad address";
case EDESTADDRREQ: return "Destination address required";
case EHOSTUNREACH: return "Host is unreachable";
case EMSGSIZE: return "Message too long";
case ENETDOWN: return "Network is down";
case ENETRESET: return "Connection aborted by network";
case ENETUNREACH: return "Network is unreachable";
case ENOBUFS: return "No buffer space available";
case ENOMSG: return "No message of the desired type";
case ENOPROTOOPT: return "Protocol not available";
case ENOTCONN: return "Socket is not connected";
case EDEADLK: return "Resource deadlock avoided";
case ENFILE: return "Too many open files in system";
case EPROTOTYPE: return "Wrong protocol type for socket";
case ENOLCK: return "No locks available";
case ESIGPENDING: return "Signal is already pending";
case ESTALE: return "Stale file handle";
case EBADMSG: return "Bad message";
case ECANCELED: return "Operation canceled";
case EDQUOT: return "Disk quota exceeded";
case EIDRM: return "Identifier removed";
case EMULTIHOP: return "Multihop attempted";
case ENOLINK: return "Link has been severed";
case ENOTRECOVERABLE: return "State not recoverable";
case EOWNERDEAD: return "Previous owner died";
case EPROTO: return "Protocol error";
case ETXTBSY: return "Text file busy";
case ENOMOUNT: return "No such mountpoint";
case ENOMEDIUM: return "No medium found";
case EHOSTDOWN: return "Host is down";
case ESOCKTNOSUPPORT: return "Socket type is not supported";
default: return "Unknown error condition";
}
}
// TODO: After releasing Sortix 1.1, or after fixing ffmpeg, remove this symbol
// retained for compatibility. ffmpeg has a native sysroot issue where it
// accidentally taints it with the local system's headers instead of the
// sysroot headers, which accidentally pulls in an old removed symbol when
// bootstrapping on an old system.
weak_alias(strerror, sortix_strerror);

26
libc/string/strerror_l.c Normal file
View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2013, 2024 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strerror_l.c
* Convert error code to a string.
*/
#include <string.h>
char* strerror_l(int errnum, locale_t locale)
{
(void) locale;
return (char*) strerror(errnum);
}

32
libc/string/strerror_r.c Normal file
View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2011, 2012, 2013, 2014, 2024 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strerror_r.c
* Convert error code to a string.
*/
#include <errno.h>
#include <string.h>
int strerror_r(int errnum, char* dest, size_t dest_len)
{
const char* msg = strerror(errnum);
if ( !msg )
return -1;
if ( dest_len < strlen(msg) + 1 )
return errno = ERANGE;
strcpy(dest, msg);
return 0;
}

59
libc/string/stresep.c Normal file
View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/stresep.c
* Extract a token from a string while handling escape characters.
*/
#include <stdbool.h>
#include <string.h>
char* stresep(char** string_ptr, const char* delim, int escape)
{
char* token = *string_ptr;
if ( !token )
return NULL;
size_t consumed_length = 0;
size_t token_length = 0;
bool escaped = false;
while ( true )
{
char c = token[consumed_length++];
bool true_nul = c == '\0';
if ( !escaped && escape && (unsigned char) c == (unsigned char) escape )
{
escaped = true;
continue;
}
if ( !escaped && c != '\0' )
{
for ( size_t i = 0; delim[i]; i++ )
{
if ( c != delim[i] )
{
c = '\0';
break;
}
}
}
token[token_length++] = c;
escaped = false;
if ( c == '\0' )
{
*string_ptr = true_nul ? (char*) NULL : token + consumed_length;
return token;
}
}
}

28
libc/string/strlcat.c Normal file
View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2013 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strlcat.c
* Appends a string onto another string truncating if the string is too small.
*/
#include <string.h>
size_t strlcat(char* restrict dest, const char* restrict src, size_t size)
{
size_t dest_len = strnlen(dest, size);
if ( size <= dest_len )
return dest_len + strlen(src);
return dest_len + strlcpy(dest + dest_len, src, size - dest_len);
}

31
libc/string/strlcpy.c Normal file
View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2013, 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strlcpy.c
* Copies a string and truncates it if the destination is too small.
*/
#include <string.h>
size_t strlcpy(char* restrict dest, const char* restrict src, size_t size)
{
if ( !size )
return strlen(src);
size_t result;
for ( result = 0; result < size-1 && src[result]; result++ )
dest[result] = src[result];
dest[result] = '\0';
return result + strlen(src + result);
}

28
libc/string/strlen.c Normal file
View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2011, 2012 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strlen.c
* Returns the length of a string.
*/
#include <string.h>
size_t strlen(const char* str)
{
size_t ret = 0;
while ( str[ret] )
ret++;
return ret;
}

37
libc/string/strncasecmp.c Normal file
View file

@ -0,0 +1,37 @@
/*
* Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strncasecmp.c
* Compares a prefix of two strings ignoring case.
*/
#include <string.h>
#include <ctype.h>
int strncasecmp(const char* a, const char* b, size_t max_count)
{
for ( size_t i = 0; i < max_count; i++ )
{
unsigned char ac = (unsigned char) tolower((unsigned char) a[i]);
unsigned char bc = (unsigned char) tolower((unsigned char) b[i]);
if ( ac == '\0' && bc == '\0' )
return 0;
if ( ac < bc )
return -1;
if ( ac > bc )
return 1;
}
return 0;
}

30
libc/string/strncat.c Normal file
View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2011, 2012 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strncat.c
* Appends parts of a string onto another string.
*/
#include <string.h>
char* strncat(char* dest, const char* src, size_t n)
{
size_t dest_len = strlen(dest);
size_t i;
for ( i = 0; i < n && src[i] != '\0'; i++ )
dest[dest_len + i] = src[i];
dest[dest_len + i] = '\0';
return dest;
}

36
libc/string/strncmp.c Normal file
View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strncmp.c
* Compares a prefix of two strings.
*/
#include <string.h>
int strncmp(const char* a, const char* b, size_t max_count)
{
for ( size_t i = 0; i < max_count; i++ )
{
unsigned char ac = (unsigned char) a[i];
unsigned char bc = (unsigned char) b[i];
if ( ac == '\0' && bc == '\0' )
return 0;
if ( ac < bc )
return -1;
if ( ac > bc )
return 1;
}
return 0;
}

30
libc/string/strncpy.c Normal file
View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2011, 2012 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strncpy.c
* Copies a string into a fixed size buffer and returns dest.
*/
#include <string.h>
char* strncpy(char* dest, const char* src, size_t n)
{
size_t i;
for ( i = 0; i < n && src[i] != '\0'; i++ )
dest[i] = src[i];
for ( ; i < n; i++ )
dest[i] = '\0';
return dest;
}

32
libc/string/strndup.c Normal file
View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strndup.c
* Creates a copy of a string.
*/
#include <stdlib.h>
#include <string.h>
char* strndup(const char* input, size_t n)
{
size_t input_size = strnlen(input, n);
char* result = (char*) malloc(input_size + 1);
if ( !result )
return NULL;
memcpy(result, input, input_size);
result[input_size] = 0;
return result;
}

28
libc/string/strnlen.c Normal file
View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2011, 2012 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strnlen.c
* Returns the length of a fixed length string.
*/
#include <string.h>
size_t strnlen(const char* str, size_t maxlen)
{
size_t ret = 0;
while ( ret < maxlen && str[ret] )
ret++;
return ret;
}

28
libc/string/strpbrk.c Normal file
View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2011, 2012 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strpbrk.c
* Search a string for any of a set of characters.
*/
#include <string.h>
char* strpbrk(const char* str, const char* accept)
{
size_t reject_length = strcspn(str, accept);
if ( !str[reject_length] )
return NULL;
return (char*) str + reject_length;
}

35
libc/string/strrchr.c Normal file
View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2011, 2012, 2013, 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strrchr.c
* Searches a string for a specific character.
*/
#include <stdbool.h>
#include <string.h>
char* strrchr(const char* str, int uc)
{
const unsigned char* ustr = (const unsigned char*) str;
const char* last = NULL;
for ( size_t i = 0; true; i++ )
{
if ( ustr[i] == (unsigned char) uc )
last = str + i;
if ( !ustr[i] )
break;
}
return (char*) last;
}

38
libc/string/strsep.c Normal file
View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strsep.c
* Extract a token from a string.
*/
#include <string.h>
char* strsep(char** string_ptr, const char* delim)
{
char* token = *string_ptr;
if ( !token )
return NULL;
size_t token_length = strcspn(token, delim);
if ( token[token_length] )
{
token[token_length++] = '\0';
*string_ptr = token + token_length;
}
else
{
*string_ptr = (char*) NULL;
}
return token;
}

62
libc/string/strsignal.c Normal file
View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2012, 2014, 2024 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strsignal.c
* Convert signal number to a string.
*/
#include <signal.h>
#include <string.h>
char* strsignal(int signum)
{
switch ( signum )
{
case SIGHUP: return "Hangup";
case SIGINT: return "Interrupt";
case SIGQUIT: return "Quit";
case SIGILL: return "Invalid instruction";
case SIGTRAP: return "Trace/breakpoint trap";
case SIGABRT: return "Aborted";
case SIGBUS: return "Bus Error";
case SIGFPE: return "Floating point exception";
case SIGKILL: return "Killed";
case SIGUSR1: return "User defined signal 1";
case SIGSEGV: return "Segmentation fault";
case SIGUSR2: return "User defined signal 2";
case SIGPIPE: return "Broken pipe";
case SIGALRM: return "Alarm clock";
case SIGTERM: return "Terminated";
case SIGSYS: return "Bad system call";
case SIGCHLD: return "Child exited";
case SIGCONT: return "Continued";
case SIGSTOP: return "Stopped (signal)";
case SIGTSTP: return "Stopped";
case SIGTTIN: return "Stopped (tty input)";
case SIGTTOU: return "Stopped (tty output)";
case SIGURG: return "Urgent I/O condition";
case SIGXCPU: return "CPU time limit exceeded";
case SIGXFSZ: return "File size limit exceeded";
case SIGVTALRM: return "Virtual timer expired";
case SIGPWR: return "Power Fail/Restart";
case SIGWINCH: return "Window changed";
default: break;
}
if ( SIGRTMIN <= signum && signum <= SIGRTMAX )
return "Real-time signal";
return "Unknown signal value";
}

44
libc/string/strspn.c Normal file
View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2011, 2012, 2014 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strspn.c
* Search a string for a set of characters.
*/
#include <stdbool.h>
#include <string.h>
size_t strspn(const char* str, const char* accept)
{
size_t accept_length = 0;
while ( accept[accept_length] )
accept_length++;
for ( size_t result = 0; true; result++ )
{
char c = str[result];
if ( !c )
return result;
bool matches = false;
for ( size_t i = 0; i < accept_length; i++ )
{
if ( str[result] != accept[i] )
continue;
matches = true;
break;
}
if ( !matches )
return result;
}
}

41
libc/string/strstr.c Normal file
View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 2011, 2012 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strstr.c
* Locate a substring.
*/
#include <stdbool.h>
#include <string.h>
// TODO: This simple and hacky implementation runs in O(N^2) even though this
// problem can be solved in O(N).
char* strstr(const char* haystack, const char* needle)
{
if ( !needle[0] )
return (char*) haystack;
for ( size_t i = 0; haystack[i]; i++ )
{
bool diff = false;
for ( size_t j = 0; needle[j]; j++ )
{
if ( haystack[i+j] != needle[j] ) { diff = true; break; }
}
if ( diff )
continue;
return (char*) haystack + i;
}
return NULL;
}

26
libc/string/strtok.c Normal file
View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2011, 2012 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strtok.c
* Extract tokens from strings.
*/
#include <string.h>
char* strtok(char* str, const char* delim)
{
static char* lasttokensaveptr = NULL;
return strtok_r(str, delim, &lasttokensaveptr);
}

38
libc/string/strtok_r.c Normal file
View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2011, 2012 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strtok_r.c
* Extract tokens from strings.
*/
#include <string.h>
char* strtok_r(char* str, const char* delim, char** saveptr)
{
if ( !str && !*saveptr )
return NULL;
if ( !str )
str = *saveptr;
str += strspn(str, delim); // Skip leading
if ( !*str )
return *saveptr = NULL;
size_t amount = strcspn(str, delim);
if ( str[amount] )
*saveptr = str + amount + 1;
else
*saveptr = NULL;
str[amount] = '\0';
return str;
}

116
libc/string/strverscmp.c Normal file
View file

@ -0,0 +1,116 @@
/*
* Copyright (c) 2013 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strverscmp.c
* Compares two version strings.
*/
#include <stdbool.h>
#include <string.h>
static bool is_number(char c)
{
return '0' <= c && c <= '9';
}
static int to_number(char c)
{
return c - '0';
}
int strverscmp(const char* a, const char* b)
{
for ( size_t i = 0; true; i++ )
{
// Be a regular strcmp if the strings are equal.
if ( a[i] == '\0' && b[i] == '\0' )
return 0;
if ( a[i] == b[i] )
continue;
// Be a regular strcmp if no digits are involed when they differ.
// Note: This implementation uses version number comparison if *either*
// of the first differing characters are digits, unlike glibc
// which is documented to require *both*. This behavior matches
// GNU sort -V and musl. It's also useful as "1.2.txt" compares
// before "1.2.3.txt".
bool version_string = is_number(a[i]) || is_number(b[i]);
if ( !version_string && a[i] < b[i] )
return -1;
if ( !version_string && a[i] > b[i] )
return 1;
// Because the number of leading zeroes matter, we have to find the
// entire numeric block we are currently within. We know the strings are
// equal until i, so we can simply find the number of shared digits by
// looking in the first string.
size_t digits_start = i;
while ( digits_start && is_number(a[digits_start-1]) )
digits_start--;
size_t shared_digits = i - digits_start;
// Find the number of shared leading zeroes.
size_t shared_zeroes = 0;
while ( shared_zeroes < shared_digits &&
to_number(a[digits_start + shared_zeroes]) == 0 )
shared_zeroes++;
// Try to expand the leading zeroes amount into a.
size_t a_zeroes = shared_zeroes;
while ( is_number(a[digits_start + a_zeroes]) == 0 )
a_zeroes++;
// Try to expand the leading zeroes amount into b.
size_t b_zeroes = shared_zeroes;
while ( is_number(b[digits_start + b_zeroes]) == 0 )
b_zeroes++;
// We treat strings with leading zeroes as if they have a decimal point
// in front of them, so strings with more zeroes sort lower.
if ( a_zeroes > b_zeroes )
return -1;
if ( b_zeroes > a_zeroes )
return 1;
// Find the number of consecutive digits in a where the strings differ.
size_t a_digits = a_zeroes;
while ( is_number(a[digits_start + a_digits]) )
a_digits++;
// Find the number of consecutive digits in b where the strings differ.
size_t b_digits = b_zeroes;
while ( is_number(b[digits_start + b_digits]) )
b_digits++;
// We know the strings have the same amount of leading zeroes, so we
// so if a a block is longer than the other, then the value must be
// longer as well.
if ( a_digits < b_digits )
return -1;
if ( b_digits < a_digits )
return 1;
// Finally run through the strings from where they differ and sort them
// numerically. We know this terminates because the strings differ. The
// strings have the same amount of digits, so comparing them is easy.
for ( size_t n = shared_zeroes; true; n++ )
{
if ( a[digits_start + n] < b[digits_start + n] )
return -1;
if ( b[digits_start + n] < a[digits_start + n] )
return 1;
}
}
}

27
libc/string/strxfrm.c Normal file
View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2011, 2012 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strxfrm.c
* Transform a string such that the result of strcmp is the same as strcoll.
*/
#include <string.h>
size_t strxfrm(char* dest, const char* src, size_t n)
{
size_t srclen = strlen(src);
strncpy(dest, src, n);
return srclen;
}

26
libc/string/strxfrm_l.c Normal file
View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2013 Jonas 'Sortie' Termansen.
*
* 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.
*
* string/strxfrm_l.c
* Transform a string such that the result of strcmp is the same as strcoll_l.
*/
#include <string.h>
size_t strxfrm_l(char* dest, const char* src, size_t n, locale_t locale)
{
(void) locale;
return strxfrm(dest, src, n);
}

View file

@ -0,0 +1,53 @@
/* $OpenBSD: timingsafe_memcmp.c,v 1.1 2014/06/13 02:12:17 matthew Exp $ */
/*
* Copyright (c) 2014 Google Inc.
*
* 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 <limits.h>
#include <string.h>
// TODO: I don't fully trust that this code is _always_ timing safe in the
// presence of very smart compilers that can prove that this computes the
// same value as memcmp and could be short-circuited. We should invent and
// rely on compiler extensions that inform the compiler that sensitive
// information is involved, which forbids the compiler code generation
// from branching on the information (and such).
// TODO: We should add testcases that verify this is actually timing safe.
int timingsafe_memcmp(const void* a_ptr, const void* b_ptr, size_t size)
{
const unsigned char* a = (const unsigned char*) a_ptr;
const unsigned char* b = (const unsigned char*) b_ptr;
int result = 0;
int done = 0;
for ( size_t i = 0; i < size; i++ )
{
/* lt is -1 if a[i] < b[i]; else 0. */
int lt = (a[i] - b[i]) >> CHAR_BIT;
/* gt is -1 if a[i] > b[i]; else 0. */
int gt = (b[i] - a[i]) >> CHAR_BIT;
/* cmp is 1 if a[i] > b[i]; -1 if a[i] < b[i]; else 0. */
int cmp = lt - gt;
/* set result = cmp if !done. */
result |= cmp & ~done;
/* set done if a[i] != b[i]. */
done |= lt | gt;
}
return result;
}