aboutsummaryrefslogtreecommitdiffstats
path: root/memory
diff options
context:
space:
mode:
Diffstat (limited to 'memory')
-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
88 files changed, 939 insertions, 0 deletions
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);
+}