aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.clang-format7
-rw-r--r--.gitignore25
-rw-r--r--io.h1
-rw-r--r--io/asprintf.c10
-rw-r--r--io/aswprintf.c11
-rw-r--r--io/fgets.c15
-rw-r--r--io/fgetws.c15
-rw-r--r--io/fprintf.c10
-rw-r--r--io/fputs.c11
-rw-r--r--io/fputws.c11
-rw-r--r--io/fscanf.c10
-rw-r--r--io/fwprinf.c10
-rw-r--r--io/fwscanf.c10
-rw-r--r--io/getchar.c3
-rw-r--r--io/gets.c18
-rw-r--r--io/getwchar.c4
-rw-r--r--io/io.h54
-rw-r--r--io/meson.build43
-rw-r--r--io/perror.c10
-rw-r--r--io/printf.c10
-rw-r--r--io/putchar.c6
-rw-r--r--io/puts.c10
-rw-r--r--io/putwchar.c7
-rw-r--r--io/rewind.c4
-rw-r--r--io/scanf.c10
-rw-r--r--io/setbuf.c8
-rw-r--r--io/snprintf.c10
-rw-r--r--io/sprintf.c10
-rw-r--r--io/sscanf.c10
-rw-r--r--io/swprintf.c11
-rw-r--r--io/swscanf.c10
-rw-r--r--io/vasprintf.c18
-rw-r--r--io/vaswprintf.c18
-rw-r--r--io/vprintf.c6
-rw-r--r--io/vscanf.c6
-rw-r--r--io/vsprintf.c7
-rw-r--r--io/vwprintf.c6
-rw-r--r--io/vwscanf.c6
-rw-r--r--io/wprinf.c10
-rw-r--r--io/wrap/feof.c11
-rw-r--r--io/wrap/fgetc.c4
-rw-r--r--io/wrap/fgetwc.c4
-rw-r--r--io/wrap/fputc.c7
-rw-r--r--io/wrap/fputwc.c7
-rw-r--r--io/wrap/io.h56
-rw-r--r--io/wrap/meson.build16
-rw-r--r--io/wrap/setvbuf.c8
-rw-r--r--io/wrap/stdstream.c16
-rw-r--r--io/wrap/vfprintf.c7
-rw-r--r--io/wrap/vfscanf.c7
-rw-r--r--io/wrap/vfwprinf.c8
-rw-r--r--io/wrap/vfwscanf.c8
-rw-r--r--io/wrap/vsnprintf.c9
-rw-r--r--io/wrap/vsscanf.c8
-rw-r--r--io/wrap/vswprintf.c9
-rw-r--r--io/wrap/vswscanf.c9
-rw-r--r--io/wscanf.c10
-rw-r--r--license22
-rw-r--r--math.h1
-rw-r--r--math/abs.c3
-rw-r--r--math/div.c7
-rw-r--r--math/fabs.c3
-rw-r--r--math/fabsf.c3
-rw-r--r--math/fabsl.c3
-rw-r--r--math/imaxabs.c3
-rw-r--r--math/imaxdiv.c7
-rw-r--r--math/labs.c3
-rw-r--r--math/ldiv.c7
-rw-r--r--math/llabs.c3
-rw-r--r--math/lldiv.c7
-rw-r--r--math/maths.h41
-rw-r--r--math/meson.build13
-rw-r--r--math/wrap/meson.build2
-rw-r--r--memory.h1
-rw-r--r--memory/atof.c3
-rw-r--r--memory/atoi.c3
-rw-r--r--memory/atol.c3
-rw-r--r--memory/atoll.c3
-rw-r--r--memory/calloc.c9
-rw-r--r--memory/memccmp.c14
-rw-r--r--memory/memccpy.c14
-rw-r--r--memory/memchr.c10
-rw-r--r--memory/memcmp.c10
-rw-r--r--memory/memcpy.c8
-rw-r--r--memory/memlchr.c10
-rw-r--r--memory/memmove.c13
-rw-r--r--memory/memory.h100
-rw-r--r--memory/mempcpy.c11
-rw-r--r--memory/memrchr.c10
-rw-r--r--memory/memset.c10
-rw-r--r--memory/meson.build84
-rw-r--r--memory/rawmemccmp.c13
-rw-r--r--memory/rawmemccpy.c13
-rw-r--r--memory/rawmemchr.c9
-rw-r--r--memory/rawmemlchr.c9
-rw-r--r--memory/reallocarray.c12
-rw-r--r--memory/stpcpy.c6
-rw-r--r--memory/stpncpy.c9
-rw-r--r--memory/strcat.c7
-rw-r--r--memory/strchr.c6
-rw-r--r--memory/strcmp.c6
-rw-r--r--memory/strcoll.c28
-rw-r--r--memory/strcpy.c7
-rw-r--r--memory/strdup.c10
-rw-r--r--memory/strlcat.c11
-rw-r--r--memory/strlcpy.c9
-rw-r--r--memory/strlen.c3
-rw-r--r--memory/strncat.c9
-rw-r--r--memory/strncmp.c6
-rw-r--r--memory/strncpy.c7
-rw-r--r--memory/strndup.c10
-rw-r--r--memory/strnlen.c6
-rw-r--r--memory/strnlen_s.c6
-rw-r--r--memory/strrchr.c6
-rw-r--r--memory/wcscat.c7
-rw-r--r--memory/wcschr.c6
-rw-r--r--memory/wcscmp.c6
-rw-r--r--memory/wcscoll.c28
-rw-r--r--memory/wcscpy.c7
-rw-r--r--memory/wcsdup.c10
-rw-r--r--memory/wcslcat.c11
-rw-r--r--memory/wcslcpy.c9
-rw-r--r--memory/wcslen.c3
-rw-r--r--memory/wcsncat.c9
-rw-r--r--memory/wcsncmp.c6
-rw-r--r--memory/wcsncpy.c7
-rw-r--r--memory/wcsndup.c10
-rw-r--r--memory/wcsnlen.c6
-rw-r--r--memory/wcsnlen_s.c6
-rw-r--r--memory/wcspcpy.c6
-rw-r--r--memory/wcspncpy.c9
-rw-r--r--memory/wcsrchr.c6
-rw-r--r--memory/wmemccmp.c14
-rw-r--r--memory/wmemccpy.c13
-rw-r--r--memory/wmemchr.c9
-rw-r--r--memory/wmemcmp.c10
-rw-r--r--memory/wmemcpy.c8
-rw-r--r--memory/wmemlchr.c9
-rw-r--r--memory/wmemmove.c12
-rw-r--r--memory/wmempcpy.c10
-rw-r--r--memory/wmemrchr.c9
-rw-r--r--memory/wmemset.c8
-rw-r--r--memory/wrap/free.c4
-rw-r--r--memory/wrap/memory.h25
-rw-r--r--memory/wrap/meson.build13
-rw-r--r--memory/wrap/realloc.c4
-rw-r--r--memory/wrap/strtod.c7
-rw-r--r--memory/wrap/strtol.c8
-rw-r--r--memory/wrap/strtoll.c8
-rw-r--r--memory/wrap/strxfrm.c8
-rw-r--r--memory/wrap/wcstod.c7
-rw-r--r--memory/wrap/wcstol.c8
-rw-r--r--memory/wrap/wcstoll.c8
-rw-r--r--memory/wrap/wcsxfrm.c8
-rw-r--r--memory/wrawmemccmp.c12
-rw-r--r--memory/wrawmemccpy.c11
-rw-r--r--memory/wrawmemchr.c8
-rw-r--r--memory/wrawmemlchr.c8
-rw-r--r--memory/wtof.c3
-rw-r--r--memory/wtoi.c3
-rw-r--r--memory/wtol.c3
-rw-r--r--memory/wtoll.c6
-rw-r--r--meson.build37
-rw-r--r--readme.md11
-rw-r--r--test.c8
165 files changed, 1789 insertions, 0 deletions
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..07bc4e0
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,7 @@
+BasedOnStyle: LLVM
+IndentWidth: 8
+UseTab: Always
+BreakBeforeBraces: Linux
+AllowShortIfStatementsOnASingleLine: false
+IndentCaseLabels: true
+IndentPPDirectives: BeforeHash
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..35df969
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,25 @@
+*.o
+*.ko
+*.obj
+*.elf
+*.gch
+*.pch
+*.dll
+*.so
+*.so.*
+*.dylib
+*.exe
+*.out
+*.app
+*.pdb
+/build*/
+/subprojects/*
+!/subprojects/*.wrap
+meson-logs
+meson-private
+meson_benchmark_setup.dat
+meson_test_setup.dat
+build.ninja
+.ninja_deps
+.ninja_logs
+compile_commands.json
diff --git a/io.h b/io.h
new file mode 100644
index 0000000..e142d5a
--- /dev/null
+++ b/io.h
@@ -0,0 +1 @@
+#include "io/io.h"
diff --git a/io/asprintf.c b/io/asprintf.c
new file mode 100644
index 0000000..5a4a641
--- /dev/null
+++ b/io/asprintf.c
@@ -0,0 +1,10 @@
+#include "io.h"
+
+int asprintf(char **string, char const *restrict format, ...)
+{
+ va_list arg;
+ va_start(arg, format);
+ int lenght = vasprintf(string, format, arg);
+ va_end(arg);
+ return lenght;
+}
diff --git a/io/aswprintf.c b/io/aswprintf.c
new file mode 100644
index 0000000..d65094e
--- /dev/null
+++ b/io/aswprintf.c
@@ -0,0 +1,11 @@
+#define NO_OPAQUE_TYPE
+#include "io.h"
+
+int aswprintf(wchar_t **string, wchar_t const *restrict format, ...)
+{
+ va_list arg;
+ va_start(arg, format);
+ int lenght = vaswprintf(string, format, arg);
+ va_end(arg);
+ return lenght;
+}
diff --git a/io/fgets.c b/io/fgets.c
new file mode 100644
index 0000000..69cd1be
--- /dev/null
+++ b/io/fgets.c
@@ -0,0 +1,15 @@
+#include "io.h"
+#include <errno.h>
+
+char* fgets(char *restrict string, int size, FILE *restrict stream)
+{
+ int character = 0;
+ for(int i=0;character == '\n' || i < size -1;i++){
+ character = _fgetc_wrap(stream);
+ if(character == _eof_wrap){
+ return NULL;
+ }
+ }
+
+ return string;
+}
diff --git a/io/fgetws.c b/io/fgetws.c
new file mode 100644
index 0000000..69cd1be
--- /dev/null
+++ b/io/fgetws.c
@@ -0,0 +1,15 @@
+#include "io.h"
+#include <errno.h>
+
+char* fgets(char *restrict string, int size, FILE *restrict stream)
+{
+ int character = 0;
+ for(int i=0;character == '\n' || i < size -1;i++){
+ character = _fgetc_wrap(stream);
+ if(character == _eof_wrap){
+ return NULL;
+ }
+ }
+
+ return string;
+}
diff --git a/io/fprintf.c b/io/fprintf.c
new file mode 100644
index 0000000..d8a3480
--- /dev/null
+++ b/io/fprintf.c
@@ -0,0 +1,10 @@
+#include "io.h"
+
+int fprintf(FILE *stream, char const *restrict format, ...)
+{
+ va_list arg;
+ va_start(arg, format);
+ int lenght = _vfprintf_wrap(stream, format, arg);
+ va_end(arg);
+ return lenght;
+}
diff --git a/io/fputs.c b/io/fputs.c
new file mode 100644
index 0000000..f121253
--- /dev/null
+++ b/io/fputs.c
@@ -0,0 +1,11 @@
+#include "io.h"
+#include <errno.h>
+
+int fputs(char const *restrict string, FILE *restrict stream)
+{
+
+ for (size_t i = 0; string[i]; ++i) {
+ if(_fputc_wrap(string[i], stream)==_eof_wrap){return _eof_wrap;};
+ }
+ return 0;
+}
diff --git a/io/fputws.c b/io/fputws.c
new file mode 100644
index 0000000..f121253
--- /dev/null
+++ b/io/fputws.c
@@ -0,0 +1,11 @@
+#include "io.h"
+#include <errno.h>
+
+int fputs(char const *restrict string, FILE *restrict stream)
+{
+
+ for (size_t i = 0; string[i]; ++i) {
+ if(_fputc_wrap(string[i], stream)==_eof_wrap){return _eof_wrap;};
+ }
+ return 0;
+}
diff --git a/io/fscanf.c b/io/fscanf.c
new file mode 100644
index 0000000..575a5f5
--- /dev/null
+++ b/io/fscanf.c
@@ -0,0 +1,10 @@
+#include "io.h"
+
+int fscanf(FILE *stream, char const *restrict format, ...)
+{
+ va_list arg;
+ va_start(arg, format);
+ int lenght = _vfscanf_wrap(stream, format, arg);
+ va_end(arg);
+ return lenght;
+}
diff --git a/io/fwprinf.c b/io/fwprinf.c
new file mode 100644
index 0000000..a382ccb
--- /dev/null
+++ b/io/fwprinf.c
@@ -0,0 +1,10 @@
+#include "io.h"
+
+int fwprintf(FILE *stream, wchar_t const *restrict format, ...)
+{
+ va_list arg;
+ va_start(arg, format);
+ int lenght = _vfwprintf_wrap(stream, format, arg);
+ va_end(arg);
+ return lenght;
+}
diff --git a/io/fwscanf.c b/io/fwscanf.c
new file mode 100644
index 0000000..f731b5b
--- /dev/null
+++ b/io/fwscanf.c
@@ -0,0 +1,10 @@
+#include "io.h"
+
+int fwscanf(FILE *stream, wchar_t const *restrict format, ...)
+{
+ va_list arg;
+ va_start(arg, format);
+ int lenght = _vfwscanf_wrap(stream, format, arg);
+ va_end(arg);
+ return lenght;
+}
diff --git a/io/getchar.c b/io/getchar.c
new file mode 100644
index 0000000..57d26c4
--- /dev/null
+++ b/io/getchar.c
@@ -0,0 +1,3 @@
+#include "io.h"
+
+int getchar(void) { return _fgetc_wrap(_stdstream_wrap(stream_input)); }
diff --git a/io/gets.c b/io/gets.c
new file mode 100644
index 0000000..0309181
--- /dev/null
+++ b/io/gets.c
@@ -0,0 +1,18 @@
+#include "io.h"
+#include <errno.h>
+
+char* gets(char *string)
+{
+ size_t i='\0';
+ for(int character = 0;character == '\n';i++){
+ character = getchar();
+ if(character == _eof_wrap){
+ return NULL;
+ }
+ string[i]=character;
+ }
+
+ string[++i]='\0';
+
+ return string;
+}
diff --git a/io/getwchar.c b/io/getwchar.c
new file mode 100644
index 0000000..a949a48
--- /dev/null
+++ b/io/getwchar.c
@@ -0,0 +1,4 @@
+#define NEED_WINT
+#include "io.h"
+
+wint_t getwchar(void) { return fgetwc(_stdstream_wrap(stream_input)); }
diff --git a/io/io.h b/io/io.h
new file mode 100644
index 0000000..488f589
--- /dev/null
+++ b/io/io.h
@@ -0,0 +1,54 @@
+#if !defined(IO_H)
+ #define IO_H
+
+ #include <stdarg.h>
+ #include <stddef.h>
+
+ #if __STDC_HOSTED__ == 1
+ #include "wrap/io.h"
+
+extern void setbuf(FILE *restrict, char *restrict);
+extern void rewind(FILE *);
+
+extern int getchar(void);
+extern int putchar(int);
+extern int puts(char const *restrict);
+extern int fputs(char const *restrict,FILE *restrict);
+
+ #if defined(NEED_WINT)
+extern wint_t getwchar(void);
+extern wint_t putwchar(wchar_t);
+ #endif
+
+extern void perror(char const *);
+
+extern int fprintf(FILE *, char const *restrict, ...);
+extern int printf(char const *restrict, ...);
+extern int snprintf(char *, size_t, char const *restrict, ...);
+extern int asprintf(char **restrict, char const *restrict, ...);
+extern int sprintf(char *, char const *restrict, ...);
+extern int vprintf(char const *restrict, va_list);
+extern int vsprintf(char *, char const *restrict, va_list);
+extern int vasprintf(char **restrict, char const *restrict, va_list);
+extern int fwprintf(FILE *, wchar_t const *restrict, ...);
+extern int wprintf(wchar_t const *restrict, ...);
+extern int swprintf(wchar_t *, size_t, wchar_t const *restrict, ...);
+extern int aswprintf(wchar_t **restrict, wchar_t const *restrict,
+ ...);
+extern int vwprintf(wchar_t const *restrict, va_list);
+extern int vaswprintf(wchar_t **restrict, wchar_t const *restrict,
+ va_list);
+
+extern int fscanf(FILE *, char const *restrict, ...);
+extern int scanf(char const *restrict, ...);
+extern int sscanf(char const *restrict, char const *restrict, ...);
+extern int vscanf(char const *restrict, va_list);
+extern int fwscanf(FILE *, wchar_t const *restrict, ...);
+extern int swscanf(wchar_t const *restrict, wchar_t const *restrict,
+ ...);
+extern int vwscanf(wchar_t const *restrict, va_list);
+extern int wscanf(wchar_t const *restrict, ...);
+
+ #endif
+
+#endif
diff --git a/io/meson.build b/io/meson.build
new file mode 100644
index 0000000..a815a56
--- /dev/null
+++ b/io/meson.build
@@ -0,0 +1,43 @@
+if is_hosted == 1
+subdir('wrap')
+sources += files(
+'io.h',
+'printf.c',
+'fprintf.c',
+'snprintf.c',
+'asprintf.c',
+'sprintf.c',
+'vprintf.c',
+'vsprintf.c',
+'wprinf.c',
+'fwprinf.c',
+'aswprintf.c',
+'swprintf.c',
+'vwprintf.c',
+'vaswprintf.c',
+'perror.c',
+'setbuf.c',
+'fread.c',
+'fwrite.c',
+'gets.c',
+'fgets.c',
+'getws.c',
+'fgetws.c',
+'getchar.c',
+'getwchar.c',
+'puts.c'
+'fputs.c'
+'putws.c'
+'fputws.c'
+'putchar.c',
+'putwchar.c',
+'scanf.c',
+'vwscanf.c',
+'vscanf.c',
+'swscanf.c',
+'sscanf.c',
+'fwscanf.c',
+'fscanf.c',
+'wscanf.c'
+)
+endif
diff --git a/io/perror.c b/io/perror.c
new file mode 100644
index 0000000..df8a09f
--- /dev/null
+++ b/io/perror.c
@@ -0,0 +1,10 @@
+#include "io.h"
+#include <errno.h>
+#include <string.h>
+
+void perror(char const *string)
+{
+
+ fprintf(_stdstream_wrap(stream_error), "%s: %s", string,
+ strerror(errno));
+}
diff --git a/io/printf.c b/io/printf.c
new file mode 100644
index 0000000..da4036d
--- /dev/null
+++ b/io/printf.c
@@ -0,0 +1,10 @@
+#include "io.h"
+
+int printf(char const *restrict format, ...)
+{
+ va_list arg;
+ va_start(arg, format);
+ int lenght = vprintf(format, arg);
+ va_end(arg);
+ return lenght;
+}
diff --git a/io/putchar.c b/io/putchar.c
new file mode 100644
index 0000000..ecba6dc
--- /dev/null
+++ b/io/putchar.c
@@ -0,0 +1,6 @@
+#include "io.h"
+
+int putchar(int character)
+{
+ return _fputc_wrap(character, _stdstream_wrap(stream_output));
+}
diff --git a/io/puts.c b/io/puts.c
new file mode 100644
index 0000000..26c477f
--- /dev/null
+++ b/io/puts.c
@@ -0,0 +1,10 @@
+#include "io.h"
+#include <errno.h>
+
+int puts(char const *string)
+{
+ if (fputs(string, _stdstream_wrap(stream_output)) == _eof_wrap) {
+ return _eof_wrap;
+ }
+ return putchar('\n');
+}
diff --git a/io/putwchar.c b/io/putwchar.c
new file mode 100644
index 0000000..c4fdf47
--- /dev/null
+++ b/io/putwchar.c
@@ -0,0 +1,7 @@
+#define NEED_WINT
+#include "io.h"
+
+wint_t putwchar(wchar_t character)
+{
+ return fputwc(character, _stdstream_wrap(stream_output));
+}
diff --git a/io/rewind.c b/io/rewind.c
new file mode 100644
index 0000000..9e0d2ee
--- /dev/null
+++ b/io/rewind.c
@@ -0,0 +1,4 @@
+#define NO_OPAQUE_TYPE
+#include "io.h"
+
+void rewind(FILE *stream) { fseek(stream, 0L, SEEK_SET); }
diff --git a/io/scanf.c b/io/scanf.c
new file mode 100644
index 0000000..51f6c10
--- /dev/null
+++ b/io/scanf.c
@@ -0,0 +1,10 @@
+#include "io.h"
+
+int scanf(char const *restrict format, ...)
+{
+ va_list arg;
+ va_start(arg, format);
+ int lenght = vscanf(format, arg);
+ va_end(arg);
+ return lenght;
+}
diff --git a/io/setbuf.c b/io/setbuf.c
new file mode 100644
index 0000000..f401770
--- /dev/null
+++ b/io/setbuf.c
@@ -0,0 +1,8 @@
+#define NO_OPAQUE_TYPE
+#include "io.h"
+
+void setbuf(FILE *restrict file, char *restrict buffer)
+{
+ (buffer == NULL) ? _setvbuf_wrap(file, NULL, _IONBF, 0)
+ : _setvbuf_wrap(file, buffer, _IOFBF, BUFSIZ);
+}
diff --git a/io/snprintf.c b/io/snprintf.c
new file mode 100644
index 0000000..c2a8f66
--- /dev/null
+++ b/io/snprintf.c
@@ -0,0 +1,10 @@
+#include "io.h"
+
+int snprintf(char *string, size_t max_size, char const *restrict format, ...)
+{
+ va_list arg;
+ va_start(arg, format);
+ int lenght = _vsnprintf_wrap(string, max_size, format, arg);
+ va_end(arg);
+ return lenght;
+}
diff --git a/io/sprintf.c b/io/sprintf.c
new file mode 100644
index 0000000..cac6d80
--- /dev/null
+++ b/io/sprintf.c
@@ -0,0 +1,10 @@
+#include "io.h"
+
+int sprintf(char *string, char const *restrict format, ...)
+{
+ va_list arg;
+ va_start(arg, format);
+ int lenght = vsprintf(string, format, arg);
+ va_end(arg);
+ return lenght;
+}
diff --git a/io/sscanf.c b/io/sscanf.c
new file mode 100644
index 0000000..0490a41
--- /dev/null
+++ b/io/sscanf.c
@@ -0,0 +1,10 @@
+#include "io.h"
+
+int sscanf(char const *restrict string, char const *restrict format, ...)
+{
+ va_list arg;
+ va_start(arg, format);
+ int lenght = _vsscanf_wrap(string, format, arg);
+ va_end(arg);
+ return lenght;
+}
diff --git a/io/swprintf.c b/io/swprintf.c
new file mode 100644
index 0000000..6021dec
--- /dev/null
+++ b/io/swprintf.c
@@ -0,0 +1,11 @@
+#include "io.h"
+
+int swprintf(wchar_t *string, size_t max_size, wchar_t const *restrict format,
+ ...)
+{
+ va_list arg;
+ va_start(arg, format);
+ int lenght = _vswprintf_wrap(string, max_size, format, arg);
+ va_end(arg);
+ return lenght;
+}
diff --git a/io/swscanf.c b/io/swscanf.c
new file mode 100644
index 0000000..4605b26
--- /dev/null
+++ b/io/swscanf.c
@@ -0,0 +1,10 @@
+#include "io.h"
+
+int swscanf(wchar_t const *restrict string, wchar_t const *restrict format, ...)
+{
+ va_list arg;
+ va_start(arg, format);
+ int lenght = _vswscanf_wrap(string, format, arg);
+ va_end(arg);
+ return lenght;
+}
diff --git a/io/vasprintf.c b/io/vasprintf.c
new file mode 100644
index 0000000..24f9332
--- /dev/null
+++ b/io/vasprintf.c
@@ -0,0 +1,18 @@
+#include "../memory.h"
+#include "io.h"
+
+int vasprintf(char **string, char const *restrict format, va_list arg)
+{
+ va_list tmp;
+ va_copy(tmp, arg);
+ int lenght = _vsnprintf_wrap(NULL, 0, format, tmp);
+ va_end(tmp);
+ if (lenght < 0) {
+ return 1;
+ }
+ *string = reallocarray(NULL, (size_t)lenght + 1, sizeof *string);
+ if (*string == NULL) {
+ return 1;
+ }
+ return _vsnprintf_wrap(*string, (size_t)lenght + 1, format, arg);
+}
diff --git a/io/vaswprintf.c b/io/vaswprintf.c
new file mode 100644
index 0000000..8568dfd
--- /dev/null
+++ b/io/vaswprintf.c
@@ -0,0 +1,18 @@
+#include "../memory.h"
+#include "io.h"
+
+int vaswprintf(wchar_t **string, wchar_t const *restrict format, va_list arg)
+{
+ va_list tmp;
+ va_copy(tmp, arg);
+ int lenght = _vswprintf_wrap(NULL, 0, format, tmp);
+ va_end(tmp);
+ if (lenght < 0) {
+ return 1;
+ }
+ *string = reallocarray(NULL, (size_t)lenght + 1, sizeof *string);
+ if (*string == NULL) {
+ return 1;
+ }
+ return _vswprintf_wrap(*string, (size_t)lenght + 1, format, arg);
+}
diff --git a/io/vprintf.c b/io/vprintf.c
new file mode 100644
index 0000000..406332e
--- /dev/null
+++ b/io/vprintf.c
@@ -0,0 +1,6 @@
+#include "io.h"
+
+int vprintf(char const *restrict format, va_list arg)
+{
+ return _vfprintf_wrap(_stdstream_wrap(stream_output), format, arg);
+}
diff --git a/io/vscanf.c b/io/vscanf.c
new file mode 100644
index 0000000..edeeacd
--- /dev/null
+++ b/io/vscanf.c
@@ -0,0 +1,6 @@
+#include "io.h"
+
+int vscanf(char const *restrict format, va_list arg)
+{
+ return _vfscanf_wrap(_stdstream_wrap(stream_input), format, arg);
+}
diff --git a/io/vsprintf.c b/io/vsprintf.c
new file mode 100644
index 0000000..e260f77
--- /dev/null
+++ b/io/vsprintf.c
@@ -0,0 +1,7 @@
+#include "io.h"
+#include <limits.h>
+
+int vsprintf(char *string, char const *restrict format, va_list arg)
+{
+ return _vsnprintf_wrap(string, INT_MAX, format, arg);
+}
diff --git a/io/vwprintf.c b/io/vwprintf.c
new file mode 100644
index 0000000..12d1fd6
--- /dev/null
+++ b/io/vwprintf.c
@@ -0,0 +1,6 @@
+#include "io.h"
+
+int vwprintf(wchar_t const *restrict format, va_list arg)
+{
+ return _vfwprintf_wrap(_stdstream_wrap(stream_output), format, arg);
+}
diff --git a/io/vwscanf.c b/io/vwscanf.c
new file mode 100644
index 0000000..9b74b2f
--- /dev/null
+++ b/io/vwscanf.c
@@ -0,0 +1,6 @@
+#include "io.h"
+
+int vwscanf(wchar_t const *restrict format, va_list arg)
+{
+ return _vfwscanf_wrap(_stdstream_wrap(stream_input), format, arg);
+}
diff --git a/io/wprinf.c b/io/wprinf.c
new file mode 100644
index 0000000..f441eda
--- /dev/null
+++ b/io/wprinf.c
@@ -0,0 +1,10 @@
+#include "io.h"
+
+int wprintf(wchar_t const *restrict format, ...)
+{
+ va_list arg;
+ va_start(arg, format);
+ int lenght = vwprintf(format, arg);
+ va_end(arg);
+ return lenght;
+}
diff --git a/io/wrap/feof.c b/io/wrap/feof.c
new file mode 100644
index 0000000..6e4b42d
--- /dev/null
+++ b/io/wrap/feof.c
@@ -0,0 +1,11 @@
+#define NO_OPAQUE_TYPE
+#include "io.h"
+#include <stdio.h>
+#include <wchar.h>
+
+int const _eof_wrap = EOF;
+wint_t const _weof_wrap = WEOF;
+
+int _feof_wrap(FILE *stream){
+ return feof(stream);
+}
diff --git a/io/wrap/fgetc.c b/io/wrap/fgetc.c
new file mode 100644
index 0000000..5c4de47
--- /dev/null
+++ b/io/wrap/fgetc.c
@@ -0,0 +1,4 @@
+#define NO_OPAQUE_TYPE
+#include "io.h"
+
+int _fgetc_wrap(FILE *stream) { return getc(stream); }
diff --git a/io/wrap/fgetwc.c b/io/wrap/fgetwc.c
new file mode 100644
index 0000000..0b854e1
--- /dev/null
+++ b/io/wrap/fgetwc.c
@@ -0,0 +1,4 @@
+#define NEED_WINT
+#include "io.h"
+
+wint_t _fgetwc_wrap(FILE *stream) { return getc(stream); }
diff --git a/io/wrap/fputc.c b/io/wrap/fputc.c
new file mode 100644
index 0000000..5075f5b
--- /dev/null
+++ b/io/wrap/fputc.c
@@ -0,0 +1,7 @@
+#define NO_OPAQUE_TYPE
+#include "io.h"
+
+int _fputc_wrap(int character, FILE *stream)
+{
+ return fputc(character, stream);
+}
diff --git a/io/wrap/fputwc.c b/io/wrap/fputwc.c
new file mode 100644
index 0000000..5075f5b
--- /dev/null
+++ b/io/wrap/fputwc.c
@@ -0,0 +1,7 @@
+#define NO_OPAQUE_TYPE
+#include "io.h"
+
+int _fputc_wrap(int character, FILE *stream)
+{
+ return fputc(character, stream);
+}
diff --git a/io/wrap/io.h b/io/wrap/io.h
new file mode 100644
index 0000000..dc5a306
--- /dev/null
+++ b/io/wrap/io.h
@@ -0,0 +1,56 @@
+#if !defined(IO_WRAP_H)
+ #define IO_WRAP_H
+
+ #include <stdarg.h>
+ #include <stddef.h>
+
+ #if __STDC_HOSTED__ == 1
+
+ #if defined(NEED_WINT)
+ #include <wchar.h>
+ #define NO_OPAQUE_TYPE
+
+ #endif
+
+ #if defined(NO_OPAQUE_TYPE)
+ #include <stdio.h>
+ #else
+typedef struct {
+ char file;
+} FILE;
+ #endif
+
+#if defined(NEED_WINT)
+extern wint_t const weof;
+
+extern wint_t _fgetwc_wrap(FILE *);
+extern wint_t _fputwc_wrap(wint_t, FILE *);
+#endif
+
+extern int const _eof_wrap;
+
+extern int _feof_wrap(FILE *stream);
+
+extern int _setvbuf_wrap(FILE *restrict file, char *restrict buffer, int mode,
+ size_t size);
+
+extern int _fgetc_wrap(FILE *);
+extern int _fputc_wrap(int, FILE *);
+
+extern int _vfprintf_wrap(FILE *, char const *restrict, va_list);
+extern int _vsnprintf_wrap(char *, size_t, char const *restrict, va_list);
+extern int _vfwprintf_wrap(FILE *, wchar_t const *restrict, va_list);
+extern int _vswprintf_wrap(wchar_t *, size_t, wchar_t const *restrict, va_list);
+
+int _vfscanf_wrap(FILE *, char const *restrict, va_list);
+int _vsscanf_wrap(char const *restrict, char const *restrict, va_list);
+int _vfwscanf_wrap(FILE *, wchar_t const *restrict, va_list);
+int _vswscanf_wrap(wchar_t const *restrict, wchar_t const *restrict, va_list);
+
+enum stdstream_list { stream_input, stream_output, stream_error };
+
+FILE *_stdstream_wrap(enum stdstream_list);
+
+ #endif
+
+#endif
diff --git a/io/wrap/meson.build b/io/wrap/meson.build
new file mode 100644
index 0000000..10b47a2
--- /dev/null
+++ b/io/wrap/meson.build
@@ -0,0 +1,16 @@
+sources += files(
+'io.h',
+'fgetc.c',
+'fputc.c',
+'stdstream.c',
+'feof.c',
+'vsnprintf.c',
+'vfprintf.c',
+'setvbuf.c',
+'vfwprinf.c',
+'vswprintf.c',
+'vswscanf.c',
+'vsscanf.c',
+'vfwscanf.c',
+'vfscanf.c',
+)
diff --git a/io/wrap/setvbuf.c b/io/wrap/setvbuf.c
new file mode 100644
index 0000000..bd411d5
--- /dev/null
+++ b/io/wrap/setvbuf.c
@@ -0,0 +1,8 @@
+#define NO_OPAQUE_TYPE
+#include "io.h"
+
+int _setvbuf_wrap(FILE *restrict file, char *restrict buffer, int mode,
+ size_t size)
+{
+ return setvbuf(file, buffer, mode, size);
+}
diff --git a/io/wrap/stdstream.c b/io/wrap/stdstream.c
new file mode 100644
index 0000000..0cc86a1
--- /dev/null
+++ b/io/wrap/stdstream.c
@@ -0,0 +1,16 @@
+#define NO_OPAQUE_TYPE
+#include "io.h"
+#include <stdio.h>
+
+FILE *_stdstream_wrap(enum stdstream_list streams)
+{
+ switch (streams) {
+ case stream_input:
+ return stdin;
+ case stream_output:
+ return stdout;
+ case stream_error:
+ return stderr;
+ }
+ return NULL;
+}
diff --git a/io/wrap/vfprintf.c b/io/wrap/vfprintf.c
new file mode 100644
index 0000000..ae49dc3
--- /dev/null
+++ b/io/wrap/vfprintf.c
@@ -0,0 +1,7 @@
+#define NO_OPAQUE_TYPE
+#include "io.h"
+
+int _vfprintf_wrap(FILE *stream, char const *restrict format, va_list arg)
+{
+ return vfprintf(stream, format, arg);
+}
diff --git a/io/wrap/vfscanf.c b/io/wrap/vfscanf.c
new file mode 100644
index 0000000..21181e1
--- /dev/null
+++ b/io/wrap/vfscanf.c
@@ -0,0 +1,7 @@
+#define NO_OPAQUE_TYPE
+#include "io.h"
+
+int _vfscanf_wrap(FILE *stream, char const *restrict format, va_list arg)
+{
+ return vfscanf(stream, format, arg);
+}
diff --git a/io/wrap/vfwprinf.c b/io/wrap/vfwprinf.c
new file mode 100644
index 0000000..02e6e03
--- /dev/null
+++ b/io/wrap/vfwprinf.c
@@ -0,0 +1,8 @@
+#define NO_OPAQUE_TYPE
+#include "io.h"
+#include <wchar.h>
+
+int _vfwprintf_wrap(FILE *stream, wchar_t const *restrict format, va_list arg)
+{
+ return vfwprintf(stream, format, arg);
+}
diff --git a/io/wrap/vfwscanf.c b/io/wrap/vfwscanf.c
new file mode 100644
index 0000000..86b884c
--- /dev/null
+++ b/io/wrap/vfwscanf.c
@@ -0,0 +1,8 @@
+#define NO_OPAQUE_TYPE
+#include "io.h"
+#include <wchar.h>
+
+int _vfwscanf_wrap(FILE *stream, wchar_t const *restrict format, va_list arg)
+{
+ return vfwscanf(stream, format, arg);
+}
diff --git a/io/wrap/vsnprintf.c b/io/wrap/vsnprintf.c
new file mode 100644
index 0000000..efe2f85
--- /dev/null
+++ b/io/wrap/vsnprintf.c
@@ -0,0 +1,9 @@
+#define NO_OPAQUE_TYPE
+#include "io.h"
+#include <wchar.h>
+
+int _vsnprintf_wrap(char *string, size_t max_size, char const *restrict format,
+ va_list arg)
+{
+ return vsnprintf(string, max_size, format, arg);
+}
diff --git a/io/wrap/vsscanf.c b/io/wrap/vsscanf.c
new file mode 100644
index 0000000..dd2bdb8
--- /dev/null
+++ b/io/wrap/vsscanf.c
@@ -0,0 +1,8 @@
+#define NO_OPAQUE_TYPE
+#include "io.h"
+
+int _vsscanf_wrap(char const *restrict string, char const *restrict format,
+ va_list arg)
+{
+ return vsscanf(string, format, arg);
+}
diff --git a/io/wrap/vswprintf.c b/io/wrap/vswprintf.c
new file mode 100644
index 0000000..8046634
--- /dev/null
+++ b/io/wrap/vswprintf.c
@@ -0,0 +1,9 @@
+#define NO_OPAQUE_TYPE
+#include "io.h"
+#include <wchar.h>
+
+int _vswprintf_wrap(wchar_t *string, size_t max_size,
+ wchar_t const *restrict format, va_list arg)
+{
+ return vswprintf(string, max_size, format, arg);
+}
diff --git a/io/wrap/vswscanf.c b/io/wrap/vswscanf.c
new file mode 100644
index 0000000..675596a
--- /dev/null
+++ b/io/wrap/vswscanf.c
@@ -0,0 +1,9 @@
+#define NO_OPAQUE_TYPE
+#include "io.h"
+#include <wchar.h>
+
+int _vswscanf_wrap(wchar_t const *restrict string,
+ wchar_t const *restrict format, va_list arg)
+{
+ return vswscanf(string, format, arg);
+}
diff --git a/io/wscanf.c b/io/wscanf.c
new file mode 100644
index 0000000..beb021a
--- /dev/null
+++ b/io/wscanf.c
@@ -0,0 +1,10 @@
+#include "io.h"
+
+int wscanf(wchar_t const *restrict format, ...)
+{
+ va_list arg;
+ va_start(arg, format);
+ int lenght = vwscanf(format, arg);
+ va_end(arg);
+ return lenght;
+}
diff --git a/license b/license
new file mode 100644
index 0000000..e38056d
--- /dev/null
+++ b/license
@@ -0,0 +1,22 @@
+MIT License
+
+Copyright (c) 2022 Marc Pervaz Boocha
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/math.h b/math.h
new file mode 100644
index 0000000..4299b3e
--- /dev/null
+++ b/math.h
@@ -0,0 +1 @@
+#include "maths/maths.h"
diff --git a/math/abs.c b/math/abs.c
new file mode 100644
index 0000000..1bb7355
--- /dev/null
+++ b/math/abs.c
@@ -0,0 +1,3 @@
+#include "maths.h"
+
+extern int abs(int n) { return n < 0 ? -n : n; }
diff --git a/math/div.c b/math/div.c
new file mode 100644
index 0000000..a97a19d
--- /dev/null
+++ b/math/div.c
@@ -0,0 +1,7 @@
+#include "maths.h"
+
+div_t div(int numerator, int denominator)
+{
+ return (div_t){.quot = numerator / denominator,
+ .rem = numerator % denominator};
+}
diff --git a/math/fabs.c b/math/fabs.c
new file mode 100644
index 0000000..8a4adf3
--- /dev/null
+++ b/math/fabs.c
@@ -0,0 +1,3 @@
+#include "maths.h"
+
+double fabs(double n) { return n < 0 ? -n : n; }
diff --git a/math/fabsf.c b/math/fabsf.c
new file mode 100644
index 0000000..c783069
--- /dev/null
+++ b/math/fabsf.c
@@ -0,0 +1,3 @@
+#include "maths.h"
+
+float fabsf(float n) { return n < 0 ? -n : n; }
diff --git a/math/fabsl.c b/math/fabsl.c
new file mode 100644
index 0000000..5390e69
--- /dev/null
+++ b/math/fabsl.c
@@ -0,0 +1,3 @@
+#include "maths.h"
+
+long double fabsl(long double n) { return n < 0 ? -n : n; }
diff --git a/math/imaxabs.c b/math/imaxabs.c
new file mode 100644
index 0000000..3f6c630
--- /dev/null
+++ b/math/imaxabs.c
@@ -0,0 +1,3 @@
+#include "maths.h"
+
+extern intmax_t imaxabs(intmax_t n) { return n < 0 ? -n : n; }
diff --git a/math/imaxdiv.c b/math/imaxdiv.c
new file mode 100644
index 0000000..52b5d39
--- /dev/null
+++ b/math/imaxdiv.c
@@ -0,0 +1,7 @@
+#include "maths.h"
+
+imaxdiv_t imaxdiv(intmax_t numerator, intmax_t denominator)
+{
+ return (imaxdiv_t){.quot = numerator / denominator,
+ .rem = numerator % denominator};
+}
diff --git a/math/labs.c b/math/labs.c
new file mode 100644
index 0000000..cf2cae8
--- /dev/null
+++ b/math/labs.c
@@ -0,0 +1,3 @@
+#include "maths.h"
+
+extern long labs(long n) { return n < 0 ? -n : n; }
diff --git a/math/ldiv.c b/math/ldiv.c
new file mode 100644
index 0000000..c45a6e6
--- /dev/null
+++ b/math/ldiv.c
@@ -0,0 +1,7 @@
+#include "maths.h"
+
+ldiv_t ldiv(long numerator, long denominator)
+{
+ return (ldiv_t){.quot = numerator / denominator,
+ .rem = numerator % denominator};
+}
diff --git a/math/llabs.c b/math/llabs.c
new file mode 100644
index 0000000..0a8bd2f
--- /dev/null
+++ b/math/llabs.c
@@ -0,0 +1,3 @@
+#include "maths.h"
+
+extern long long llabs(long long n) { return n < 0 ? -n : n; }
diff --git a/math/lldiv.c b/math/lldiv.c
new file mode 100644
index 0000000..3a9008c
--- /dev/null
+++ b/math/lldiv.c
@@ -0,0 +1,7 @@
+#include "maths.h"
+
+lldiv_t lldiv(long long numerator, long long denominator)
+{
+ return (lldiv_t){.quot = numerator / denominator,
+ .rem = numerator % denominator};
+}
diff --git a/math/maths.h b/math/maths.h
new file mode 100644
index 0000000..c330d0c
--- /dev/null
+++ b/math/maths.h
@@ -0,0 +1,41 @@
+#if !defined(MATH_H)
+ #define MATH_H
+
+ #include <stdint.h>
+
+extern int abs(int n);
+extern long labs(long n);
+extern long long llabs(long long n);
+extern intmax_t imaxabs(intmax_t n);
+extern float fabsf(float n);
+extern double fabs(double n);
+extern long double fabsl(long double n);
+
+ #if __STDC_HOSTED__ == 1
+ #include <inttypes.h>
+ #include <stdlib.h>
+ #else
+
+typedef struct {
+ int quot, rem;
+} div_t;
+
+typedef struct {
+ long quot, rem;
+} ldiv_t;
+
+typedef struct {
+ long long quot, rem;
+} lldiv_t;
+
+typedef struct {
+ intmax_t quot, rem;
+} imaxdiv_t;
+ #endif
+
+extern div_t div(int numerator, int denominator);
+extern ldiv_t ldiv(long numerator, long denominator);
+extern lldiv_t lldiv(long long numerator, long long denominator);
+extern imaxdiv_t imaxdiv(intmax_t numerator, intmax_t denominator);
+
+#endif
diff --git a/math/meson.build b/math/meson.build
new file mode 100644
index 0000000..a1f9227
--- /dev/null
+++ b/math/meson.build
@@ -0,0 +1,13 @@
+sources += files(
+'abs.c',
+'div.c',
+'fabs.c',
+'fabsf.c',
+'fabsl.c',
+'imaxabs.c',
+'labs.c',
+'ldiv.c',
+'imaxdiv.c',
+'llabs.c',
+'lldiv.c'
+)
diff --git a/math/wrap/meson.build b/math/wrap/meson.build
new file mode 100644
index 0000000..fcf4a29
--- /dev/null
+++ b/math/wrap/meson.build
@@ -0,0 +1,2 @@
+sources += files(
+)
diff --git a/memory.h b/memory.h
new file mode 100644
index 0000000..88a8d35
--- /dev/null
+++ b/memory.h
@@ -0,0 +1 @@
+#include "memory/memory.h"
diff --git a/memory/atof.c b/memory/atof.c
new file mode 100644
index 0000000..c7cdc7e
--- /dev/null
+++ b/memory/atof.c
@@ -0,0 +1,3 @@
+#include "memory.h"
+
+double atof(char const *string) { return _strtod_wrap(string, NULL); }
diff --git a/memory/atoi.c b/memory/atoi.c
new file mode 100644
index 0000000..7dedafb
--- /dev/null
+++ b/memory/atoi.c
@@ -0,0 +1,3 @@
+#include "memory.h"
+
+int atoi(char const *string) { return (int)_strtol_wrap(string, NULL, 10); }
diff --git a/memory/atol.c b/memory/atol.c
new file mode 100644
index 0000000..27f644e
--- /dev/null
+++ b/memory/atol.c
@@ -0,0 +1,3 @@
+#include "memory.h"
+
+long atol(char const *string) { return _strtol_wrap(string, NULL, 10); }
diff --git a/memory/atoll.c b/memory/atoll.c
new file mode 100644
index 0000000..85b190f
--- /dev/null
+++ b/memory/atoll.c
@@ -0,0 +1,3 @@
+#include "memory.h"
+
+long long atoll(char const *string) { return _strtoll_wrap(string, NULL, 10); }
diff --git a/memory/calloc.c b/memory/calloc.c
new file mode 100644
index 0000000..c14b150
--- /dev/null
+++ b/memory/calloc.c
@@ -0,0 +1,9 @@
+#include "memory.h"
+
+void *calloc(size_t count, size_t size)
+{
+ void *ptr = reallocarray(NULL, count, size);
+ if (ptr != NULL)
+ memset(ptr, 0, count * size);
+ return ptr;
+}
diff --git a/memory/memccmp.c b/memory/memccmp.c
new file mode 100644
index 0000000..dadb406
--- /dev/null
+++ b/memory/memccmp.c
@@ -0,0 +1,14 @@
+#include "memory.h"
+
+int memccmp(void const *buffer1, void const *buffer2, int value, size_t size)
+{
+ unsigned char const *buffer[] = {buffer1, buffer2};
+ for (size_t i = 0; i < size; i++) {
+ if (buffer[0][i] != buffer[1][i])
+ return buffer[0][i] - buffer[1][i];
+ if (buffer[0][i] == (unsigned char)value ||
+ buffer[1][i] == (unsigned char)value)
+ break;
+ }
+ return 0;
+}
diff --git a/memory/memccpy.c b/memory/memccpy.c
new file mode 100644
index 0000000..b960b34
--- /dev/null
+++ b/memory/memccpy.c
@@ -0,0 +1,14 @@
+#include "memory.h"
+
+void *memccpy(void *restrict dest, void const *restrict src, int value,
+ size_t count)
+{
+ unsigned char *restrict destination = dest;
+ unsigned char const *restrict source = src;
+ for (size_t i = 0; i < count; i++) {
+ destination[i] = source[i];
+ if (destination[i] == (unsigned char)value)
+ return &destination[i + 1];
+ }
+ return NULL;
+}
diff --git a/memory/memchr.c b/memory/memchr.c
new file mode 100644
index 0000000..61c10e3
--- /dev/null
+++ b/memory/memchr.c
@@ -0,0 +1,10 @@
+#include "memory.h"
+
+void *memchr(void const *buf, int value, size_t size)
+{
+ unsigned char const *buffer = buf;
+ for (size_t i = 0; i < size; i++)
+ if (buffer[i] == (unsigned char)value)
+ return (void *)&buffer[i];
+ return NULL;
+}
diff --git a/memory/memcmp.c b/memory/memcmp.c
new file mode 100644
index 0000000..621ec24
--- /dev/null
+++ b/memory/memcmp.c
@@ -0,0 +1,10 @@
+#include "memory.h"
+
+int memcmp(void const *buffer1, void const *buffer2, size_t size)
+{
+ unsigned char const *buffer[] = {buffer1, buffer2};
+ for (size_t i = 0; i < size; i++)
+ if (buffer[0][i] != buffer[1][i])
+ return (int)buffer[0][i] - (int)buffer[1][i];
+ return 0;
+}
diff --git a/memory/memcpy.c b/memory/memcpy.c
new file mode 100644
index 0000000..374484e
--- /dev/null
+++ b/memory/memcpy.c
@@ -0,0 +1,8 @@
+#include "memory.h"
+
+void *memcpy(void *restrict destination, void const *restrict source,
+ size_t count)
+{
+ mempcpy(destination, source, count);
+ return destination;
+}
diff --git a/memory/memlchr.c b/memory/memlchr.c
new file mode 100644
index 0000000..34aa7d0
--- /dev/null
+++ b/memory/memlchr.c
@@ -0,0 +1,10 @@
+#include "memory.h"
+
+size_t memlchr(void const *buf, int value, size_t size)
+{
+ unsigned char const *buffer = buf;
+ for (size_t i = 0; i < size; i++)
+ if (buffer[i] == (unsigned char)value)
+ return i;
+ return size;
+}
diff --git a/memory/memmove.c b/memory/memmove.c
new file mode 100644
index 0000000..b3a2f08
--- /dev/null
+++ b/memory/memmove.c
@@ -0,0 +1,13 @@
+#include "memory.h"
+
+void *memmove(void *restrict dest, void const *restrict src, size_t count)
+{
+ unsigned char *restrict destination = dest;
+ unsigned char const *restrict source = src;
+ if (destination < source)
+ memcpy(destination, source, count);
+ else
+ for (size_t i = count; i-- > 0;)
+ destination[i] = source[i];
+ return destination;
+}
diff --git a/memory/memory.h b/memory/memory.h
new file mode 100644
index 0000000..cf08b18
--- /dev/null
+++ b/memory/memory.h
@@ -0,0 +1,100 @@
+#if !defined(MEMORY_H)
+ #define MEMORY_H
+
+ #include <stddef.h>
+
+extern void *memset(void *, int, size_t);
+extern wchar_t *wmemset(wchar_t *, wchar_t, size_t);
+
+extern void *memchr(void const *, int, size_t);
+extern void *memrchr(void const *, int, size_t);
+extern size_t memlchr(void const *, int, size_t);
+extern void *rawmemchr(void const *, int);
+extern size_t rawmemlchr(void const *, int);
+extern wchar_t *wmemchr(wchar_t const *, wchar_t, size_t);
+extern wchar_t *wmemrchr(wchar_t const *, wchar_t, size_t);
+extern size_t wmemlchr(wchar_t const *, wchar_t, size_t);
+extern wchar_t *wrawmemchr(wchar_t const *, wchar_t);
+extern size_t wrawmemlchr(wchar_t const *, wchar_t);
+extern char *strchr(char const *, int);
+extern char *strrchr(char const *, int);
+extern wchar_t *wcschr(wchar_t const *, wchar_t);
+extern wchar_t *wcsrchr(wchar_t const *, wchar_t);
+
+extern int memcmp(void const *, void const *, size_t);
+extern int memccmp(void const *, void const *, int, size_t);
+extern int rawmemccmp(void const *, void const *, unsigned char);
+extern int wmemcmp(wchar_t const *, wchar_t const *, size_t);
+extern int wmemccmp(wchar_t const *, wchar_t const *, wchar_t, size_t);
+extern int wrawmemccmp(wchar_t const *, wchar_t const *, wchar_t);
+extern int strncmp(char const *, char const *, size_t);
+extern int strcmp(char const *, char const *);
+extern int wcsncmp(wchar_t const *, wchar_t const *, size_t);
+extern int wcscmp(wchar_t const *, wchar_t const *);
+
+extern void *mempcpy(void *restrict, void const *restrict, size_t);
+extern void *memccpy(void *restrict, void const *restrict, int, size_t);
+extern void *rawmemccpy(void *restrict, void const *restrict, int);
+extern void *memcpy(void *restrict, void const *restrict, size_t);
+extern void *memmove(void *restrict, void const *restrict, size_t);
+extern wchar_t *wmempcpy(wchar_t *restrict, wchar_t const *restrict,
+ size_t);
+extern wchar_t *wmemccpy(wchar_t *restrict, wchar_t const *restrict,
+ wchar_t, size_t);
+extern wchar_t *wrawmemccpy(wchar_t *restrict, wchar_t const *restrict,
+ wchar_t);
+extern wchar_t *wmemcpy(wchar_t *restrict, wchar_t const *restrict, size_t);
+extern wchar_t *wmemmove(wchar_t *restrict, wchar_t const *restrict,
+ size_t);
+extern char *stpcpy(char *, char const *);
+extern char *stpncpy(char *, char const *, size_t);
+extern char *strncpy(char *, char const *, size_t);
+extern char *strcpy(char *, char const *);
+extern size_t strlcpy(char *, char const *, size_t);
+extern wchar_t *wcspcpy(wchar_t *, wchar_t const *);
+extern wchar_t *wcspncpy(wchar_t *, wchar_t const *, size_t);
+extern wchar_t *wcsncpy(wchar_t *, wchar_t const *, size_t);
+extern wchar_t *wcscpy(wchar_t *, wchar_t const *);
+extern size_t wcslcpy(wchar_t *, wchar_t const *, size_t);
+
+extern size_t strnlen(char const *, size_t);
+extern size_t strnlen_s(char const *, size_t);
+extern size_t strlen(char const *);
+extern size_t wcsnlen(wchar_t const *, size_t);
+extern size_t wcsnlen_s(wchar_t const *, size_t);
+extern size_t wcslen(wchar_t const *);
+
+extern char *strcat(char *restrict, char const *restrict);
+extern char *strncat(char *restrict, char const *restrict, size_t);
+extern wchar_t *wcscat(wchar_t *restrict, wchar_t const *restrict);
+extern wchar_t *wcsncat(wchar_t *restrict, wchar_t const *restrict, size_t);
+extern size_t strlcat(char *, char const *, size_t);
+extern size_t wcslcat(wchar_t *, wchar_t const *, size_t);
+
+ #if __STDC_HOSTED__ == 1
+
+ #include "wrap/memory.h"
+
+extern double atof(char const *);
+extern long atol(char const *);
+extern long long atoll(char const *);
+extern int atoi(char const *);
+extern double wtof(wchar_t const *);
+extern long wtol(wchar_t const *);
+extern long long wtoll(wchar_t const *);
+extern int wtoi(wchar_t const *);
+
+extern void *calloc(size_t, size_t);
+extern void *reallocarray(void *buffer, size_t count, size_t size);
+
+extern char *strdup(char const *);
+extern char *strndup(char const *, size_t);
+extern wchar_t *wcsdup(wchar_t const *);
+extern wchar_t *wcsndup(wchar_t const *, size_t);
+
+extern int strcoll(char const *, char const *);
+extern int wcscoll(wchar_t const *, wchar_t const *);
+
+ #endif
+
+#endif
diff --git a/memory/mempcpy.c b/memory/mempcpy.c
new file mode 100644
index 0000000..0243885
--- /dev/null
+++ b/memory/mempcpy.c
@@ -0,0 +1,11 @@
+#include "memory.h"
+
+void *mempcpy(void *restrict dest, void const *restrict src, size_t count)
+{
+ unsigned char *restrict destination = dest;
+ unsigned char const *restrict source = src;
+ size_t i = 0;
+ for (i = 0; i < count; i++)
+ destination[i] = source[i];
+ return &destination[i];
+}
diff --git a/memory/memrchr.c b/memory/memrchr.c
new file mode 100644
index 0000000..6413808
--- /dev/null
+++ b/memory/memrchr.c
@@ -0,0 +1,10 @@
+#include "memory.h"
+
+void *memrchr(void const *buf, int value, size_t size)
+{
+ unsigned char const *buffer = buf;
+ for (size_t i = size; i-- > 0;)
+ if (buffer[i] == (unsigned char)value)
+ return (void *)&buffer[i];
+ return NULL;
+}
diff --git a/memory/memset.c b/memory/memset.c
new file mode 100644
index 0000000..f452276
--- /dev/null
+++ b/memory/memset.c
@@ -0,0 +1,10 @@
+#include "memory.h"
+
+void *memset(void *buf, int value, size_t size)
+{
+ unsigned char *buffer = buf;
+ for (size_t i = 0; i < size; i++) {
+ buffer[i] = (unsigned char)value;
+ }
+ return buffer;
+}
diff --git a/memory/meson.build b/memory/meson.build
new file mode 100644
index 0000000..281dbde
--- /dev/null
+++ b/memory/meson.build
@@ -0,0 +1,84 @@
+sources += files(
+'memory.h',
+'memccmp.c',
+'memccpy.c',
+'memchr.c',
+'memcmp.c',
+'memcpy.c',
+'memlchr.c',
+'memmove.c',
+'mempcpy.c',
+'memrchr.c',
+'memset.c',
+'rawmemccmp.c',
+'rawmemccpy.c',
+'rawmemchr.c',
+'rawmemlchr.c',
+'stpcpy.c',
+'stpncpy.c',
+'strcat.c',
+'strchr.c',
+'strcmp.c',
+'strcpy.c',
+'strlcat.c',
+'strlcpy.c',
+'strlen.c',
+'strncat.c',
+'strncmp.c',
+'strncpy.c',
+'strnlen.c',
+'strnlen_s.c',
+'strrchr.c',
+'wcscat.c',
+'wcschr.c',
+'wcscmp.c',
+'wcscpy.c',
+'wcslcat.c',
+'wcslcpy.c',
+'wcslen.c',
+'wcsncat.c',
+'wcsncmp.c',
+'wcsncpy.c',
+'wcsnlen.c',
+'wcsnlen_s.c',
+'wcspcpy.c',
+'wcspncpy.c',
+'wcsrchr.c',
+'wmemccmp.c',
+'wmemccpy.c',
+'wmemchr.c',
+'wmemcmp.c',
+'wmemcpy.c',
+'wmemlchr.c',
+'wmemmove.c',
+'wmempcpy.c',
+'wmemrchr.c',
+'wmemset.c',
+'wrawmemccmp.c',
+'wrawmemccpy.c',
+'wrawmemchr.c',
+'wrawmemlchr.c',
+)
+
+if is_hosted == 1
+subdir('wrap')
+sources += files(
+'atof.c',
+'atoi.c',
+'atol.c',
+'atoll.c',
+'calloc.c',
+'reallocarray.c',
+'strcoll.c',
+'strdup.c',
+'strndup.c',
+'wcsdup.c',
+'wcscoll.c',
+'wcsndup.c',
+'wtof.c',
+'wtoi.c',
+'wtol.c',
+'wtoll.c',
+)
+endif
+
diff --git a/memory/rawmemccmp.c b/memory/rawmemccmp.c
new file mode 100644
index 0000000..a2fe423
--- /dev/null
+++ b/memory/rawmemccmp.c
@@ -0,0 +1,13 @@
+#include "memory.h"
+
+int rawmemccmp(void const *buffer1, void const *buffer2, unsigned char value)
+{
+ unsigned char const *buffer[] = {buffer1, buffer2};
+ for (size_t i = 0;; i++) {
+ if (buffer[0][i] != buffer[1][i])
+ return (int)buffer[0][i] - (int)buffer[1][i];
+ if (buffer[0][i] == (unsigned char)value ||
+ buffer[1][i] == (unsigned char)value)
+ return 0;
+ }
+}
diff --git a/memory/rawmemccpy.c b/memory/rawmemccpy.c
new file mode 100644
index 0000000..ed83ef1
--- /dev/null
+++ b/memory/rawmemccpy.c
@@ -0,0 +1,13 @@
+#include "memory.h"
+
+void *rawmemccpy(void *restrict dest, void const *restrict src, int value)
+{
+ unsigned char *restrict destination = dest;
+ unsigned char const *restrict source = src;
+ size_t i = 0;
+ for (i = 0;; i++) {
+ destination[i] = source[i];
+ if (destination[i] == (unsigned char)value)
+ return &destination[i + 1];
+ }
+}
diff --git a/memory/rawmemchr.c b/memory/rawmemchr.c
new file mode 100644
index 0000000..496fe8a
--- /dev/null
+++ b/memory/rawmemchr.c
@@ -0,0 +1,9 @@
+#include "memory.h"
+
+void *rawmemchr(void const *buf, int value)
+{
+ unsigned char const *buffer = buf;
+ for (size_t i = 0;; i++)
+ if (buffer[i] == (unsigned char)value)
+ return (void *)&buffer[i];
+}
diff --git a/memory/rawmemlchr.c b/memory/rawmemlchr.c
new file mode 100644
index 0000000..3759840
--- /dev/null
+++ b/memory/rawmemlchr.c
@@ -0,0 +1,9 @@
+#include "memory.h"
+
+size_t rawmemlchr(void const *buf, int value)
+{
+ unsigned char const *buffer = buf;
+ for (size_t i = 0;; i++)
+ if (buffer[i] == (unsigned char)value)
+ return i;
+}
diff --git a/memory/reallocarray.c b/memory/reallocarray.c
new file mode 100644
index 0000000..8148b20
--- /dev/null
+++ b/memory/reallocarray.c
@@ -0,0 +1,12 @@
+#include "memory.h"
+#include <errno.h>
+#include <stdint.h>
+
+void *reallocarray(void *buffer, size_t count, size_t size)
+{
+ if (count > 0 && SIZE_MAX / count < size) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ return _realloc_wrap(buffer, count * size);
+}
diff --git a/memory/stpcpy.c b/memory/stpcpy.c
new file mode 100644
index 0000000..86421d9
--- /dev/null
+++ b/memory/stpcpy.c
@@ -0,0 +1,6 @@
+#include "memory.h"
+
+char *stpcpy(char *destination, char const *source)
+{
+ return (char *)rawmemccpy(destination, source, '\0') - 1;
+}
diff --git a/memory/stpncpy.c b/memory/stpncpy.c
new file mode 100644
index 0000000..fa53db7
--- /dev/null
+++ b/memory/stpncpy.c
@@ -0,0 +1,9 @@
+#include "memory.h"
+
+char *stpncpy(char *destination, char const *source, size_t count)
+{
+ char *result = memccpy(destination, source, '\0', count);
+ result = (result == NULL) ? &destination[count] : (result - 1);
+ memset(result, 0, (size_t)(&destination[count] - result));
+ return result;
+}
diff --git a/memory/strcat.c b/memory/strcat.c
new file mode 100644
index 0000000..118e152
--- /dev/null
+++ b/memory/strcat.c
@@ -0,0 +1,7 @@
+#include "memory.h"
+
+char *strcat(char *restrict destination, char const *restrict source)
+{
+ strcpy(destination + strlen(destination), source);
+ return destination;
+}
diff --git a/memory/strchr.c b/memory/strchr.c
new file mode 100644
index 0000000..4638c88
--- /dev/null
+++ b/memory/strchr.c
@@ -0,0 +1,6 @@
+#include "memory.h"
+
+char *strchr(char const *buffer, int value)
+{
+ return memchr(buffer, value, strlen(buffer) + 1);
+}
diff --git a/memory/strcmp.c b/memory/strcmp.c
new file mode 100644
index 0000000..604c4fc
--- /dev/null
+++ b/memory/strcmp.c
@@ -0,0 +1,6 @@
+#include "memory.h"
+
+int strcmp(char const *string1, char const *string2)
+{
+ return rawmemccmp(string1, string2, '\0');
+}
diff --git a/memory/strcoll.c b/memory/strcoll.c
new file mode 100644
index 0000000..2b7bde7
--- /dev/null
+++ b/memory/strcoll.c
@@ -0,0 +1,28 @@
+#include "memory.h"
+
+struct array_container {
+ char *string;
+ size_t lenght;
+};
+
+int strcoll(char const *string1, char const *string2)
+{
+ char const *string[2] = {string1, string2};
+ struct array_container normalized[2];
+
+ for (size_t i = 0; i < ((sizeof normalized) / (sizeof normalized[0]));
+ i++) {
+ normalized[i].lenght = 1 + _strxfrm_wrap(NULL, string[i], 0);
+ normalized[i].string = reallocarray(
+ NULL, normalized[i].lenght, sizeof *(normalized[i].string));
+ _strxfrm_wrap(normalized[i].string, string[i],
+ normalized[i].lenght);
+ }
+
+ int res = strcmp(normalized[0].string, normalized[1].string);
+
+ for (size_t i = 0; i < ((sizeof normalized) / (sizeof normalized[0]));
+ i++)
+ _free_wrap(normalized[i].string);
+ return res;
+}
diff --git a/memory/strcpy.c b/memory/strcpy.c
new file mode 100644
index 0000000..106b1a3
--- /dev/null
+++ b/memory/strcpy.c
@@ -0,0 +1,7 @@
+#include "memory.h"
+
+char *strcpy(char *destination, char const *source)
+{
+ stpcpy(destination, source);
+ return destination;
+}
diff --git a/memory/strdup.c b/memory/strdup.c
new file mode 100644
index 0000000..a69143d
--- /dev/null
+++ b/memory/strdup.c
@@ -0,0 +1,10 @@
+#include "memory.h"
+
+char *strdup(char const *restrict string)
+{
+ size_t lenght = strlen(string) + 1;
+ char *duplicate = reallocarray(NULL, lenght, sizeof *duplicate);
+ if (duplicate != NULL)
+ memcpy(duplicate, string, lenght);
+ return duplicate;
+}
diff --git a/memory/strlcat.c b/memory/strlcat.c
new file mode 100644
index 0000000..3061500
--- /dev/null
+++ b/memory/strlcat.c
@@ -0,0 +1,11 @@
+#include "memory.h"
+
+size_t strlcat(char *destination, char const *source, size_t max_lenght)
+{
+ size_t destination_lenght = strnlen(destination, max_lenght);
+ if (destination_lenght == max_lenght)
+ return destination_lenght + strlen(source);
+ return destination_lenght + strlcpy(destination + destination_lenght,
+ source,
+ max_lenght - destination_lenght);
+}
diff --git a/memory/strlcpy.c b/memory/strlcpy.c
new file mode 100644
index 0000000..a8bc45b
--- /dev/null
+++ b/memory/strlcpy.c
@@ -0,0 +1,9 @@
+#include "memory.h"
+
+size_t strlcpy(char *destination, char const *source, size_t count)
+{
+ char *result = memccpy(destination, source, '\0', count);
+ result = (result == NULL) ? &destination[count] : (result - 1);
+ *result = '\0';
+ return strlen(source);
+}
diff --git a/memory/strlen.c b/memory/strlen.c
new file mode 100644
index 0000000..c440bae
--- /dev/null
+++ b/memory/strlen.c
@@ -0,0 +1,3 @@
+#include "memory.h"
+
+size_t strlen(char const *string) { return rawmemlchr(string, '\0'); }
diff --git a/memory/strncat.c b/memory/strncat.c
new file mode 100644
index 0000000..fb70ab8
--- /dev/null
+++ b/memory/strncat.c
@@ -0,0 +1,9 @@
+#include "memory.h"
+
+char *strncat(char *restrict destination, char const *restrict source,
+ size_t max_len)
+{
+ memcpy(destination + strlen(destination), source,
+ strnlen(source, max_len));
+ return destination;
+}
diff --git a/memory/strncmp.c b/memory/strncmp.c
new file mode 100644
index 0000000..a41afd6
--- /dev/null
+++ b/memory/strncmp.c
@@ -0,0 +1,6 @@
+#include "memory.h"
+
+int strncmp(char const *string1, char const *string2, size_t size)
+{
+ return memccmp(string1, string2, '\0', size);
+}
diff --git a/memory/strncpy.c b/memory/strncpy.c
new file mode 100644
index 0000000..75e49e5
--- /dev/null
+++ b/memory/strncpy.c
@@ -0,0 +1,7 @@
+#include "memory.h"
+
+char *strncpy(char *destination, char const *source, size_t count)
+{
+ stpncpy(destination, source, count);
+ return destination;
+}
diff --git a/memory/strndup.c b/memory/strndup.c
new file mode 100644
index 0000000..8b369ed
--- /dev/null
+++ b/memory/strndup.c
@@ -0,0 +1,10 @@
+#include "memory.h"
+
+char *strndup(char const *restrict string, size_t max_lenght)
+{
+ size_t lenght = strnlen(string, max_lenght) + 1;
+ char *duplicate = reallocarray(NULL, lenght, sizeof *duplicate);
+ if (duplicate != NULL)
+ memcpy(duplicate, string, lenght);
+ return duplicate;
+}
diff --git a/memory/strnlen.c b/memory/strnlen.c
new file mode 100644
index 0000000..29c6156
--- /dev/null
+++ b/memory/strnlen.c
@@ -0,0 +1,6 @@
+#include "memory.h"
+
+size_t strnlen(char const *string, size_t max_len)
+{
+ return memlchr(string, '\0', max_len);
+}
diff --git a/memory/strnlen_s.c b/memory/strnlen_s.c
new file mode 100644
index 0000000..4f37aed
--- /dev/null
+++ b/memory/strnlen_s.c
@@ -0,0 +1,6 @@
+#include "memory.h"
+
+size_t strnlen_s(char const *string, size_t max_len)
+{
+ return (string == NULL) ? 0 : strnlen(string, max_len);
+}
diff --git a/memory/strrchr.c b/memory/strrchr.c
new file mode 100644
index 0000000..96a04eb
--- /dev/null
+++ b/memory/strrchr.c
@@ -0,0 +1,6 @@
+#include "memory.h"
+
+char *strrchr(char const *buffer, int value)
+{
+ return memrchr(buffer, value, strlen(buffer) + 1);
+}
diff --git a/memory/wcscat.c b/memory/wcscat.c
new file mode 100644
index 0000000..a8d59d1
--- /dev/null
+++ b/memory/wcscat.c
@@ -0,0 +1,7 @@
+#include "memory.h"
+
+wchar_t *wcscat(wchar_t *restrict destination, wchar_t const *restrict source)
+{
+ wcscpy(destination + wcslen(destination), source);
+ return destination;
+}
diff --git a/memory/wcschr.c b/memory/wcschr.c
new file mode 100644
index 0000000..91983b7
--- /dev/null
+++ b/memory/wcschr.c
@@ -0,0 +1,6 @@
+#include "memory.h"
+
+wchar_t *wcschr(wchar_t const *buffer, wchar_t value)
+{
+ return wmemchr(buffer, value, wcslen(buffer) + 1);
+}
diff --git a/memory/wcscmp.c b/memory/wcscmp.c
new file mode 100644
index 0000000..9a52e5b
--- /dev/null
+++ b/memory/wcscmp.c
@@ -0,0 +1,6 @@
+#include "memory.h"
+
+int wcscmp(wchar_t const *string1, wchar_t const *string2)
+{
+ return wrawmemccmp(string1, string2, L'\0');
+}
diff --git a/memory/wcscoll.c b/memory/wcscoll.c
new file mode 100644
index 0000000..f93bae7
--- /dev/null
+++ b/memory/wcscoll.c
@@ -0,0 +1,28 @@
+#include "memory.h"
+
+struct array_container {
+ wchar_t *string;
+ size_t lenght;
+};
+
+int wcscoll(wchar_t const *string1, wchar_t const *string2)
+{
+ wchar_t const *string[2] = {string1, string2};
+ struct array_container normalized[2];
+
+ for (size_t i = 0; i < ((sizeof normalized) / (sizeof normalized[0]));
+ i++) {
+ normalized[i].lenght = 1 + _wcsxfrm_wrap(NULL, string[i], 0);
+ normalized[i].string = reallocarray(
+ NULL, normalized[i].lenght, sizeof *(normalized[i].string));
+ _wcsxfrm_wrap(normalized[i].string, string[i],
+ normalized[i].lenght);
+ }
+
+ int res = wcscmp(normalized[0].string, normalized[1].string);
+
+ for (size_t i = 0; i < ((sizeof normalized) / (sizeof normalized[0]));
+ i++)
+ _free_wrap(normalized[i].string);
+ return res;
+}
diff --git a/memory/wcscpy.c b/memory/wcscpy.c
new file mode 100644
index 0000000..b583345
--- /dev/null
+++ b/memory/wcscpy.c
@@ -0,0 +1,7 @@
+#include "memory.h"
+
+wchar_t *wcscpy(wchar_t *destination, wchar_t const *source)
+{
+ wcspcpy(destination, source);
+ return destination;
+}
diff --git a/memory/wcsdup.c b/memory/wcsdup.c
new file mode 100644
index 0000000..ee11c46
--- /dev/null
+++ b/memory/wcsdup.c
@@ -0,0 +1,10 @@
+#include "memory.h"
+
+wchar_t *wcsdup(wchar_t const *restrict string)
+{
+ size_t lenght = wcslen(string) + 1;
+ wchar_t *duplicate = reallocarray(NULL, lenght, sizeof *duplicate);
+ if (duplicate != NULL)
+ wmemcpy(duplicate, string, lenght);
+ return duplicate;
+}
diff --git a/memory/wcslcat.c b/memory/wcslcat.c
new file mode 100644
index 0000000..c1a11dd
--- /dev/null
+++ b/memory/wcslcat.c
@@ -0,0 +1,11 @@
+#include "memory.h"
+
+size_t wcslcat(wchar_t *destination, wchar_t const *source, size_t max_lenght)
+{
+ size_t destination_lenght = wcsnlen(destination, max_lenght);
+ if (destination_lenght == max_lenght)
+ return destination_lenght + wcslen(source);
+ return destination_lenght + wcslcpy(destination + destination_lenght,
+ source,
+ max_lenght - destination_lenght);
+}
diff --git a/memory/wcslcpy.c b/memory/wcslcpy.c
new file mode 100644
index 0000000..236759e
--- /dev/null
+++ b/memory/wcslcpy.c
@@ -0,0 +1,9 @@
+#include "memory.h"
+
+size_t wcslcpy(wchar_t *destination, wchar_t const *source, size_t count)
+{
+ wchar_t *result = wmemccpy(destination, source, L'\0', count);
+ result = (result == NULL) ? &destination[count] : (result - 1);
+ *result = L'\0';
+ return wcslen(source);
+}
diff --git a/memory/wcslen.c b/memory/wcslen.c
new file mode 100644
index 0000000..5b1216b
--- /dev/null
+++ b/memory/wcslen.c
@@ -0,0 +1,3 @@
+#include "memory.h"
+
+size_t wcslen(wchar_t const *string) { return wrawmemlchr(string, L'\0'); }
diff --git a/memory/wcsncat.c b/memory/wcsncat.c
new file mode 100644
index 0000000..e979253
--- /dev/null
+++ b/memory/wcsncat.c
@@ -0,0 +1,9 @@
+#include "memory.h"
+
+wchar_t *wcsncat(wchar_t *restrict destination, wchar_t const *restrict source,
+ size_t max_len)
+{
+ wmemcpy(destination + wcslen(destination), source,
+ wcsnlen(destination, max_len));
+ return destination;
+}
diff --git a/memory/wcsncmp.c b/memory/wcsncmp.c
new file mode 100644
index 0000000..6ebd43c
--- /dev/null
+++ b/memory/wcsncmp.c
@@ -0,0 +1,6 @@
+#include "memory.h"
+
+int wcsncmp(wchar_t const *string1, wchar_t const *string2, size_t size)
+{
+ return wmemccmp(string1, string2, L'\0', size);
+}
diff --git a/memory/wcsncpy.c b/memory/wcsncpy.c
new file mode 100644
index 0000000..6fd47c3
--- /dev/null
+++ b/memory/wcsncpy.c
@@ -0,0 +1,7 @@
+#include "memory.h"
+
+wchar_t *wcsncpy(wchar_t *destination, wchar_t const *source, size_t count)
+{
+ wcspncpy(destination, source, count);
+ return destination;
+}
diff --git a/memory/wcsndup.c b/memory/wcsndup.c
new file mode 100644
index 0000000..0d65ce3
--- /dev/null
+++ b/memory/wcsndup.c
@@ -0,0 +1,10 @@
+#include "memory.h"
+
+wchar_t *wcsndup(wchar_t const *restrict string, size_t max_lenght)
+{
+ size_t lenght = wcsnlen(string, max_lenght) + 1;
+ wchar_t *duplicate = reallocarray(NULL, lenght, sizeof *duplicate);
+ if (duplicate != NULL)
+ wmemcpy(duplicate, string, lenght);
+ return duplicate;
+}
diff --git a/memory/wcsnlen.c b/memory/wcsnlen.c
new file mode 100644
index 0000000..0759419
--- /dev/null
+++ b/memory/wcsnlen.c
@@ -0,0 +1,6 @@
+#include "memory.h"
+
+size_t wcsnlen(wchar_t const *string, size_t max_len)
+{
+ return wmemlchr(string, L'\0', max_len);
+}
diff --git a/memory/wcsnlen_s.c b/memory/wcsnlen_s.c
new file mode 100644
index 0000000..1544c9b
--- /dev/null
+++ b/memory/wcsnlen_s.c
@@ -0,0 +1,6 @@
+#include "memory.h"
+
+size_t wcsnlen_s(wchar_t const *string, size_t max_len)
+{
+ return (string == NULL) ? 0 : wcsnlen(string, max_len);
+}
diff --git a/memory/wcspcpy.c b/memory/wcspcpy.c
new file mode 100644
index 0000000..652db3f
--- /dev/null
+++ b/memory/wcspcpy.c
@@ -0,0 +1,6 @@
+#include "memory.h"
+
+wchar_t *wcspcpy(wchar_t *destination, wchar_t const *source)
+{
+ return wrawmemccpy(destination, source, L'\0') - 1;
+}
diff --git a/memory/wcspncpy.c b/memory/wcspncpy.c
new file mode 100644
index 0000000..22cd44f
--- /dev/null
+++ b/memory/wcspncpy.c
@@ -0,0 +1,9 @@
+#include "memory.h"
+
+wchar_t *wcspncpy(wchar_t *destination, wchar_t const *source, size_t count)
+{
+ wchar_t *result = wmemccpy(destination, source, L'\0', count);
+ result = (result == NULL) ? &destination[count] : (result - 1);
+ wmemset(result, L'\0', (size_t)(&destination[count] - result));
+ return result;
+}
diff --git a/memory/wcsrchr.c b/memory/wcsrchr.c
new file mode 100644
index 0000000..63b2a6f
--- /dev/null
+++ b/memory/wcsrchr.c
@@ -0,0 +1,6 @@
+#include "memory.h"
+
+wchar_t *wcsrchr(wchar_t const *buffer, wchar_t value)
+{
+ return wmemrchr(buffer, value, wcslen(buffer) + 1);
+}
diff --git a/memory/wmemccmp.c b/memory/wmemccmp.c
new file mode 100644
index 0000000..a8f13b5
--- /dev/null
+++ b/memory/wmemccmp.c
@@ -0,0 +1,14 @@
+#include "memory.h"
+
+int wmemccmp(wchar_t const *buffer1, wchar_t const *buffer2, wchar_t value,
+ size_t size)
+{
+ wchar_t const *buffer[] = {buffer1, buffer2};
+ for (size_t i = 0; i < size; i++) {
+ if (buffer[0][i] != buffer[1][i])
+ return buffer[0][i] - buffer[1][i];
+ if (buffer[0][i] == value || buffer[1][i] == value)
+ break;
+ }
+ return 0;
+}
diff --git a/memory/wmemccpy.c b/memory/wmemccpy.c
new file mode 100644
index 0000000..05dbe07
--- /dev/null
+++ b/memory/wmemccpy.c
@@ -0,0 +1,13 @@
+#include "memory.h"
+
+wchar_t *wmemccpy(wchar_t *restrict destination, wchar_t const *restrict source,
+ wchar_t value, size_t count)
+{
+ size_t i = 0;
+ for (i = 0; i < count; i++) {
+ destination[i] = source[i];
+ if (destination[i] == value)
+ break;
+ }
+ return &destination[i + 1];
+}
diff --git a/memory/wmemchr.c b/memory/wmemchr.c
new file mode 100644
index 0000000..599b33e
--- /dev/null
+++ b/memory/wmemchr.c
@@ -0,0 +1,9 @@
+#include "memory.h"
+
+wchar_t *wmemchr(wchar_t const *buffer, wchar_t value, size_t size)
+{
+ for (size_t i = 0; i < size; i++)
+ if (buffer[i] == value)
+ return (wchar_t *)&buffer[i];
+ return NULL;
+}
diff --git a/memory/wmemcmp.c b/memory/wmemcmp.c
new file mode 100644
index 0000000..d0747c6
--- /dev/null
+++ b/memory/wmemcmp.c
@@ -0,0 +1,10 @@
+#include "memory.h"
+
+int wmemcmp(wchar_t const *buffer1, wchar_t const *buffer2, size_t size)
+{
+ wchar_t const *buffer[] = {buffer1, buffer2};
+ for (size_t i = 0; i < size; i++)
+ if (buffer[0][i] != buffer[1][i])
+ return (int)buffer[0][i] - (int)buffer[1][i];
+ return 0;
+}
diff --git a/memory/wmemcpy.c b/memory/wmemcpy.c
new file mode 100644
index 0000000..4c5d947
--- /dev/null
+++ b/memory/wmemcpy.c
@@ -0,0 +1,8 @@
+#include "memory.h"
+
+wchar_t *wmemcpy(wchar_t *restrict destination, wchar_t const *restrict source,
+ size_t count)
+{
+ mempcpy(destination, source, count);
+ return destination;
+}
diff --git a/memory/wmemlchr.c b/memory/wmemlchr.c
new file mode 100644
index 0000000..f776107
--- /dev/null
+++ b/memory/wmemlchr.c
@@ -0,0 +1,9 @@
+#include "memory.h"
+
+size_t wmemlchr(wchar_t const *buffer, wchar_t value, size_t size)
+{
+ for (size_t i = 0; i < size; i++)
+ if (buffer[i] == value)
+ return i;
+ return size;
+}
diff --git a/memory/wmemmove.c b/memory/wmemmove.c
new file mode 100644
index 0000000..1d30daf
--- /dev/null
+++ b/memory/wmemmove.c
@@ -0,0 +1,12 @@
+#include "memory.h"
+
+wchar_t *wmemmove(wchar_t *restrict destination, wchar_t const *restrict source,
+ size_t count)
+{
+ if (destination < source)
+ wmemcpy(destination, source, count);
+ else
+ for (size_t i = count; i-- > 0;)
+ destination[i] = source[i];
+ return destination;
+}
diff --git a/memory/wmempcpy.c b/memory/wmempcpy.c
new file mode 100644
index 0000000..67820f0
--- /dev/null
+++ b/memory/wmempcpy.c
@@ -0,0 +1,10 @@
+#include "memory.h"
+
+wchar_t *wmempcpy(wchar_t *restrict destination, wchar_t const *restrict source,
+ size_t count)
+{
+ size_t i = 0;
+ for (i = 0; i < count; i++)
+ destination[i] = source[i];
+ return &destination[i];
+}
diff --git a/memory/wmemrchr.c b/memory/wmemrchr.c
new file mode 100644
index 0000000..c7b1684
--- /dev/null
+++ b/memory/wmemrchr.c
@@ -0,0 +1,9 @@
+#include "memory.h"
+
+wchar_t *wmemrchr(wchar_t const *buffer, wchar_t value, size_t size)
+{
+ for (size_t i = size; i-- > 0;)
+ if (buffer[i] == value)
+ return (wchar_t *)&buffer[i];
+ return NULL;
+}
diff --git a/memory/wmemset.c b/memory/wmemset.c
new file mode 100644
index 0000000..7cb6ba1
--- /dev/null
+++ b/memory/wmemset.c
@@ -0,0 +1,8 @@
+#include "memory.h"
+
+wchar_t *wmemset(wchar_t *buffer, wchar_t value, size_t size)
+{
+ for (size_t i = 0; i < size; i++)
+ buffer[i] = value;
+ return buffer;
+}
diff --git a/memory/wrap/free.c b/memory/wrap/free.c
new file mode 100644
index 0000000..d65e3d8
--- /dev/null
+++ b/memory/wrap/free.c
@@ -0,0 +1,4 @@
+#include "memory.h"
+#include <stdlib.h>
+
+void _free_wrap(void *buffer) { free(buffer); }
diff --git a/memory/wrap/memory.h b/memory/wrap/memory.h
new file mode 100644
index 0000000..55af1c6
--- /dev/null
+++ b/memory/wrap/memory.h
@@ -0,0 +1,25 @@
+#ifndef MEMORY_WRAP_H
+#define MEMORY_WRAP_H
+
+#include <stddef.h>
+
+#if __STDC_HOSTED__ == 1
+extern void _free_wrap(void *ptr);
+extern void *_realloc_wrap(void *ptr, size_t size);
+
+extern long _strtol_wrap(char const *restrict, char **restrict, int);
+extern long long _strtoll_wrap(char const *restrict, char **restrict, int);
+extern double _strtod_wrap(char const *restrict, char **restrict);
+extern long _wcstol_wrap(wchar_t const *restrict, wchar_t **restrict, int);
+extern long long _wcstoll_wrap(wchar_t const *restrict, wchar_t **restrict,
+ int);
+extern double _wcstod_wrap(wchar_t const *restrict, wchar_t **restrict);
+
+extern size_t _strxfrm_wrap(char *restrict destination,
+ char const *restrict source, size_t count);
+extern size_t _wcsxfrm_wrap(wchar_t *restrict destination,
+ wchar_t const *restrict source, size_t count);
+
+#endif
+
+#endif
diff --git a/memory/wrap/meson.build b/memory/wrap/meson.build
new file mode 100644
index 0000000..fc8a57f
--- /dev/null
+++ b/memory/wrap/meson.build
@@ -0,0 +1,13 @@
+sources += files(
+'memory.h',
+'strtol.c',
+'strtoll.c',
+'strtod.c',
+'strxfrm.c',
+'wcsxfrm.c',
+'wcstol.c',
+'wcstoll.c',
+'wcstod.c',
+'free.c',
+'realloc.c'
+)
diff --git a/memory/wrap/realloc.c b/memory/wrap/realloc.c
new file mode 100644
index 0000000..5efb62e
--- /dev/null
+++ b/memory/wrap/realloc.c
@@ -0,0 +1,4 @@
+#include "memory.h"
+#include <stdlib.h>
+
+void *_realloc_wrap(void *buffer, size_t size) { return realloc(buffer, size); }
diff --git a/memory/wrap/strtod.c b/memory/wrap/strtod.c
new file mode 100644
index 0000000..19d4a0e
--- /dev/null
+++ b/memory/wrap/strtod.c
@@ -0,0 +1,7 @@
+#include "memory.h"
+#include <stdlib.h>
+
+double _strtod_wrap(char const *restrict string, char **restrict invalid)
+{
+ return strtod(string, invalid);
+}
diff --git a/memory/wrap/strtol.c b/memory/wrap/strtol.c
new file mode 100644
index 0000000..e364f40
--- /dev/null
+++ b/memory/wrap/strtol.c
@@ -0,0 +1,8 @@
+#include "memory.h"
+#include <stdlib.h>
+
+long _strtol_wrap(char const *restrict string, char **restrict invalid,
+ int base)
+{
+ return strtol(string, invalid, base);
+}
diff --git a/memory/wrap/strtoll.c b/memory/wrap/strtoll.c
new file mode 100644
index 0000000..27bda06
--- /dev/null
+++ b/memory/wrap/strtoll.c
@@ -0,0 +1,8 @@
+#include "memory.h"
+#include <stdlib.h>
+
+long long _strtoll_wrap(char const *restrict string, char **restrict invalid,
+ int base)
+{
+ return strtoll(string, invalid, base);
+}
diff --git a/memory/wrap/strxfrm.c b/memory/wrap/strxfrm.c
new file mode 100644
index 0000000..87e9420
--- /dev/null
+++ b/memory/wrap/strxfrm.c
@@ -0,0 +1,8 @@
+#include "memory.h"
+#include <string.h>
+
+size_t _strxfrm_wrap(char *restrict destination, char const *restrict source,
+ size_t count)
+{
+ return strxfrm(destination, source, count);
+}
diff --git a/memory/wrap/wcstod.c b/memory/wrap/wcstod.c
new file mode 100644
index 0000000..037e210
--- /dev/null
+++ b/memory/wrap/wcstod.c
@@ -0,0 +1,7 @@
+#include "memory.h"
+#include <wchar.h>
+
+double _wcstod_wrap(wchar_t const *restrict string, wchar_t **restrict invalid)
+{
+ return wcstod(string, invalid);
+}
diff --git a/memory/wrap/wcstol.c b/memory/wrap/wcstol.c
new file mode 100644
index 0000000..7f0a569
--- /dev/null
+++ b/memory/wrap/wcstol.c
@@ -0,0 +1,8 @@
+#include "memory.h"
+#include <wchar.h>
+
+long _wcstol_wrap(wchar_t const *restrict string, wchar_t **restrict invalid,
+ int base)
+{
+ return wcstol(string, invalid, base);
+}
diff --git a/memory/wrap/wcstoll.c b/memory/wrap/wcstoll.c
new file mode 100644
index 0000000..e54272c
--- /dev/null
+++ b/memory/wrap/wcstoll.c
@@ -0,0 +1,8 @@
+#include "memory.h"
+#include <wchar.h>
+
+long long _wcstoll_wrap(wchar_t const *restrict string,
+ wchar_t **restrict invalid, int base)
+{
+ return wcstoll(string, invalid, base);
+}
diff --git a/memory/wrap/wcsxfrm.c b/memory/wrap/wcsxfrm.c
new file mode 100644
index 0000000..4f39a31
--- /dev/null
+++ b/memory/wrap/wcsxfrm.c
@@ -0,0 +1,8 @@
+#include "memory.h"
+#include <wchar.h>
+
+size_t _wcsxfrm_wrap(wchar_t *restrict destination,
+ wchar_t const *restrict source, size_t count)
+{
+ return wcsxfrm(destination, source, count);
+}
diff --git a/memory/wrawmemccmp.c b/memory/wrawmemccmp.c
new file mode 100644
index 0000000..8b86278
--- /dev/null
+++ b/memory/wrawmemccmp.c
@@ -0,0 +1,12 @@
+#include "memory.h"
+
+int wrawmemccmp(wchar_t const *buffer1, wchar_t const *buffer2, wchar_t value)
+{
+ wchar_t const *buffer[] = {buffer1, buffer2};
+ for (size_t i = 0;; i++) {
+ if (buffer[0][i] != buffer[1][i])
+ return (int)buffer[0][i] - (int)buffer[1][i];
+ if (buffer[0][i] == value || buffer[1][i] == value)
+ return 0;
+ }
+}
diff --git a/memory/wrawmemccpy.c b/memory/wrawmemccpy.c
new file mode 100644
index 0000000..ce5b0be
--- /dev/null
+++ b/memory/wrawmemccpy.c
@@ -0,0 +1,11 @@
+#include "memory.h"
+
+wchar_t *wrawmemccpy(wchar_t *restrict destination,
+ wchar_t const *restrict source, wchar_t value)
+{
+ for (size_t i = 0;; i++) {
+ destination[i] = source[i];
+ if (destination[i] == value)
+ return &destination[i + 1];
+ }
+}
diff --git a/memory/wrawmemchr.c b/memory/wrawmemchr.c
new file mode 100644
index 0000000..23a432f
--- /dev/null
+++ b/memory/wrawmemchr.c
@@ -0,0 +1,8 @@
+#include "memory.h"
+
+wchar_t *wrawmemchr(wchar_t const *buffer, wchar_t value)
+{
+ for (size_t i = 0;; i++)
+ if (buffer[i] == value)
+ return (wchar_t *)&buffer[i];
+}
diff --git a/memory/wrawmemlchr.c b/memory/wrawmemlchr.c
new file mode 100644
index 0000000..a89334e
--- /dev/null
+++ b/memory/wrawmemlchr.c
@@ -0,0 +1,8 @@
+#include "memory.h"
+
+size_t wrawmemlchr(wchar_t const *buffer, wchar_t value)
+{
+ for (size_t i = 0;; i++)
+ if (buffer[i] == value)
+ return i;
+}
diff --git a/memory/wtof.c b/memory/wtof.c
new file mode 100644
index 0000000..99a5758
--- /dev/null
+++ b/memory/wtof.c
@@ -0,0 +1,3 @@
+#include "memory.h"
+
+double wtof(wchar_t const *string) { return _wcstod_wrap(string, NULL); }
diff --git a/memory/wtoi.c b/memory/wtoi.c
new file mode 100644
index 0000000..9510d3f
--- /dev/null
+++ b/memory/wtoi.c
@@ -0,0 +1,3 @@
+#include "memory.h"
+
+int wtoi(wchar_t const *string) { return (int)_wcstol_wrap(string, NULL, 10); }
diff --git a/memory/wtol.c b/memory/wtol.c
new file mode 100644
index 0000000..a2196b2
--- /dev/null
+++ b/memory/wtol.c
@@ -0,0 +1,3 @@
+#include "memory.h"
+
+long wtol(wchar_t const *string) { return _wcstol_wrap(string, NULL, 10); }
diff --git a/memory/wtoll.c b/memory/wtoll.c
new file mode 100644
index 0000000..af4be82
--- /dev/null
+++ b/memory/wtoll.c
@@ -0,0 +1,6 @@
+#include "memory.h"
+
+long long wtoll(wchar_t const *string)
+{
+ return _wcstoll_wrap(string, NULL, 10);
+}
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..f1d5973
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,37 @@
+project('ffc', 'c',
+ version : '0.1',
+ default_options : [
+ 'c_std=c11',
+ 'warning_level=3'
+ ]
+)
+
+cc = meson.get_compiler('c')
+if cc.has_argument('-fno-builtin')
+ add_project_arguments('-fno-builtin', language : 'c')
+endif
+
+is_hosted = cc.get_define('__STDC_HOSTED__').to_int()
+has_strings = cc.check_header('unistd.h')
+
+sources = []
+
+subdir('memory')
+subdir('math')
+subdir('io')
+
+lib = library('ffc', sources,
+ install : true,
+ gnu_symbol_visibility: 'hidden',
+)
+
+# Make this library usable as a Meson subproject.
+ffc_dep = declare_dependency(
+ link_with : lib
+)
+
+pkg_mod = import('pkgconfig')
+pkg_mod.generate(name: 'ffc',
+ description : 'A libc compat layer',
+ libraries: lib
+)
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..3bed775
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,11 @@
+# FFlibc
+This is an prototype of layering several function of the standard c library while maintaining ABI compatibility with the system's libc. It try to avoid using extension or any internal implementation details of the system libc.
+
+## Build
+It needs [meson](https://mesonbuild.com/) to build.
+
+```bash
+meson build
+ninja -C build
+ninja -C build install
+``` \ No newline at end of file
diff --git a/test.c b/test.c
new file mode 100644
index 0000000..9b84578
--- /dev/null
+++ b/test.c
@@ -0,0 +1,8 @@
+#include <string.h>
+#include <stdio.h>
+
+int main(int argc,char* argv[argc+1]){
+ puts(argv[1]);
+ printf("%d\n",strlen(argv[1]));
+ return 1;
+}