diff options
41 files changed, 364 insertions, 163 deletions
@@ -18,4 +18,5 @@ obj/ *.pdf *.dvi *.ps +/config.mk diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..19cba87 --- /dev/null +++ b/Makefile @@ -0,0 +1,112 @@ +# slibc — Yet another C library +# Copyright © 2015 Mattias Andrée (maandree@member.fsf.org) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + + + + +# Flags required at compilation of a libc, specifying that unhosted C is used. +CCFLAGS_UNHOSTED = -nostdinc -ffreestanding + +# Preprocessor flags defined by slibc that are required to build the slibc. +CCFLAGS_SLIBC_DEFS = -D_SLIBC_SOURCE=1 -D_GNU_SOURCE=1 -D_BSD_SOURCE=1 -D_SLIBC_SUPPRESS_WARNINGS=1 \ + -D_POSIX_C_SOURCE=999999L -D_XOPEN_SOURCE=9999 + +# Flag that specifies which C dialect the library is written. +CCFLAGS_CSTD = -std=gnu11 + +# Flags that specify where the system header files (that would in this case +# be this library's header files) are located. +CCFLAGS_INCLUDES = -Iinclude + +# Optimisation flags. +CCFLAGS_OPTIIMISE = -Og -g + +# Warning flags. +CCFLAGS_WARNINGS = -Wall -Wextra -Wdouble-promotion -Wformat=2 -Winit-self -Wmissing-include-dirs \ + -Wtrampolines -Wfloat-equal -Wshadow -Wmissing-prototypes -Wmissing-declarations \ + -Wredundant-decls -Wnested-externs -Winline -Wno-variadic-macros -Wsign-conversion \ + -Wswitch-default -Wconversion -Wsync-nand -Wunsafe-loop-optimizations -Wcast-align \ + -Wstrict-overflow -Wdeclaration-after-statement -Wundef -Wbad-function-cast \ + -Wcast-qual -Wwrite-strings -Wlogical-op -Waggregate-return -Wstrict-prototypes \ + -Wold-style-definition -Wpacked -Wvector-operation-performance \ + -Wunsuffixed-float-constants -Wsuggest-attribute=const -Wsuggest-attribute=noreturn \ + -Wsuggest-attribute=pure -Wsuggest-attribute=format -Wnormalized=nfkc +# -pedantic is excluded. + + +# All flags used required when compiling the library. +CCFLAGS_COMMON = $(CCFLAGS_UNHOSTED) $(CCFLAGS_SLIBC_DEFS) $(CCFLAGS_CSTD) $(CCFLAGS_INCLUDES) \ + $(CCFLAGS_OPTIIMISE) $(CCFLAGS_WARNINGS) +CCFLAGS_COMMON += $(CPPFLAGS) $(CFLAGS) +CCFLAGS_STATIC = $(CCFLAGS_COMMON) +CCFLAGS_SHARED = $(CCFLAGS_COMMON) -fPIC -DSHARED + +# Flags required when genering header file dependency list. +MMFLAGS = $(CCFLAGS_COMMON) -MG + + +# Object files to build. +OBJECTS = $(shell find src | grep '\.c$$' | sed -e 's:^src/:obj/:' -e 's:\.c$$:\.o:') + + + +# You may add config.mk to the topmost directory +# to change any configurations above. +-include config.mk + +# The default rule. +.PHONY: default +default: all + +# Include list of file dependencies for object files. +include obj/deps.mk + + + + +# Build everything. +.PHONY: all +all: $(OBJECTS) + @echo $^ + + +# Build object file. +obj/%.o: + @mkdir -p $$(dirname $@) + $(CC) -c -o $@ src/$*.c $(CCFLAGS_SHARED) + + + + + +# Generate list of file dependencies for object files. +obj/deps.mk: Makefile + @mkdir -p obj + find src | grep '\.c$$' | xargs $(CC) -MM $(MMFLAGS) > $@ + sed -i 's#^[^ :]*\.o: src\([^ ]*\)/[^ /]*\.c#obj\1/&#' $@ + + + +# Clean generated files. +.PHONY: clean +clean: + -rm -rf obj bin + +# Remove all files that are not part of the source. +.PHONY: distclean +distclean: clean + -rm -f config.mk + diff --git a/include/assert.h b/include/assert.h index 6315ae1..838a9bf 100644 --- a/include/assert.h +++ b/include/assert.h @@ -56,7 +56,7 @@ #define static_assert _Static_assert -#ifndef __PORTABLE +#if (defined(_SLIBC_SOURCE) || defined(_GNU_SOURCE)) && !defined(__PORTABLE) /** * Unless `NDEBUG` is defined, print an error message * and abort the process, if `errnum` is non-zero. @@ -65,15 +65,15 @@ * * `assert_perror` is a GNU extension. */ -#if defined(_SLIBC_SOURCE) || defined(_GNU_SOURCE) -#ifdef assert_perror -# undef assert_perror -#endif -#ifdef NDEBUG -# define assert_perror(errnum) ((void)0) -#else -# define assert_perror(errnum) \ +# ifdef assert_perror +# undef assert_perror +# endif +# ifdef NDEBUG +# define assert_perror(errnum) ((void)0) +# else +# define assert_perror(errnum) \ ((void)((errnum == 0) ? 0 : (__assert_fail(NULL, errnum, __FILE__, __LINE__, __func__), 0))) +# endif #endif @@ -89,7 +89,6 @@ */ void __assert_fail(const char*, int, const char*, int, const char*) __noreturn __GCC_ONLY(__attribute__((nonnull(3, 4, 5)))); -#endif diff --git a/include/bits/types.h b/include/bits/types.h index e594e44..7a2244e 100644 --- a/include/bits/types.h +++ b/include/bits/types.h @@ -32,7 +32,7 @@ #ifndef __MAX_OF # define __MAX_OF(type) \ (((type)1) << sizeof(type)) -#define +#endif /** diff --git a/include/ctype.h b/include/ctype.h index f01ad57..f98705d 100644 --- a/include/ctype.h +++ b/include/ctype.h @@ -35,7 +35,8 @@ * @return Whether the character is in * ['0', '9'], ['A', 'Z'], or ['a', 'z']. */ -int (isalnum)(int); /* [0x30, 0x39], [0x41, 0x5A], [0x61, 0x7A] */ +int (isalnum)(int) /* [0x30, 0x39], [0x41, 0x5A], [0x61, 0x7A] */ + __GCC_ONLY(__attribute__((const))); #if defined (__GNUC__) # define isalnum(c) \ ({ int __c = (c); (isalpha(__c) || isdigit(__c)); }) @@ -49,7 +50,8 @@ int (isalnum)(int); /* [0x30, 0x39], [0x41, 0x5A], [0x61, 0x7A] */ * @return Whether the character is in * ['A', 'Z'] or ['a', 'z']. */ -int (isalpha)(int); /* [0x41, 0x5A], [0x61, 0x7A] */ +int (isalpha)(int) /* [0x41, 0x5A], [0x61, 0x7A] */ + __GCC_ONLY(__attribute__((const))); #define isalpha(c) (islower(tolower(a))) @@ -63,7 +65,8 @@ int (isalpha)(int); /* [0x41, 0x5A], [0x61, 0x7A] */ * @param c The character. * @return Whether the character is a ' ' or a '\t'. */ -int (isblank)(int); /* ' ', '\t' */ +int (isblank)(int) /* ' ', '\t' */ + __GCC_ONLY(__attribute__((const))); # if defined(__GNUC__) # define isblank(c) \ ({ int __c = (c); ((__c == ' ') || (__c == '\t')); }) @@ -79,7 +82,8 @@ int (isblank)(int); /* ' ', '\t' */ * @return Whether the character is lower than ' ', * or is 0x7F. */ -int (iscntrl)(int); /* [0x00, 0x1F], 0x7F */ +int (iscntrl)(int) /* [0x00, 0x1F], 0x7F */ + __GCC_ONLY(__attribute__((const))); #if defined(__GNUC__) # define iscntrl(c) \ ({ int __c = (c); (((unsigned)__c < ' ') || (c__ == 0x7F)); }) @@ -92,7 +96,8 @@ int (iscntrl)(int); /* [0x00, 0x1F], 0x7F */ * @param c The character. * @return Whether the character is in ['0', '9']. */ -int (isdigit)(int); /* [0x30, 0x39] */ +int (isdigit)(int) /* [0x30, 0x39] */ + __GCC_ONLY(__attribute__((const))); #define isdigit(c) ((unsigned)((c) - '0') < 10) @@ -103,7 +108,8 @@ int (isdigit)(int); /* [0x30, 0x39] */ * @return Whether the character is greater * than ' ', but is not 0x7F. */ -int (isgraph)(int); /* [0x21, 0x7E] */ +int (isgraph)(int) /* [0x21, 0x7E] */ + __GCC_ONLY(__attribute__((const))); #define isgraph(c) ((unsigned)(c - 0x21) < 0x5E) @@ -114,7 +120,8 @@ int (isgraph)(int); /* [0x21, 0x7E] */ * @param c The character. * @return Whether the character is in ['a', 'z']. */ -int (islower)(int); /* [0x61, 0x7A] */ +int (islower)(int) /* [0x61, 0x7A] */ + __GCC_ONLY(__attribute__((const))); #define islower(c) ((unsigned)((c) - 'a') < 26) @@ -126,7 +133,8 @@ int (islower)(int); /* [0x61, 0x7A] */ * @return Whether the character is at least * as great as ' ', but is not 0x7F. */ -int (isprint)(int); /* [0x20, 0x7E] */ +int (isprint)(int) /* [0x20, 0x7E] */ + __GCC_ONLY(__attribute__((const))); #define isprint(c) ((unsigned)(c - 0x20) < 0x5F) @@ -138,7 +146,8 @@ int (isprint)(int); /* [0x20, 0x7E] */ * @param c The character. * @return Whether the character is a punctuation. */ -int (ispunct)(int); /* isprint && !isalnum && !isspace) */ +int (ispunct)(int) /* isprint && !isalnum && !isspace) */ + __GCC_ONLY(__attribute__((const))); #if defined (__GNUC__) # define ispunk(c) \ ({ int __c = (c); (isprint(__c) && !isalnum(__c) && !isspace(__c)); }) @@ -152,7 +161,8 @@ int (ispunct)(int); /* isprint && !isalnum && !isspace) */ * @return Whether the character is a ' ', '\f', * '\n', '\r', '\t', or '\v'. */ -int (isspace)(int); /* 0x20, [0x09, 0x0D] */ +int (isspace)(int) /* 0x20, [0x09, 0x0D] */ + __GCC_ONLY(__attribute__((const))); #if defined (__GNUC__) # define isspace(c) \ ({ int __c = (c); ((__c == ' ') || ((unsigned)(__c - '\t') < 5)); }) @@ -166,7 +176,8 @@ int (isspace)(int); /* 0x20, [0x09, 0x0D] */ * @param c The character. * @return Whether the character is in ['A', 'Z']. */ -int (isupper)(int); /* [0x41, 0x5A] */ +int (isupper)(int) /* [0x41, 0x5A] */ + __GCC_ONLY(__attribute__((const))); #define isupper(c) ((unsigned)((c) - 'A') < 26) @@ -179,7 +190,8 @@ int (isupper)(int); /* [0x41, 0x5A] */ * @return Whether the character is in * ['0', '9'], ['A', 'Z'], or ['a', 'z']. */ -int (isxdigit)(int); /* [0x30, 0x39], [0x41, 0x46], [0x61, 0x66] */ +int (isxdigit)(int) /* [0x30, 0x39], [0x41, 0x46], [0x61, 0x66] */ + __GCC_ONLY(__attribute__((const))); #if defined (__GNUC__) # define isxdigit(c) \ ({ int __c = (c); (isdigit(__c) && (tolower(__c) - 'a' < 6)); }) @@ -201,8 +213,9 @@ int (isxdigit)(int); /* [0x30, 0x39], [0x41, 0x46], [0x61, 0x66] */ * Guaranteed to be unchanged if the * character already is in lowercase. */ -int (tolower)(int); /* [0x41, 0x5A] -> [0x61, 0x7A] */ -#define tolower(c) ((c) | 0x20) +int (tolower)(int) /* [0x41, 0x5A] -> [0x61, 0x7A] */ + __GCC_ONLY(__attribute__((const))); +#define tolower(c) ((unsigned)(c) | 0x20) /** * Convert a lowercase ASCII character to @@ -218,8 +231,9 @@ int (tolower)(int); /* [0x41, 0x5A] -> [0x61, 0x7A] */ * Guaranteed to be unchanged if the * character already is in lowercase. */ -int (toupper)(int); /* [0x61, 0x7A] -> [0x41, 0x5A] */ -#define toupper(c) ((c) & ~0x20) +int (toupper)(int) /* [0x61, 0x7A] -> [0x41, 0x5A] */ + __GCC_ONLY(__attribute__((const))); +#define toupper(c) ((unsigned)(c) & ~0x20) @@ -229,7 +243,8 @@ int (toupper)(int); /* [0x61, 0x7A] -> [0x41, 0x5A] */ * @param c The character * @return - Whether the character is an ASCII character. */ -int (isascii)(int); /* [0x00, 0x7E] */ +int (isascii)(int) /* [0x00, 0x7E] */ + __GCC_ONLY(__attribute__((const))); #define isascii(c) ((unsigned)(c) < 0x7F) /** @@ -242,9 +257,10 @@ int (isascii)(int); /* [0x00, 0x7E] */ * @param c The character with the 8:th bit cleared. */ int (toascii)(int) - __warning("Using 'toascii' is, generally, unwise."); + __warning("Using 'toascii' is, generally, unwise.") + __GCC_ONLY(__attribute__((const))); #if defined(_SLIBC_SUPPRESS_WARNINGS) -# define toascii(c) ((c) & 0x7F) +# define toascii(c) ((unsigned)(c) & 0x7F) #endif /** @@ -252,14 +268,16 @@ int (toascii)(int) * It is provided for backwards-compatibility with SVID. */ int _tolower(int) - __deprecated("Use 'tolower' instead."); + __deprecated("Use 'tolower' instead.") + __GCC_ONLY(__attribute__((const))); /** * This function is identical to `tolower`. * It is provided for backwards-compatibility with SVID. */ int _toupper(int) - __deprecated("Use 'toupper' instead."); + __deprecated("Use 'toupper' instead.") + __GCC_ONLY(__attribute__((const))); diff --git a/include/err.h b/include/err.h index 6e9b828..c4b241a 100644 --- a/include/err.h +++ b/include/err.h @@ -87,7 +87,7 @@ void vwarnx(const char*, va_list); * @param ... Formatting-arguments. */ void err(int, const char*, ...) - __noreturn __GCC_ONLY(__attribute__((format(printf, 2, 3)))); + __GCC_ONLY(__attribute__((format(printf, 2, 3)))) __noreturn; /** * Print an error message to stderr, followed by a diff --git a/include/error.h b/include/error.h index f38ee44..37d8328 100644 --- a/include/error.h +++ b/include/error.h @@ -26,7 +26,7 @@ #endif -#include <slibc/features.h> +#include <stdarg.h> @@ -140,7 +140,7 @@ extern volatile int error_one_per_line; * * This is a GNU extension. */ -extern volatile void (*error_print_progname)(void); +extern void (*volatile error_print_progname)(void); diff --git a/include/stddef.h b/include/stddef.h index 26286f5..871a618 100644 --- a/include/stddef.h +++ b/include/stddef.h @@ -44,7 +44,7 @@ */ #ifndef NULL # define NULL ((void*)0) -#define +#endif /** diff --git a/include/stdlib.h b/include/stdlib.h index 3151947..c02e094 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -39,7 +39,7 @@ */ #ifndef NULL # define NULL ((void*)0) -#define +#endif diff --git a/include/string.h b/include/string.h index c43b41d..fe1b930 100644 --- a/include/string.h +++ b/include/string.h @@ -22,6 +22,14 @@ +/** + * `NULL`'s canonical header is <stddef.h> + */ +#ifndef NULL +# define NULL ((void*)0) +#endif + + #define __NEED_size_t #define __NEED_locale_t /* TODO not defined */ @@ -66,11 +74,13 @@ char* strerror(int) * `LC_GLOBAL_LOCALE`, lest the behaviour is undefined. * @return A description of the error. */ +/* TODO strerror_l char* strerror_l(int, locale_t) __GCC_ONLY(__attribute__((warn_unused_result))); +*/ -#if !defined(__PORTABLE) && !defined(_SLIBC_SOURCE) +#if !defined(__PORTABLE) /** * Reenterant variant of `strerror`. * @@ -125,7 +135,7 @@ char* __gnu_strerror_r(int, char*, size_t); /* GNU-specific strerror_r */ * @return The number of bytes before the first NUL byte. */ size_t strlen(const char*) - __GCC_ONLY(__attribute__((nonnull, warn_unused_result))); + __GCC_ONLY(__attribute__((nonnull, warn_unused_result, pure))); #if (defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || \ defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || \ @@ -140,7 +150,7 @@ size_t strlen(const char*) * `maxlen` if no NUL byte was found. */ size_t strnlen(const char*, size_t) - __GCC_ONLY(__attribute__((warn_unused_result))); + __GCC_ONLY(__attribute__((warn_unused_result, pure))); #endif @@ -716,7 +726,7 @@ void* memdup(const void*, size_t) * see the specifications for `a` and `b`. */ int memcmp(const void*, const void*, size_t) - __GCC_ONLY(__attribute__((warn_unused_result))); + __GCC_ONLY(__attribute__((warn_unused_result, pure))); /** * Compare two strings alphabetically in a case sensitive manner. @@ -727,7 +737,7 @@ int memcmp(const void*, const void*, size_t) * see the specifications for `a` and `b`. */ int strcmp(const char*, const char*) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); /** * Compare two strings alphabetically in a case sensitive manner. @@ -739,12 +749,12 @@ int strcmp(const char*, const char*) * see the specifications for `a` and `b`. */ int strncmp(const char*, const char*, size_t) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); #if defined(_GNU_SOURCE) && !defined(__PORTABLE) int strverscmp(const char*, const char*) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); /* TODO document and implement strverscmp */ #endif @@ -759,7 +769,7 @@ int strverscmp(const char*, const char*) * `NULL` if none were found. */ void* memchr(const void*, int, size_t) - __GCC_ONLY(__attribute__((warn_unused_result))); + __GCC_ONLY(__attribute__((warn_unused_result, pure))); #if (defined(_GNU_SOURCE) || defined(_SLIBC_SOURCE)) && !defined(__PORTABLE) /** @@ -773,7 +783,7 @@ void* memchr(const void*, int, size_t) * @return Pointer to the first occurrence of `c`. */ void* rawmemchr(const void*, int) - __GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull, nonnull, pure))); #endif /** @@ -790,7 +800,7 @@ void* rawmemchr(const void*, int) * `NULL` if none were found. */ void* memrchr(const void*, int, size_t) - __GCC_ONLY(__attribute__((warn_unused_result))); + __GCC_ONLY(__attribute__((warn_unused_result, pure))); /** * Find the first occurrence of a byte in a string. @@ -806,7 +816,7 @@ void* memrchr(const void*, int, size_t) * `NULL` if none were found. */ char* strchr(const char*, int) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); #if (defined(_GNU_SOURCE) || defined(_SLIBC_SOURCE)) && !defined(__PORTABLE) /** @@ -824,7 +834,7 @@ char* strchr(const char*, int) * if none were found. */ char* strchrnul(const char*, int) - __GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull, nonnull, pure))); #endif /** @@ -842,7 +852,7 @@ char* strchrnul(const char*, int) * `NULL` if none were found. */ char* strrchr(const char*, int) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); /* TODO Add case insensitive character searching functions. */ @@ -858,7 +868,7 @@ char* strrchr(const char*, int) * substring, `NULL` if not found. */ char* strstr(const char*, const char*) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); /** * Finds the first occurrence of a substring. @@ -870,7 +880,7 @@ char* strstr(const char*, const char*) * substring, `NULL` if not found. */ char* strcasestr(const char*, const char*) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); #if defined(_SLIBC_SOURCE) && !defined(__PORTABLE) /** @@ -887,7 +897,7 @@ char* strcasestr(const char*, const char*) * substring, `NULL` if not found. */ char* strnstr(const char*, const char*, size_t) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); /** * Finds the first occurrence of a substring. @@ -902,7 +912,7 @@ char* strnstr(const char*, const char*, size_t) * substring, `NULL` if not found. */ char* strncasestr(const char*, const char*, size_t) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); /** * Finds the first occurrence of a substring. @@ -916,7 +926,7 @@ char* strncasestr(const char*, const char*, size_t) * @return Pointer to the first occurrence of the substring. */ char* rawstrstr(const char*, const char*) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull, returns_nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, returns_nonnull, pure))); /** * Finds the first occurrence of a substring. @@ -930,7 +940,7 @@ char* rawstrstr(const char*, const char*) * @return Pointer to the first occurrence of the substring. */ char* rawstrcasestr(const char*, const char*) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull, returns_nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, returns_nonnull, pure))); /** * Finds the first occurrence of a substring @@ -947,7 +957,7 @@ char* rawstrcasestr(const char*, const char*) * the substring, `NULL` if not found. */ void* memcasemem(const void*, size_t, const void*, size_t) - __GCC_ONLY(__attribute__((warn_unused_result))); + __GCC_ONLY(__attribute__((warn_unused_result, pure))); #endif #if (defined(_GNU_SOURCE) || defined(_SLIBC_SOURCE)) && !defined(__PORTABLE) @@ -966,7 +976,7 @@ void* memcasemem(const void*, size_t, const void*, size_t) * the substring, `NULL` if not found. */ void* memmem(const void*, size_t, const void*, size_t) - __GCC_ONLY(__attribute__((warn_unused_result))); + __GCC_ONLY(__attribute__((warn_unused_result, pure))); #endif @@ -983,7 +993,7 @@ void* memmem(const void*, size_t, const void*, size_t) * @return The length of the substring. */ size_t strspn(const char*, const char*) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); /** * Returns length of the initial substring @@ -995,7 +1005,7 @@ size_t strspn(const char*, const char*) * @return The length of the substring. */ size_t strcspn(const char*, const char*) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); /** * This function works like `strcspn`, @@ -1010,7 +1020,7 @@ size_t strcspn(const char*, const char*) * `NULL` is returned if none is found. */ char* stpbrk(const char*, const char*) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); /** @@ -1086,7 +1096,7 @@ char* strsep(char** restrict, const char* restrict) * so it must not freed or edited. */ char* __gnu_basename(const char*) - __GCC_ONLY(__attribute__((warn_unused_result))); + __GCC_ONLY(__attribute__((warn_unused_result, pure))); # define basename __gnu_basename #endif diff --git a/include/strings.h b/include/strings.h index 2044fa6..a06a167 100644 --- a/include/strings.h +++ b/include/strings.h @@ -64,7 +64,7 @@ void bcopy(const void*, void*, size_t) */ int bcmp(const void*, const void*, size_t) __deprecated("Use 'memcmp' instead.") - __GCC_ONLY(__attribute__((warn_unused_result))); + __GCC_ONLY(__attribute__((warn_unused_result, pure))); /** @@ -78,7 +78,7 @@ int bcmp(const void*, const void*, size_t) * see the specifications for `a` and `b`. */ int strcasecmp(const char*, const char*) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); /** * Compare two strings alphabetically in a case insensitive manner. @@ -92,7 +92,7 @@ int strcasecmp(const char*, const char*) * see the specifications for `a` and `b`. */ int strncasecmp(const char*, const char*, size_t) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); /** @@ -102,7 +102,7 @@ int strncasecmp(const char*, const char*, size_t) */ char* index(const char*, int) __deprecated("Use 'strchr' instead.") - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); /** * This function is identical to `strrchr`. @@ -111,7 +111,7 @@ char* index(const char*, int) */ char* rindex(const char*, int) __deprecated("Use 'strrchr' instead.") - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); diff --git a/include/wchar.h b/include/wchar.h index faf9275..12b1de9 100644 --- a/include/wchar.h +++ b/include/wchar.h @@ -23,6 +23,14 @@ +/** + * `NULL`'s canonical header is <stddef.h> + */ +#ifndef NULL +# define NULL ((void*)0) +#endif + + #define __NEED_size_t #define __NEED_wchar_t @@ -37,7 +45,7 @@ * first NUL character. */ size_t wcslen(const wchar_t*) - __GCC_ONLY(__attribute__((nonnull, warn_unused_result))); + __GCC_ONLY(__attribute__((nonnull, warn_unused_result, pure))); #if (defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || \ defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || \ @@ -52,7 +60,7 @@ size_t wcslen(const wchar_t*) * NUL character was found. */ size_t wcsnlen(const wchar_t*, size_t) - __GCC_ONLY(__attribute__((warn_unused_result))); + __GCC_ONLY(__attribute__((warn_unused_result, pure))); #endif @@ -200,7 +208,7 @@ wchar_t* wcpcpy(wchar_t* restrict, const wchar_t* restrict) * one character passed the last written non-NUL * character. */ -wchar_t* wcsccpy(wchar_t* restrict, const wchar_t* restrict, wchat_t) +wchar_t* wcsccpy(wchar_t* restrict, const wchar_t* restrict, wchar_t) __GCC_ONLY(__attribute__((nonnull))); /** @@ -286,7 +294,7 @@ wchar_t* wcpncpy(wchar_t* restrict, const wchar_t* restrict, size_t) * one character passed the last written non-NUL * character. */ -wchar_t* wcscncpy(wchar_t* restrict, const wchar_t* restrict, wchat_t, size_t) +wchar_t* wcscncpy(wchar_t* restrict, const wchar_t* restrict, wchar_t, size_t) __GCC_ONLY(__attribute__((nonnull))); /** @@ -361,7 +369,7 @@ wchar_t* wcpmove(wchar_t*, const wchar_t*) * one character passed the last written non-NUL * character. */ -wchar_t* wcscmove(wchar_t*, const wchar_t*, wchat_t) +wchar_t* wcscmove(wchar_t*, const wchar_t*, wchar_t) __GCC_ONLY(__attribute__((nonnull))); /** @@ -446,7 +454,7 @@ wchar_t* wcpnmove(wchar_t*, const wchar_t*, size_t) * one character passed the last written non-NUL * character. */ -wchar_t* wcscnmove(wchar_t*, const wchar_t*, wchat_t, size_t) +wchar_t* wcscnmove(wchar_t*, const wchar_t*, wchar_t, size_t) __GCC_ONLY(__attribute__((nonnull))); /** @@ -641,7 +649,7 @@ wchar_t* wmemdup(const wchar_t*, size_t) * see the specifications for `a` and `b`. */ int wmemcmp(const wchar_t*, const wchar_t*, size_t) - __GCC_ONLY(__attribute__((warn_unused_result))); + __GCC_ONLY(__attribute__((warn_unused_result, pure))); /** * Compare two strings alphabetically in a case sensitive manner. @@ -652,7 +660,7 @@ int wmemcmp(const wchar_t*, const wchar_t*, size_t) * see the specifications for `a` and `b`. */ int wcscmp(const wchar_t*, const wchar_t*) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); #if (defined(_GNU_SOURCE) || defined(_SLIBC_SOURCE)) && !defined(__PORTABLE) /** @@ -668,7 +676,7 @@ int wcscmp(const wchar_t*, const wchar_t*) * see the specifications for `a` and `b`. */ int wcscasecmp(const wchar_t*, const wchar_t*) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); /** * Compare two strings alphabetically in a case sensitive manner. @@ -682,7 +690,7 @@ int wcscasecmp(const wchar_t*, const wchar_t*) * see the specifications for `a` and `b`. */ int wcsncmp(const wchar_t*, const wchar_t*, size_t) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); /** * Compare two strings alphabetically in a case insensitive manner. @@ -698,7 +706,7 @@ int wcsncmp(const wchar_t*, const wchar_t*, size_t) * see the specifications for `a` and `b`. */ int wcsncasecmp(const wchar_t*, const wchar_t*, size_t) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); #endif @@ -713,7 +721,7 @@ int wcsncasecmp(const wchar_t*, const wchar_t*, size_t) * `NULL` if none were found. */ wchar_t* wmemchr(const wchar_t*, wchar_t, size_t) - __GCC_ONLY(__attribute__((warn_unused_result))); + __GCC_ONLY(__attribute__((warn_unused_result, pure))); #if defined(_SLIBC_SOURCE) && !defined(__PORTABLE) /** @@ -728,7 +736,7 @@ wchar_t* wmemchr(const wchar_t*, wchar_t, size_t) * @return Pointer to the first occurrence of `c`. */ wchar_t* rawwmemchr(const wchar_t*, wchar_t) - __GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull, nonnull, pure))); /** * Find the last occurrence of a wide character in @@ -747,7 +755,7 @@ wchar_t* rawwmemchr(const wchar_t*, wchar_t) * `NULL` if none were found. */ wchar_t* wmemrchr(const wchar_t*, wchar_t, size_t) - __GCC_ONLY(__attribute__((warn_unused_result))); + __GCC_ONLY(__attribute__((warn_unused_result, pure))); #endif /** @@ -761,7 +769,7 @@ wchar_t* wmemrchr(const wchar_t*, wchar_t, size_t) * `NULL` if none were found. */ wchar_t* wcschr(const wchar_t*, wchar_t) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); #if (defined(_GNU_SOURCE) || defined(_SLIBC_SOURCE)) && !defined(__PORTABLE) /** @@ -780,7 +788,7 @@ wchar_t* wcschr(const wchar_t*, wchar_t) * if none were found. */ wchar_t* wcschrnul(const wchar_t*, wchar_t) - __GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull, nonnull, pure))); #endif /** @@ -798,7 +806,7 @@ wchar_t* wcschrnul(const wchar_t*, wchar_t) * `NULL` if none were found. */ wchar_t* wcsrchr(const wchar_t*, wchar_t) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); /* TODO Add case insensitive character searching functions. */ @@ -808,7 +816,7 @@ wchar_t* wcsrchr(const wchar_t*, wchar_t) * This function is identical to `wcsstr`. */ wchar_t* wcswcs(const wchar_t*, const wchar_t*) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))) + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))) __deprecated("Use 'wcsstr' instead."); /** @@ -821,7 +829,7 @@ wchar_t* wcswcs(const wchar_t*, const wchar_t*) * substring, `NULL` if not found. */ wchar_t* wcsstr(const wchar_t*, const wchar_t*) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); #if defined(_SLIBC_SOURCE) && !defined(__PORTABLE) /** @@ -836,7 +844,7 @@ wchar_t* wcsstr(const wchar_t*, const wchar_t*) * substring, `NULL` if not found. */ wchar_t* wcscasestr(const wchar_t*, const wchar_t*) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); /** * Finds the first occurrence of a substring. @@ -852,7 +860,7 @@ wchar_t* wcscasestr(const wchar_t*, const wchar_t*) * substring, `NULL` if not found. */ wchar_t* wcsnstr(const wchar_t*, const wchar_t*, size_t) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); /** * Finds the first occurrence of a substring. @@ -867,7 +875,7 @@ wchar_t* wcsnstr(const wchar_t*, const wchar_t*, size_t) * substring, `NULL` if not found. */ wchar_t* wcsncasestr(const wchar_t*, const wchar_t*, size_t) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); /** * Finds the first occurrence of a substring. @@ -881,7 +889,7 @@ wchar_t* wcsncasestr(const wchar_t*, const wchar_t*, size_t) * @return Pointer to the first occurrence of the substring. */ wchar_t* rawwcsstr(const wchar_t*, const wchar_t*) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull, returns_nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, returns_nonnull, pure))); /** * Finds the first occurrence of a substring. @@ -895,7 +903,7 @@ wchar_t* rawwcsstr(const wchar_t*, const wchar_t*) * @return Pointer to the first occurrence of the substring. */ wchar_t* rawwcscasestr(const wchar_t*, const wchar_t*) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull, returns_nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, returns_nonnull, pure))); /** * Finds the first occurrence of a substring @@ -911,7 +919,8 @@ wchar_t* rawwcscasestr(const wchar_t*, const wchar_t*) * @return Pointer to the first occurrence of * the substring, `NULL` if not found. */ -wchar_t* wmemcasemem(const wchar_t*, size_t, const wchar_t*, size_t); +wchar_t* wmemcasemem(const wchar_t*, size_t, const wchar_t*, size_t) + __GCC_ONLY(__attribute__((warn_unused_result, pure))); #endif #if (defined(_GNU_SOURCE) || defined(_SLIBC_SOURCE)) && !defined(__PORTABLE) @@ -931,7 +940,7 @@ wchar_t* wmemcasemem(const wchar_t*, size_t, const wchar_t*, size_t); * the substring, `NULL` if not found. */ wchar_t* wmemmem(const wchar_t*, size_t, const wchar_t*, size_t) - __GCC_ONLY(__attribute__((warn_unused_result))); + __GCC_ONLY(__attribute__((warn_unused_result, pure))); #endif @@ -948,7 +957,7 @@ wchar_t* wmemmem(const wchar_t*, size_t, const wchar_t*, size_t) * @return The length of the substring. */ size_t wcsspn(const wchar_t*, const wchar_t*) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); /** * Returns length of the initial substring @@ -960,7 +969,7 @@ size_t wcsspn(const wchar_t*, const wchar_t*) * @return The length of the substring. */ size_t wcscspn(const wchar_t*, const wchar_t*) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); /** * This function works like `strcspn`, @@ -975,7 +984,7 @@ size_t wcscspn(const wchar_t*, const wchar_t*) * `NULL` is returned if none is found. */ wchar_t* wcpbrk(const wchar_t*, const wchar_t*) - __GCC_ONLY(__attribute__((warn_unused_result, nonnull))); + __GCC_ONLY(__attribute__((warn_unused_result, nonnull, pure))); /** diff --git a/src/errno.c b/src/errno.c new file mode 100644 index 0000000..80b46fe --- /dev/null +++ b/src/errno.c @@ -0,0 +1,51 @@ +/** + * slibc — Yet another C library + * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#include <errno.h> + + + +/** + * This is the name that was used to invoke the program + * running in the current process. This is the value + * of `argv[0]` from the `main` function (where `argv` + * is the second parameter). If `argc` is zero, this + * variable will have the value `NULL`. This is not + * necessarily a proper comman name. For example, + * login shells are usually prefixes with a dash, + * for example "-bash", despite that there is no such + * command. Often, but not always, this will not contain + * directory. + * + * This string may be edited if `program_invocation_short_name` + * or `argv[0]` is edited. + * + * This is a GNU and slibc extension. + */ +char* program_invocation_name = NULL; + +/** + * Variant of `program_invocation_name` that is + * guaranteed to not include the directory. + * + * This string may be edited if `program_invocation_name` + * or `argv[0]` is edited. + * + * This is a GNU extension. + */ +char* program_invocation_short_name = NULL; + diff --git a/src/string/memccpy.c b/src/string/memccpy.c index 85378d9..4212419 100644 --- a/src/string/memccpy.c +++ b/src/string/memccpy.c @@ -35,10 +35,10 @@ */ void* memccpy(void* restrict whither, const void* restrict whence, int c, size_t size) { - char_t* stop = memchr(whence, c, size); - void* r = NULL + char* stop = memchr(whence, c, size); + void* r = NULL; if (stop != NULL) - size = (size_t)(stop - whence), r = whither + size; + size = (size_t)(stop - (const char*)whence), r = whither + size; memcpy(whither, whence, size); return r; } @@ -62,10 +62,10 @@ void* memccpy(void* restrict whither, const void* restrict whence, int c, size_t */ void* memcmove(void* whither, const void* whence, int c, size_t size) { - char_t* stop = memchr(whence, c, size); - void* r = NULL + char* stop = memchr(whence, c, size); + void* r = NULL; if (stop != NULL) - size = (size_t)(stop - whence), r = whither + size; + size = (size_t)(stop - (const char*)whence), r = whither + size; memmove(whither, whence, size); return r; } diff --git a/src/string/memcpy.c b/src/string/memcpy.c index 4582544..02479cd 100644 --- a/src/string/memcpy.c +++ b/src/string/memcpy.c @@ -18,6 +18,9 @@ #include <string.h> +# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers" + + /** * Copy a memory segment to another, non-overlapping, segment. @@ -30,10 +33,11 @@ void* memcpy(void* restrict whither, const void* restrict whence, size_t size) { /* TODO improve implementation of memcpy */ - void* r = whither; + char* d = whither; + char* s = whence; while (size--) - *whither++ = *whence++; - return r; + *d++ = *s++; + return whither; } diff --git a/src/string/memfrob.c b/src/string/memfrob.c index e43496a..7ec9abd 100644 --- a/src/string/memfrob.c +++ b/src/string/memfrob.c @@ -16,7 +16,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <string.h> -#include <stddef.h> diff --git a/src/string/strcat.c b/src/string/strcat.c index ed10cc2..2205f39 100644 --- a/src/string/strcat.c +++ b/src/string/strcat.c @@ -16,7 +16,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <string.h> -#include <stddef.h> diff --git a/src/string/strchr.c b/src/string/strchr.c index 21345d4..2b49c2e 100644 --- a/src/string/strchr.c +++ b/src/string/strchr.c @@ -16,7 +16,9 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <string.h> -#include <stddef.h> + + +# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers" @@ -31,9 +33,10 @@ */ void* memchr(const void* segment, int c, size_t size) { + char* s = segment; while (size--) - if (*segment++ == c) - return segment - 1; + if (*s++ == c) + return s - 1; return NULL; } @@ -50,9 +53,10 @@ void* memchr(const void* segment, int c, size_t size) */ void* rawmemchr(const void* segment, int c) { + char* s = segment; for (;;) - if (*segment++ == c) - return segment - 1; + if (*s++ == c) + return s - 1; } @@ -71,9 +75,10 @@ void* rawmemchr(const void* segment, int c) */ void* memrchr(const void* segment, int c, size_t size) { + char* s = segment; while (size--) - if (segment[size] == c) - return segment + size; + if (s[size] == c) + return s + size; return NULL; } diff --git a/src/string/strcmp.c b/src/string/strcmp.c index 966bb06..f626f91 100644 --- a/src/string/strcmp.c +++ b/src/string/strcmp.c @@ -17,7 +17,6 @@ */ #include <string.h> #include <strings.h> -#include <stddef.h> #include <inttypes.h> #include <ctype.h> diff --git a/src/string/strcpy.c b/src/string/strcpy.c index dfbdc75..17dd339 100644 --- a/src/string/strcpy.c +++ b/src/string/strcpy.c @@ -16,7 +16,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <string.h> -#include <stddef.h> @@ -93,7 +92,7 @@ char* strstrcpy(char* restrict whither, const char* restrict whence, const char* { const char* stop = str == NULL ? NULL : strstr(whence, str); size_t n = stop == NULL ? strlen(whence) : (size_t)(stop - whence); - char* r = stop == NULL ? NULL ? whither + n; + char* r = stop == NULL ? NULL : (whither + n); memcpy(whither, whence, n); whither[n] = 0; return r; diff --git a/src/string/strdup.c b/src/string/strdup.c index c65970e..c23548b 100644 --- a/src/string/strdup.c +++ b/src/string/strdup.c @@ -16,7 +16,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <string.h> -#include <stddef.h> diff --git a/src/string/strerror.c b/src/string/strerror.c index 7366f63..87f3261 100644 --- a/src/string/strerror.c +++ b/src/string/strerror.c @@ -16,7 +16,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <string.h> -#include <stddef.h> +#include <errno.h> diff --git a/src/string/strfry.c b/src/string/strfry.c index f020202..cf8d643 100644 --- a/src/string/strfry.c +++ b/src/string/strfry.c @@ -34,13 +34,16 @@ char* strfry(char* anagram) { size_t i, j; + int r; char t; if (anagram == NULL) return NULL; for (i = strlen(anagram); --i;) { - j = (int)((double)rand() / (RAND_MAX + 1)); + r = rand(); + j = (int)((double)r / (RAND_MAX + 1)); t = anagram[i], anagram[i] = anagram[j], anagram[j] = t; } + return anagram; } diff --git a/src/string/strlen.c b/src/string/strlen.c index 7023cc0..7a08fa0 100644 --- a/src/string/strlen.c +++ b/src/string/strlen.c @@ -16,7 +16,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <string.h> -#include <stddef.h> diff --git a/src/string/strmove.c b/src/string/strmove.c index 86298cf..596822a 100644 --- a/src/string/strmove.c +++ b/src/string/strmove.c @@ -16,7 +16,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <string.h> -#include <stddef.h> @@ -97,7 +96,7 @@ char* strstrmove(char* whither, const char* whence, const char* restrict str) { const char* stop = str == NULL ? NULL : strstr(whence, str); size_t n = stop == NULL ? strlen(whence) : (size_t)(stop - whence); - char* r = stop == NULL ? NULL ? whither + n; + char* r = stop == NULL ? NULL : (whither + n); memmove(whither, whence, n); whither[n] = 0; return r; diff --git a/src/string/strspn.c b/src/string/strspn.c index cf82529..3facfd8 100644 --- a/src/string/strspn.c +++ b/src/string/strspn.c @@ -16,7 +16,9 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <string.h> -#include <stddef.h> + + +# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers" @@ -59,7 +61,7 @@ size_t strcspn(const char* string, const char* stopset) char c; const char* s = string; memset(set, 0, 256); - while ((c = *skipset++)) + while ((c = *stopset++)) set[(size_t)c] = 1; while ((c = *s++)) if (!set[(size_t)c]) @@ -86,7 +88,7 @@ char* stpbrk(const char* string, const char* stopset) char c; const char* s = string; memset(set, 0, 256); - while ((c = *skipset++)) + while ((c = *stopset++)) set[(size_t)c] = 1; while ((c = *s++)) if (!set[(size_t)c]) diff --git a/src/string/strstr.c b/src/string/strstr.c index a7e490a..68cc647 100644 --- a/src/string/strstr.c +++ b/src/string/strstr.c @@ -16,7 +16,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <string.h> -#include <stddef.h> #include <inttypes.h> diff --git a/src/string/strtok.c b/src/string/strtok.c index 04668fc..1520431 100644 --- a/src/string/strtok.c +++ b/src/string/strtok.c @@ -16,7 +16,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <string.h> -#include <stddef.h> @@ -102,7 +101,7 @@ char* strsep(char** restrict string, const char* restrict delimiters) if (r == NULL) return NULL; - next = stpbrk(string, delimiters); + next = stpbrk(r, delimiters); if (next != NULL) *next++ = 0; *string = next; diff --git a/src/strings/bzero.c b/src/strings/bzero.c index ab7a5f8..4be0948 100644 --- a/src/strings/bzero.c +++ b/src/strings/bzero.c @@ -23,7 +23,7 @@ /** * `memset`, except calls to it cannot be removed by the compiler. */ -void* (volatile *__slibc_explicit_memset)(void*, int, size_t) = memset; +void* (*volatile __slibc_explicit_memset)(void*, int, size_t) = memset; diff --git a/src/wchar/wcscat.c b/src/wchar/wcscat.c index c7b1c5e..491f9b7 100644 --- a/src/wchar/wcscat.c +++ b/src/wchar/wcscat.c @@ -16,7 +16,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <wchar.h> -#include <stddef.h> @@ -55,7 +54,7 @@ wchar_t* wcscat(wchar_t* restrict whither, const wchar_t* restrict whence) */ wchar_t* wcsncat(wchar_t* restrict whither, const wchar_t* restrict whence, size_t maxlen) { - wcsncpy(whither + wcslen(whither), whence, laxmen); + wcsncpy(whither + wcslen(whither), whence, maxlen); return whither; } diff --git a/src/wchar/wcschr.c b/src/wchar/wcschr.c index 493f0a7..16ecac2 100644 --- a/src/wchar/wcschr.c +++ b/src/wchar/wcschr.c @@ -16,7 +16,9 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <wchar.h> -#include <stddef.h> + + +# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers" diff --git a/src/wchar/wcscmp.c b/src/wchar/wcscmp.c index ebac2df..c9d1180 100644 --- a/src/wchar/wcscmp.c +++ b/src/wchar/wcscmp.c @@ -16,7 +16,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <wchar.h> -#include <stddef.h> #include <inttypes.h> #include <wctype.h> diff --git a/src/wchar/wcscpy.c b/src/wchar/wcscpy.c index 7d75a98..37b8ed4 100644 --- a/src/wchar/wcscpy.c +++ b/src/wchar/wcscpy.c @@ -16,7 +16,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <wchar.h> -#include <stddef.h> @@ -67,9 +66,9 @@ wchar_t* wcpcpy(wchar_t* restrict whither, const wchar_t* restrict whence) * one character passed the last written non-NUL * character. */ -wchar_t* wcsccpy(wchar_t* restrict whither, const wchar_t* restrict whence, wchat_t c) +wchar_t* wcsccpy(wchar_t* restrict whither, const wchar_t* restrict whence, wchar_t c) { - wchar_t* r = wmemccopy(whither, whence, c, wcslen(whence) + 1); + wchar_t* r = wmemccpy(whither, whence, c, wcslen(whence) + 1); if (r) *r = 0; return r; @@ -96,7 +95,7 @@ wchar_t* wcswcscpy(wchar_t* restrict whither, const wchar_t* restrict whence, co { const wchar_t* stop = str == NULL ? NULL : wcsstr(whence, str); size_t n = stop == NULL ? wcslen(whence) : (size_t)(stop - whence); - wchar_t* r = stop == NULL ? NULL ? whither + n; + wchar_t* r = stop == NULL ? NULL : (whither + n); wmemcpy(whither, whence, n); whither[n] = 0; return r; @@ -176,11 +175,11 @@ wchar_t* wcpncpy(wchar_t* restrict whither, const wchar_t* restrict whence, size * one character passed the last written non-NUL * character. */ -wchar_t* wcscncpy(wchar_t* restrict whither, const wchar_t* restrict whence, wchat_t c, size_t maxlen) +wchar_t* wcscncpy(wchar_t* restrict whither, const wchar_t* restrict whence, wchar_t c, size_t maxlen) { - const char* stop = wmemchr(whence, c, maxlen); + const wchar_t* stop = wmemchr(whence, c, maxlen); size_t n = stop == NULL ? wcsnlen(whence, maxlen) : (size_t)(stop - whence); - char* r = stop == NULL ? NULL : (whither + n); + wchar_t* r = stop == NULL ? NULL : (whither + n); wmemcpy(whither, whence, n); wmemset(whither, 0, maxlen - n); return r; @@ -213,9 +212,9 @@ wchar_t* wcscncpy(wchar_t* restrict whither, const wchar_t* restrict whence, wch wchar_t* wcswcsncpy(wchar_t* restrict whither, const wchar_t* restrict whence, const wchar_t* restrict str, size_t maxlen) { - const char* stop = wcsnstr(whence, str, maxlen); + const wchar_t* stop = wcsnstr(whence, str, maxlen); size_t n = stop == NULL ? wcsnlen(whence, maxlen) : (size_t)(stop - whence); - char* r = stop == NULL ? NULL : (whither + n); + wchar_t* r = stop == NULL ? NULL : (whither + n); wmemcpy(whither, whence, n); wmemset(whither, 0, maxlen - n); return r; diff --git a/src/wchar/wcsdup.c b/src/wchar/wcsdup.c index dbbbb4c..37b57f9 100644 --- a/src/wchar/wcsdup.c +++ b/src/wchar/wcsdup.c @@ -16,7 +16,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <wchar.h> -#include <stddef.h> diff --git a/src/wchar/wcslen.c b/src/wchar/wcslen.c index ad81227..b4a07c6 100644 --- a/src/wchar/wcslen.c +++ b/src/wchar/wcslen.c @@ -16,7 +16,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <wchar.h> -#include <stddef.h> diff --git a/src/wchar/wcsmove.c b/src/wchar/wcsmove.c index c84e4ee..bf86928 100644 --- a/src/wchar/wcsmove.c +++ b/src/wchar/wcsmove.c @@ -16,7 +16,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <wchar.h> -#include <stddef.h> @@ -69,7 +68,7 @@ wchar_t* wcpmove(wchar_t* whither, const wchar_t* whence) * one character passed the last written non-NUL * character. */ -wchar_t* wcscmove(wchar_t* whither, const wchar_t* whence, wchat_t c) +wchar_t* wcscmove(wchar_t* whither, const wchar_t* whence, wchar_t c) { wchar_t* r = wmemcmove(whither, whence, c, wcslen(whence) + 1); if (r) @@ -98,7 +97,7 @@ wchar_t* wcswcsmove(wchar_t* whither, const wchar_t* whence, const wchar_t* rest { const wchar_t* stop = str == NULL ? NULL : wcsstr(whence, str); size_t n = stop == NULL ? wcslen(whence) : (size_t)(stop - whence); - wchar_t* r = stop == NULL ? NULL ? whither + n; + wchar_t* r = stop == NULL ? NULL : (whither + n); wmemmove(whither, whence, n); whither[n] = 0; return r; @@ -179,11 +178,11 @@ wchar_t* wcpnmove(wchar_t* whither, const wchar_t* whence, size_t maxlen) * one character passed the last written non-NUL * character. */ -wchar_t* wcscnmove(wchar_t* whither, const wchar_t* whence, wchat_t c, size_t maxlen) +wchar_t* wcscnmove(wchar_t* whither, const wchar_t* whence, wchar_t c, size_t maxlen) { - const char* stop = wmemchr(whence, c, maxlen); + const wchar_t* stop = wmemchr(whence, c, maxlen); size_t n = stop == NULL ? wcsnlen(whence, maxlen) : (size_t)(stop - whence); - char* r = stop == NULL ? NULL : (whither + n); + wchar_t* r = stop == NULL ? NULL : (whither + n); wmemmove(whither, whence, n); wmemset(whither, 0, maxlen - n); return r; @@ -215,9 +214,9 @@ wchar_t* wcscnmove(wchar_t* whither, const wchar_t* whence, wchat_t c, size_t ma */ wchar_t* wcswcsnmove(wchar_t* whither, const wchar_t* whence, const wchar_t* restrict str, size_t maxlen) { - const char* stop = wcsnstr(whence, str, maxlen); + const wchar_t* stop = wcsnstr(whence, str, maxlen); size_t n = stop == NULL ? wcsnlen(whence, maxlen) : (size_t)(stop - whence); - char* r = stop == NULL ? NULL : (whither + n); + wchar_t* r = stop == NULL ? NULL : (whither + n); wmemmove(whither, whence, n); wmemset(whither, 0, maxlen - n); return r; diff --git a/src/wchar/wcsspn.c b/src/wchar/wcsspn.c index 360ab5f..d0ce908 100644 --- a/src/wchar/wcsspn.c +++ b/src/wchar/wcsspn.c @@ -16,7 +16,9 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <wchar.h> -#include <stddef.h> + + +# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers" @@ -54,7 +56,7 @@ size_t wcscspn(const wchar_t* string, const wchar_t* stopset) size_t end = wcslen(string); wchar_t* p; wchar_t c; - while ((c = *skipset++)) + while ((c = *stopset++)) if (p = wcsnchr(string, c, end), p != NULL) end = (size_t)(p - string); return end; diff --git a/src/wchar/wcsstr.c b/src/wchar/wcsstr.c index bba7d96..0ae7b71 100644 --- a/src/wchar/wcsstr.c +++ b/src/wchar/wcsstr.c @@ -16,7 +16,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <wchar.h> -#include <stddef.h> #include <inttypes.h> #define WIDE diff --git a/src/wchar/wcstok.c b/src/wchar/wcstok.c index 1598d07..2694dc0 100644 --- a/src/wchar/wcstok.c +++ b/src/wchar/wcstok.c @@ -16,7 +16,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <wchar.h> -#include <stddef.h> @@ -80,7 +79,7 @@ wchar_t* wcssep(wchar_t** restrict string, const wchar_t* restrict delimiters) if (r == NULL) return NULL; - next = wcpbrk(string, delimiters); + next = wcpbrk(r, delimiters); if (next != NULL) *next++ = 0; *string = next; diff --git a/src/wchar/wmemccpy.c b/src/wchar/wmemccpy.c index fbabe0b..cde1a6a 100644 --- a/src/wchar/wmemccpy.c +++ b/src/wchar/wmemccpy.c @@ -38,10 +38,10 @@ wchar_t* wmemccpy(wchar_t* restrict whither, const wchar_t* restrict whence, wchar_t c, size_t size) { wchar_t* stop = wmemchr(whence, c, size); - wchar_t* r = NULL + wchar_t* r = NULL; if (stop != NULL) size = (size_t)(stop - whence), r = whither + size; - memcpy(whither, whence, size); + wmemcpy(whither, whence, size); return r; } @@ -65,10 +65,10 @@ wchar_t* wmemccpy(wchar_t* restrict whither, const wchar_t* restrict whence, wch wchar_t* wmemcmove(wchar_t* whither, const wchar_t* whence, wchar_t c, size_t size) { wchar_t* stop = wmemchr(whence, c, size); - wchar_t* r = NULL + wchar_t* r = NULL; if (stop != NULL) size = (size_t)(stop - whence), r = whither + size; - memmove(whither, whence, size); + wmemmove(whither, whence, size); return r; } diff --git a/src/wchar/wmemset.c b/src/wchar/wmemset.c index 2a60b45..95ec70f 100644 --- a/src/wchar/wmemset.c +++ b/src/wchar/wmemset.c @@ -27,7 +27,7 @@ * @param size The number of wide characters in the memory segment. * @return `segment` is returned. */ -wchar_t* wmemset(wchar_t* segment, wchar_t c, size_t size); +wchar_t* wmemset(wchar_t* segment, wchar_t c, size_t size) { wchar_t* r = segment; while (size--) |