aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/string/mem/memcasemem.c1
-rw-r--r--src/wchar/rawwcscasestr.c38
-rw-r--r--src/wchar/rawwcsstr.c38
-rw-r--r--src/wchar/rawwmemchr.c42
-rw-r--r--src/wchar/wcpcpy.c36
-rw-r--r--src/wchar/wcpmove.c36
-rw-r--r--src/wchar/wcpncpy.c46
-rw-r--r--src/wchar/wcpnmove.c47
-rw-r--r--src/wchar/wcscasecmp.c39
-rw-r--r--src/wchar/wcscaseends.c41
-rw-r--r--src/wchar/wcscasestarts.c41
-rw-r--r--src/wchar/wcscasestr.c37
-rw-r--r--src/wchar/wcscat.c23
-rw-r--r--src/wchar/wcsccpy.c46
-rw-r--r--src/wchar/wcschr.c113
-rw-r--r--src/wchar/wcschrnul.c48
-rw-r--r--src/wchar/wcscmove.c46
-rw-r--r--src/wchar/wcscmp.c115
-rw-r--r--src/wchar/wcscncpy.c55
-rw-r--r--src/wchar/wcscnmove.c55
-rw-r--r--src/wchar/wcscpy.c188
-rw-r--r--src/wchar/wcscspn.c48
-rw-r--r--src/wchar/wcsdup.c42
-rw-r--r--src/wchar/wcsends.c41
-rw-r--r--src/wchar/wcslen.c16
-rw-r--r--src/wchar/wcsmove.c188
-rw-r--r--src/wchar/wcsncasecmp.c52
-rw-r--r--src/wchar/wcsncasestr.c38
-rw-r--r--src/wchar/wcsncat.c43
-rw-r--r--src/wchar/wcsncmp.c40
-rw-r--r--src/wchar/wcsncpy.c43
-rw-r--r--src/wchar/wcsndup.c44
-rw-r--r--src/wchar/wcsnlen.c36
-rw-r--r--src/wchar/wcsnmove.c43
-rw-r--r--src/wchar/wcsnstr.c39
-rw-r--r--src/wchar/wcspbrk.c42
-rw-r--r--src/wchar/wcsrchr.c48
-rw-r--r--src/wchar/wcssep.c53
-rw-r--r--src/wchar/wcsspn.c44
-rw-r--r--src/wchar/wcsstarts.c41
-rw-r--r--src/wchar/wcsstr.c247
-rw-r--r--src/wchar/wcsstrcpy.c47
-rw-r--r--src/wchar/wcsstrmove.c47
-rw-r--r--src/wchar/wcsstrncpy.c55
-rw-r--r--src/wchar/wcsstrnmove.c54
-rw-r--r--src/wchar/wcstok.c33
-rw-r--r--src/wchar/wcswcs.c29
-rw-r--r--src/wchar/wmemcasecmp.c45
-rw-r--r--src/wchar/wmemcasemem.c54
-rw-r--r--src/wchar/wmemccpy.c27
-rw-r--r--src/wchar/wmemchr.c42
-rw-r--r--src/wchar/wmemcmove.c47
-rw-r--r--src/wchar/wmemcmp.c40
-rw-r--r--src/wchar/wmemcpy.c16
-rw-r--r--src/wchar/wmemdup.c40
-rw-r--r--src/wchar/wmemmem.c53
-rw-r--r--src/wchar/wmemmove.c17
-rw-r--r--src/wchar/wmempcpy.c36
-rw-r--r--src/wchar/wmempmove.c37
-rw-r--r--src/wchar/wmemrchr.c48
60 files changed, 2018 insertions, 1068 deletions
diff --git a/src/string/mem/memcasemem.c b/src/string/mem/memcasemem.c
index 3fb24dc..aad5d68 100644
--- a/src/string/mem/memcasemem.c
+++ b/src/string/mem/memcasemem.c
@@ -50,6 +50,5 @@ void* (memcasemem)(const void* __haystack, size_t haystack_length,
return !(memcasecmp)(haystack, needle, haystack_length) ? haystack : NULL;
#define CASE
#include "substring.h"
-#undef CASE
}
diff --git a/src/wchar/rawwcscasestr.c b/src/wchar/rawwcscasestr.c
new file mode 100644
index 0000000..51af4ce
--- /dev/null
+++ b/src/wchar/rawwcscasestr.c
@@ -0,0 +1,38 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+#include <stdint.h>
+
+
+
+/**
+ * Finds the first occurrence of a substring.
+ * This search is case insensitive.
+ * It must already be known that such a substring exists.
+ *
+ * This is a slibc extension.
+ *
+ * @param haystack The string to search.
+ * @param needle The sought after substring.
+ * @return Pointer to the first occurrence of the substring.
+ */
+wchar_t* (rawwcscasestr)(const wchar_t* haystack, const wchar_t* needle)
+{
+ return (wmemcasemem)(haystack, SIZE_MAX, needle, wcslen(needle));
+}
+
diff --git a/src/wchar/rawwcsstr.c b/src/wchar/rawwcsstr.c
new file mode 100644
index 0000000..42450ab
--- /dev/null
+++ b/src/wchar/rawwcsstr.c
@@ -0,0 +1,38 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+#include <stdint.h>
+
+
+
+/**
+ * Finds the first occurrence of a substring.
+ * This search is case sensitive.
+ * It must already be known that such a substring exists.
+ *
+ * This is a slibc extension.
+ *
+ * @param haystack The string to search.
+ * @param needle The sought after substring.
+ * @return Pointer to the first occurrence of the substring.
+ */
+wchar_t* (rawwcsstr)(const wchar_t* haystack, const wchar_t* needle)
+{
+ return (wmemmem)(haystack, SIZE_MAX, needle, wcslen(needle));
+}
+
diff --git a/src/wchar/rawwmemchr.c b/src/wchar/rawwmemchr.c
new file mode 100644
index 0000000..dafc58b
--- /dev/null
+++ b/src/wchar/rawwmemchr.c
@@ -0,0 +1,42 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
+
+
+
+/**
+ * Find the first occurrence of a wide character in a
+ * memory segment. The memory segment must be known to
+ * contain the sought after character.
+ *
+ * This is a slibc extension added for completeness.
+ *
+ * @param segment The memory segment to search.
+ * @param c The sought after character.
+ * @return Pointer to the first occurrence of `c`.
+ */
+wchar_t* (rawwmemchr)(const wchar_t* segment, wchar_t c)
+{
+ for (;;)
+ if (*segment++ == c)
+ return segment - 1;
+}
+
diff --git a/src/wchar/wcpcpy.c b/src/wchar/wcpcpy.c
new file mode 100644
index 0000000..7afbd26
--- /dev/null
+++ b/src/wchar/wcpcpy.c
@@ -0,0 +1,36 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Copy a memory segment to another, non-overlapping, segment,
+ * stop when a NUL wide character is encountered.
+ *
+ * This is a GNU-compliant slibc extension.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @return `whither + wcslen(whence)` is returned.
+ */
+wchar_t* wcpcpy(wchar_t* restrict whither, const wchar_t* restrict whence)
+{
+ return wmempcpy(whither, whence, wcslen(whence) + 1) - 1;
+}
+
diff --git a/src/wchar/wcpmove.c b/src/wchar/wcpmove.c
new file mode 100644
index 0000000..bc1e754
--- /dev/null
+++ b/src/wchar/wcpmove.c
@@ -0,0 +1,36 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Copy a memory segment to another, possibly overlapping, segment,
+ * stop when a NUL wide character is encountered.
+ *
+ * This is a slibc extension added for completeness.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @return `whither + wcslen(whence)` is returned.
+ */
+wchar_t* wcpmove(wchar_t* whither, const wchar_t* whence)
+{
+ return wmempmove(whither, whence, wcslen(whence) + 1) - 1;
+}
+
diff --git a/src/wchar/wcpncpy.c b/src/wchar/wcpncpy.c
new file mode 100644
index 0000000..fc5d68b
--- /dev/null
+++ b/src/wchar/wcpncpy.c
@@ -0,0 +1,46 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Copy a memory segment to another, non-overlapping, segment,
+ * stop when a NUL wide character is encountered.
+ *
+ * This is a GNU extension.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @param maxlen The maximum number of wide characters to copy.
+ * NOTE that if the resulting string at least this
+ * long, no NUL character will be written to `whither'.
+ * On the otherhand, if the resultnig string is
+ * shorter, `whither` will be filled with NUL characters
+ * until this amount of characters have been written.
+ * @return `whither` plus the number of written characters,
+ * excluding NUL characters, is returned.
+ */
+wchar_t* wcpncpy(wchar_t* restrict whither, const wchar_t* restrict whence, size_t maxlen)
+{
+ size_t n = wcsnlen(whence, maxlen);
+ wmemcpy(whither, whence, n);
+ wmemset(whither, 0, maxlen - n);
+ return whither + n;
+}
+
diff --git a/src/wchar/wcpnmove.c b/src/wchar/wcpnmove.c
new file mode 100644
index 0000000..f81caec
--- /dev/null
+++ b/src/wchar/wcpnmove.c
@@ -0,0 +1,47 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Copy a memory segment to another, possibly overlapping, segment,
+ * stop when a NUL wide character is encountered.
+ *
+ * This is a slibc extension added for completeness.
+ * It is only available if GNU extensions are available.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @param maxlen The maximum number of wide characters to copy.
+ * NOTE that if the resulting string at least this
+ * long, no NUL character will be written to `whither'.
+ * On the otherhand, if the resultnig string is
+ * shorter, `whither` will be filled with NUL characters
+ * until this amount of characters have been written.
+ * @return `whither` plus the number of written characters,
+ * excluding NUL characters, is returned.
+ */
+wchar_t* wcpnmove(wchar_t* whither, const wchar_t* whence, size_t maxlen)
+{
+ size_t n = wcsnlen(whence, maxlen);
+ wmemmove(whither, whence, n);
+ wmemset(whither, 0, maxlen - n);
+ return whither + n;
+}
+
diff --git a/src/wchar/wcscasecmp.c b/src/wchar/wcscasecmp.c
new file mode 100644
index 0000000..dea8f46
--- /dev/null
+++ b/src/wchar/wcscasecmp.c
@@ -0,0 +1,39 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+#include <stdint.h>
+
+
+
+/**
+ * Compare two strings alphabetically in a case insensitive manner.
+ * Be aware, only ASCII characters are case insensitive, non-ASCII
+ * characters are case sensitive.
+ *
+ * This is a GNU-compliant slibc extension.
+ *
+ * @param a A negative value is returned if this is the lesser.
+ * @param b A positive value is returned if this is the lesser.
+ * @return Zero is returned if `a` and `b` are equal, otherwise,
+ * see the specifications for `a` and `b`.
+ */
+int wcscasecmp(const wchar_t* a, const wchar_t* b)
+{
+ return wcsncasecmp(a, b, SIZE_MAX);
+}
+
diff --git a/src/wchar/wcscaseends.c b/src/wchar/wcscaseends.c
new file mode 100644
index 0000000..93d0cc6
--- /dev/null
+++ b/src/wchar/wcscaseends.c
@@ -0,0 +1,41 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Check whether a string ends with a specific string.
+ * This check is case insensitive.
+ *
+ * This is a slibc extension.
+ *
+ * @param string The string to inspect.
+ * @param desired The desired ending of the string.
+ * @return The `string`, where `desired` beings if
+ * `string` ends with `desired`, `NULL` otherwise.
+ */
+wchar_t* (wcscaseends)(const wchar_t* string, const wchar_t* desired)
+{
+ size_t n = wcslen(string);
+ size_t m = wcslen(desired);
+ if (n < m)
+ return NULL;
+ return wmemcasecmp(string + (n - m), desired, m) ? NULL : (string + n);
+}
+
diff --git a/src/wchar/wcscasestarts.c b/src/wchar/wcscasestarts.c
new file mode 100644
index 0000000..bba5881
--- /dev/null
+++ b/src/wchar/wcscasestarts.c
@@ -0,0 +1,41 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Check whether a string starts with a specific string.
+ * This check is case insensitive.
+ *
+ * This is a slibc extension.
+ *
+ * @param string The string to inspect.
+ * @param desired The desired beginning of the string.
+ * @return `string` if `string` begins with
+ * `desired`, `NULL` otherwise.
+ */
+wchar_t* (wcscasestarts)(const wchar_t* string, const wchar_t* desired)
+{
+ size_t n = wcslen(string);
+ size_t m = wcslen(desired);
+ if (n < m)
+ return NULL;
+ return wmemcasecmp(string, desired, m) ? NULL : string;
+}
+
diff --git a/src/wchar/wcscasestr.c b/src/wchar/wcscasestr.c
new file mode 100644
index 0000000..3e0e6d0
--- /dev/null
+++ b/src/wchar/wcscasestr.c
@@ -0,0 +1,37 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Finds the first occurrence of a substring.
+ * This search is case insensitive.
+ *
+ * This is a slibc extension.
+ *
+ * @param haystack The string to search.
+ * @param needle The sought after substring.
+ * @return Pointer to the first occurrence of the
+ * substring, `NULL` if not found.
+ */
+wchar_t* (wcscasestr)(const wchar_t* haystack, const wchar_t* needle)
+{
+ return (wmemcasemem)(haystack, wcslen(haystack), needle, wcslen(needle));
+}
+
diff --git a/src/wchar/wcscat.c b/src/wchar/wcscat.c
index 491f9b7..e6780e4 100644
--- a/src/wchar/wcscat.c
+++ b/src/wchar/wcscat.c
@@ -35,26 +35,3 @@ wchar_t* wcscat(wchar_t* restrict whither, const wchar_t* restrict whence)
return whither;
}
-
-/**
- * Concatenate a string to the end of another string.
- * The resulting strings must not overlap with the appended string.
- *
- * The use of this function is often a really bad idea.
- *
- * @param whither The string to extend.
- * @param whence The string to append.
- * @param maxlen The maximum number of wide characters to copy.
- * NOTE that if the resulting string at least this
- * long, no NUL character will be written to `whither'.
- * On the otherhand, if the resultnig string is
- * shorter, `whither` will be filled with NUL characters
- * until this amount of characters have been written.
- * @return `whither` is returned.
- */
-wchar_t* wcsncat(wchar_t* restrict whither, const wchar_t* restrict whence, size_t maxlen)
-{
- wcsncpy(whither + wcslen(whither), whence, maxlen);
- return whither;
-}
-
diff --git a/src/wchar/wcsccpy.c b/src/wchar/wcsccpy.c
new file mode 100644
index 0000000..e078359
--- /dev/null
+++ b/src/wchar/wcsccpy.c
@@ -0,0 +1,46 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Copy a memory segment to another, non-overlapping, segment,
+ * stop when a NUL wide character or a specified wide character
+ * is encountered.
+ *
+ * This is a slibc extension added for completeness.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @param c The stop character.
+ * @return `NULL` if `c` was not encountered, otherwise
+ * the position of `c` translated to `whither`,
+ * that is, the address of `whither` plus the
+ * number of copied characters; the address of
+ * one character passed the last written non-NUL
+ * character.
+ */
+wchar_t* wcsccpy(wchar_t* restrict whither, const wchar_t* restrict whence, wchar_t c)
+{
+ wchar_t* r = wmemccpy(whither, whence, c, wcslen(whence) + 1);
+ if (r)
+ *r = 0;
+ return r;
+}
+
diff --git a/src/wchar/wcschr.c b/src/wchar/wcschr.c
index 7acc032..8ebe6c1 100644
--- a/src/wchar/wcschr.c
+++ b/src/wchar/wcschr.c
@@ -23,69 +23,6 @@
/**
- * Find the first occurrence of a wide character
- * in a memory segment.
- *
- * @param segment The memory segment to search.
- * @param c The sought after character.
- * @param size The size of the memory segment.
- * @return Pointer to the first occurrence of `c`,
- * `NULL` if none were found.
- */
-wchar_t* (wmemchr)(const wchar_t* segment, wchar_t c, size_t size)
-{
- while (size--)
- if (*segment++ == c)
- return segment - 1;
- return NULL;
-}
-
-
-/**
- * Find the first occurrence of a wide character in a
- * memory segment. The memory segment must be known to
- * contain the sought after character.
- *
- * This is a slibc extension added for completeness.
- *
- * @param segment The memory segment to search.
- * @param c The sought after character.
- * @return Pointer to the first occurrence of `c`.
- */
-wchar_t* (rawwmemchr)(const wchar_t* segment, wchar_t c)
-{
- for (;;)
- if (*segment++ == c)
- return segment - 1;
-}
-
-
-/**
- * Find the last occurrence of a wide character in
- * a memory segment.
- *
- * For improved performace, use this function instead
- * of `wcssrchr` if you already know the length of the
- * string.
- *
- * This is a slibc extension added for completeness.
- *
- * @param segment The memory segment to search.
- * @param c The sought after character.
- * @param size The size of the memory segment.
- * @return Pointer to the last occurrence of `c`,
- * `NULL` if none were found.
- */
-wchar_t* (wmemrchr)(const wchar_t* segment, wchar_t c, size_t size)
-{
- while (size--)
- if (segment[size] == c)
- return segment + size;
- return NULL;
-}
-
-
-/**
* Find the first occurrence of a wide character in a string.
*
* @param string The string to search.
@@ -104,53 +41,3 @@ wchar_t* (wcschr)(const wchar_t* string, wchar_t c)
return NULL;
}
-
-/**
- * Find the first occurrence of a wide character in a
- * string, or if there is no such character, the end of
- * the string.
- *
- * This is a GNU-compliant slibc extension.
- *
- * @param string The string to search.
- * The terminating NUL character is
- * considered a part of the string.
- * @param c The sought after character.
- * @return Pointer to the first occurrence of `c`,
- * Pointer to the terminating NUL character
- * if none were found.
- */
-wchar_t* (wcschrnul)(const wchar_t* string, wchar_t c)
-{
- for (;; string++)
- if (*string == c)
- return string;
- else if (!*string)
- return string;
-}
-
-
-/**
- * Find the last occurrence of a wide character in a string.
- *
- * For improved performace, use `wmemrchr` instead of
- * this function if you already know the length of the
- * string.
- *
- * @param string The string to search.
- * The terminating NUL character is
- * considered a part of the string.
- * @param c The sought after character.
- * @return Pointer to the last occurrence of `c`,
- * `NULL` if none were found.
- */
-wchar_t* (wcsrchr)(const wchar_t* string, wchar_t c)
-{
- wchar_t* r = NULL;
- for (;;)
- if (*string == c)
- r = string;
- else if (!*string++)
- return c ? r : (string - 1);
-}
-
diff --git a/src/wchar/wcschrnul.c b/src/wchar/wcschrnul.c
new file mode 100644
index 0000000..e548e97
--- /dev/null
+++ b/src/wchar/wcschrnul.c
@@ -0,0 +1,48 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
+
+
+
+/**
+ * Find the first occurrence of a wide character in a
+ * string, or if there is no such character, the end of
+ * the string.
+ *
+ * This is a GNU-compliant slibc extension.
+ *
+ * @param string The string to search.
+ * The terminating NUL character is
+ * considered a part of the string.
+ * @param c The sought after character.
+ * @return Pointer to the first occurrence of `c`,
+ * Pointer to the terminating NUL character
+ * if none were found.
+ */
+wchar_t* (wcschrnul)(const wchar_t* string, wchar_t c)
+{
+ for (;; string++)
+ if (*string == c)
+ return string;
+ else if (!*string)
+ return string;
+}
+
diff --git a/src/wchar/wcscmove.c b/src/wchar/wcscmove.c
new file mode 100644
index 0000000..733ec41
--- /dev/null
+++ b/src/wchar/wcscmove.c
@@ -0,0 +1,46 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Copy a memory segment to another, possibly overlapping, segment,
+ * stop when a NUL wide character or a specified wide character
+ * is encountered.
+ *
+ * This is a slibc extension added for completeness.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @param c The stop character.
+ * @return `NULL` if `c` was not encountered, otherwise
+ * the position of `c` translated to `whither`,
+ * that is, the address of `whither` plus the
+ * number of copied characters; the address of
+ * one character passed the last written non-NUL
+ * character.
+ */
+wchar_t* wcscmove(wchar_t* whither, const wchar_t* whence, wchar_t c)
+{
+ wchar_t* r = wmemcmove(whither, whence, c, wcslen(whence) + 1);
+ if (r)
+ *r = 0;
+ return r;
+}
+
diff --git a/src/wchar/wcscmp.c b/src/wchar/wcscmp.c
index 980906d..90ad251 100644
--- a/src/wchar/wcscmp.c
+++ b/src/wchar/wcscmp.c
@@ -16,56 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <wchar.h>
-#include <stdint.h>
-/* TODO #include <wctype.h> */
/**
- * Compare two memory segments alphabetically in a case sensitive manner.
- *
- * @param a A negative value is returned if this is the lesser.
- * @param b A positive value is returned if this is the lesser.
- * @param size The size of the segments.
- * @return Zero is returned if `a` and `b` are equal, otherwise,
- * see the specifications for `a` and `b`.
- */
-int wmemcmp(const wchar_t* a, const wchar_t* b, size_t size)
-{
- while (size--)
- if (*a == *b)
- a++, b++;
- else
- return *a < *b ? -1 : +1;
- return 0;
-}
-
-
-/**
- * Compare two memory segments alphabetically in a case insensitive manner.
- *
- * @param a A negative value is returned if this is the lesser.
- * @param b A positive value is returned if this is the lesser.
- * @param size The size of the segments.
- * @return Zero is returned if `a` and `b` are equal, otherwise,
- * see the specifications for `a` and `b`.
- */
-int wmemcasecmp(const wchar_t* a, const wchar_t* b, size_t size)
-{
- wchar_t c1, c2;
- for (; size--; a++, b++)
- if (*a != *b)
- {
- c1 = iswalpha(*a) ? towlower(*a) : *a;
- c2 = iswalpha(*b) ? towlower(*b) : *b;
- if (c1 != c2)
- return c1 < c2 ? -1 : +1;
- }
- return 0;
-}
-
-
-/**
* Compare two strings alphabetically in a case sensitive manner.
*
* @param a A negative value is returned if this is the lesser.
@@ -80,72 +34,3 @@ int wcscmp(const wchar_t* a, const wchar_t* b)
return wmemcmp(a, b, (n < m ? n : m) + 1);
}
-
-/**
- * Compare two strings alphabetically in a case insensitive manner.
- * Be aware, only ASCII characters are case insensitive, non-ASCII
- * characters are case sensitive.
- *
- * This is a GNU-compliant slibc extension.
- *
- * @param a A negative value is returned if this is the lesser.
- * @param b A positive value is returned if this is the lesser.
- * @return Zero is returned if `a` and `b` are equal, otherwise,
- * see the specifications for `a` and `b`.
- */
-int wcscasecmp(const wchar_t* a, const wchar_t* b)
-{
- return wcsncasecmp(a, b, SIZE_MAX);
-}
-
-
-/**
- * Compare two strings alphabetically in a case sensitive manner.
- *
- * This is a GNU-compliant slibc extension.
- *
- * @param a A negative value is returned if this is the lesser.
- * @param b A positive value is returned if this is the lesser.
- * @param length The maximum number of characters to compare.
- * @return Zero is returned if `a` and `b` are equal, otherwise,
- * see the specifications for `a` and `b`.
- */
-int wcsncmp(const wchar_t* a, const wchar_t* b, size_t length)
-{
- size_t n = wcsnlen(a, length);
- size_t m = wcsnlen(b, length);
- int r = wmemcmp(a, b, (n < m ? n : m));
- return r ? r : n == m ? 0 : n < m ? -1 : +1;
-}
-
-
-/**
- * Compare two strings alphabetically in a case insensitive manner.
- * Be aware, only ASCII characters are case insensitive, non-ASCII
- * characters are case sensitive.
- *
- * This is a GNU-compliant slibc extension.
- *
- * @param a A negative value is returned if this is the lesser.
- * @param b A positive value is returned if this is the lesser.
- * @param length The maximum number of characters to compare.
- * @return Zero is returned if `a` and `b` are equal, otherwise,
- * see the specifications for `a` and `b`.
- */
-int wcsncasecmp(const wchar_t* a, const wchar_t* b, size_t length)
-{
- wchar_t c1, c2;
- for (; length--; a++, b++)
- if (*a != *b)
- {
- c1 = iswalpha(*a) ? towlower(*a) : *a;
- c2 = iswalpha(*b) ? towlower(*b) : *b;
- if (c1 < c2) return -1;
- if (c1 > c2) return +1;
- }
- else if (!*a && !*b) return 0;
- else if (!*a) return -1;
- else if (!*b) return +1;
- return 0;
-}
-
diff --git a/src/wchar/wcscncpy.c b/src/wchar/wcscncpy.c
new file mode 100644
index 0000000..91af467
--- /dev/null
+++ b/src/wchar/wcscncpy.c
@@ -0,0 +1,55 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Copy a memory segment to another, non-overlapping, segment,
+ * stop when a NUL wide character or a specified wide character
+ * is encountered.
+ *
+ * This is a slibc extension added for completeness.
+ * It is only available if GNU extensions are available.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @param c The stop character.
+ * @param maxlen The maximum number of wide characters to copy.
+ * NOTE that if the resulting string at least this
+ * long, no NUL character will be written to `whither'.
+ * On the otherhand, if the resultnig string is
+ * shorter, `whither` will be filled with NUL characters
+ * until this amount of characters have been written.
+ * @return `NULL` if `c` was not encountered, otherwise
+ * the position of `c` translated to `whither`,
+ * that is, the address of `whither` plus the
+ * number of copied characters; the address of
+ * one character passed the last written non-NUL
+ * character.
+ */
+wchar_t* wcscncpy(wchar_t* restrict whither, const wchar_t* restrict whence, wchar_t c, size_t maxlen)
+{
+ const wchar_t* stop = wmemchr(whence, c, maxlen);
+ size_t n = stop == NULL ? wcsnlen(whence, maxlen) : (size_t)(stop - whence);
+ wchar_t* r = stop == NULL ? NULL : (whither + n);
+ wmemcpy(whither, whence, n);
+ wmemset(whither, 0, maxlen - n);
+ return r;
+}
+
diff --git a/src/wchar/wcscnmove.c b/src/wchar/wcscnmove.c
new file mode 100644
index 0000000..005a80c
--- /dev/null
+++ b/src/wchar/wcscnmove.c
@@ -0,0 +1,55 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Copy a memory segment to another, possibly overlapping, segment,
+ * stop when a NUL wide character or a specified wide character
+ * is encountered.
+ *
+ * This is a slibc extension added for completeness.
+ * It is only available if GNU extensions are available.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @param c The stop character.
+ * @param maxlen The maximum number of wide characters to copy.
+ * NOTE that if the resulting string at least this
+ * long, no NUL character will be written to `whither'.
+ * On the otherhand, if the resultnig string is
+ * shorter, `whither` will be filled with NUL characters
+ * until this amount of characters have been written.
+ * @return `NULL` if `c` was not encountered, otherwise
+ * the position of `c` translated to `whither`,
+ * that is, the address of `whither` plus the
+ * number of copied characters; the address of
+ * one character passed the last written non-NUL
+ * character.
+ */
+wchar_t* wcscnmove(wchar_t* whither, const wchar_t* whence, wchar_t c, size_t maxlen)
+{
+ const wchar_t* stop = wmemchr(whence, c, maxlen);
+ size_t n = stop == NULL ? wcsnlen(whence, maxlen) : (size_t)(stop - whence);
+ wchar_t* r = stop == NULL ? NULL : (whither + n);
+ wmemmove(whither, whence, n);
+ wmemset(whither, 0, maxlen - n);
+ return r;
+}
+
diff --git a/src/wchar/wcscpy.c b/src/wchar/wcscpy.c
index 9c1207d..671e894 100644
--- a/src/wchar/wcscpy.c
+++ b/src/wchar/wcscpy.c
@@ -32,191 +32,3 @@ wchar_t* wcscpy(wchar_t* restrict whither, const wchar_t* restrict whence)
return wmemcpy(whither, whence, wcslen(whence) + 1);
}
-
-/**
- * Copy a memory segment to another, non-overlapping, segment,
- * stop when a NUL wide character is encountered.
- *
- * This is a GNU-compliant slibc extension.
- *
- * @param whither The destination memory segment.
- * @param whence The source memory segment.
- * @return `whither + wcslen(whence)` is returned.
- */
-wchar_t* wcpcpy(wchar_t* restrict whither, const wchar_t* restrict whence)
-{
- return wmempcpy(whither, whence, wcslen(whence) + 1) - 1;
-}
-
-
-/**
- * Copy a memory segment to another, non-overlapping, segment,
- * stop when a NUL wide character or a specified wide character
- * is encountered.
- *
- * This is a slibc extension added for completeness.
- *
- * @param whither The destination memory segment.
- * @param whence The source memory segment.
- * @param c The stop character.
- * @return `NULL` if `c` was not encountered, otherwise
- * the position of `c` translated to `whither`,
- * that is, the address of `whither` plus the
- * number of copied characters; the address of
- * one character passed the last written non-NUL
- * character.
- */
-wchar_t* wcsccpy(wchar_t* restrict whither, const wchar_t* restrict whence, wchar_t c)
-{
- wchar_t* r = wmemccpy(whither, whence, c, wcslen(whence) + 1);
- if (r)
- *r = 0;
- return r;
-}
-
-
-/**
- * Copy a memory segment to another, non-overlapping, segment,
- * stop when a NUL wide character or a specified substring is encountered.
- *
- * This is a slibc extension added for completeness.
- *
- * @param whither The destination memory segment.
- * @param whence The source memory segment.
- * @param str The substring, ignored if `NULL`.
- * @return `NULL` if `str` was not encountered, otherwise
- * the position of `str` translated to `whither`,
- * that is, the address of `whither` plus the
- * number of copied characters; the address of
- * one character passed the last written non-NUL
- * character.
- */
-wchar_t* wcsstrcpy(wchar_t* restrict whither, const wchar_t* restrict whence, const wchar_t* restrict str)
-{
- const wchar_t* stop = str == NULL ? NULL : wcsstr(whence, str);
- size_t n = stop == NULL ? wcslen(whence) : (size_t)(stop - whence);
- wchar_t* r = stop == NULL ? NULL : (whither + n);
- wmemcpy(whither, whence, n);
- whither[n] = 0;
- return r;
-}
-
-
-/**
- * Copy a memory segment to another, non-overlapping, segment,
- * stop when a NUL wide character is encountered.
- *
- * @param whither The destination memory segment.
- * @param whence The source memory segment.
- * @param maxlen The maximum number of wide characters to copy.
- * NOTE that if the resulting string at least this
- * long, no NUL character will be written to `whither'.
- * On the otherhand, if the resultnig string is
- * shorter, `whither` will be filled with NUL characters
- * until this amount of characters have been written.
- * @return `whither` is returned.
- */
-wchar_t* wcsncpy(wchar_t* restrict whither, const wchar_t* restrict whence, size_t maxlen)
-{
- size_t n = wcsnlen(whence, maxlen);
- wmemcpy(whither, whence, n);
- wmemset(whither, 0, maxlen - n);
- return whither;
-}
-
-
-/**
- * Copy a memory segment to another, non-overlapping, segment,
- * stop when a NUL wide character is encountered.
- *
- * This is a GNU extension.
- *
- * @param whither The destination memory segment.
- * @param whence The source memory segment.
- * @param maxlen The maximum number of wide characters to copy.
- * NOTE that if the resulting string at least this
- * long, no NUL character will be written to `whither'.
- * On the otherhand, if the resultnig string is
- * shorter, `whither` will be filled with NUL characters
- * until this amount of characters have been written.
- * @return `whither` plus the number of written characters,
- * excluding NUL characters, is returned.
- */
-wchar_t* wcpncpy(wchar_t* restrict whither, const wchar_t* restrict whence, size_t maxlen)
-{
- size_t n = wcsnlen(whence, maxlen);
- wmemcpy(whither, whence, n);
- wmemset(whither, 0, maxlen - n);
- return whither + n;
-}
-
-
-/**
- * Copy a memory segment to another, non-overlapping, segment,
- * stop when a NUL wide character or a specified wide character
- * is encountered.
- *
- * This is a slibc extension added for completeness.
- * It is only available if GNU extensions are available.
- *
- * @param whither The destination memory segment.
- * @param whence The source memory segment.
- * @param c The stop character.
- * @param maxlen The maximum number of wide characters to copy.
- * NOTE that if the resulting string at least this
- * long, no NUL character will be written to `whither'.
- * On the otherhand, if the resultnig string is
- * shorter, `whither` will be filled with NUL characters
- * until this amount of characters have been written.
- * @return `NULL` if `c` was not encountered, otherwise
- * the position of `c` translated to `whither`,
- * that is, the address of `whither` plus the
- * number of copied characters; the address of
- * one character passed the last written non-NUL
- * character.
- */
-wchar_t* wcscncpy(wchar_t* restrict whither, const wchar_t* restrict whence, wchar_t c, size_t maxlen)
-{
- const wchar_t* stop = wmemchr(whence, c, maxlen);
- size_t n = stop == NULL ? wcsnlen(whence, maxlen) : (size_t)(stop - whence);
- wchar_t* r = stop == NULL ? NULL : (whither + n);
- wmemcpy(whither, whence, n);
- wmemset(whither, 0, maxlen - n);
- return r;
-}
-
-
-/**
- * Copy a memory segment to another, non-overlapping, segment,
- * stop when a NUL wide character or a specified substring is encountered.
- *
- * This is a slibc extension added for completeness.
- * It is only available if GNU extensions are available.
- *
- * @param whither The destination memory segment.
- * @param whence The source memory segment.
- * @param str The substring, ignored if `NULL`.
- * @param maxlen The maximum number of wide characters to copy.
- * NOTE that if the resulting string at least this
- * long, no NUL character will be written to `whither'.
- * On the otherhand, if the resultnig string is
- * shorter, `whither` will be filled with NUL characters
- * until this amount of characters have been written.
- * @return `NULL` if `str` was not encountered, otherwise
- * the position of `str` translated to `whither`,
- * that is, the address of `whither` plus the
- * number of copied chartacters; the address of
- * one character passed the last written non-NUL
- * character.
- */
-wchar_t* wcsstrncpy(wchar_t* restrict whither, const wchar_t* restrict whence,
- const wchar_t* restrict str, size_t maxlen)
-{
- const wchar_t* stop = wcsnstr(whence, str, maxlen);
- size_t n = stop == NULL ? wcsnlen(whence, maxlen) : (size_t)(stop - whence);
- wchar_t* r = stop == NULL ? NULL : (whither + n);
- wmemcpy(whither, whence, n);
- wmemset(whither, 0, maxlen - n);
- return r;
-}
-
diff --git a/src/wchar/wcscspn.c b/src/wchar/wcscspn.c
new file mode 100644
index 0000000..f32af00
--- /dev/null
+++ b/src/wchar/wcscspn.c
@@ -0,0 +1,48 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
+
+
+
+/**
+ * Returns length of the initial substring
+ * that consists entirely of the complement
+ * of a set of specified wide characters.
+ *
+ * @param string The string.
+ * @param stopset Characters disallowed in the substring.
+ * @return The length of the substring.
+ */
+size_t wcscspn(const wchar_t* string, const wchar_t* stopset)
+{
+ size_t i, end = wcslen(string);
+ wchar_t* s;
+ wchar_t c;
+ while ((c = *stopset++))
+ for (i = 0, s = string; *s && (i < end); i++, s++)
+ if (*s == c)
+ {
+ end = (size_t)(s - string);
+ break;
+ }
+ return end;
+}
+
diff --git a/src/wchar/wcsdup.c b/src/wchar/wcsdup.c
index fa68834..62fef76 100644
--- a/src/wchar/wcsdup.c
+++ b/src/wchar/wcsdup.c
@@ -38,45 +38,3 @@ wchar_t* wcsdup(const wchar_t* string)
return r == NULL ? NULL : wmemcpy(r, string, n);
}
-
-/**
- * Duplicate a string.
- *
- * This is a slibc extension added for completeness.
- * It is only available if GNU extensions are available.
- *
- * @param string The string to duplicate.
- * @param maxlen Truncate the string to this length, if it is longer.
- * A NUL wide character is guaranteed to always be
- * written upon successful completion.
- * @return The new string. `NULL` is returned on error
- * and `errno` is set to indicate the error.
- *
- * @throws ENOMEM The process could not allocate sufficient amount of memory.
- */
-wchar_t* wcsndup(const wchar_t* string, size_t maxlen)
-{
- size_t n = wcsnlen(string, maxlen) + 1;
- wchar_t* r = malloc(n * sizeof(wchar_t));
- return r == NULL ? NULL : wmemcpy(r, string, n);
-}
-
-
-/**
- * Duplicate a memory segment.
- *
- * This is a slibc extension added for completeness.
- *
- * @param segment The memory segment to duplicate.
- * @param size The size of the memory segment.
- * @return The new segment. `NULL` is returned on error
- * and `errno` is set to indicate the error.
- *
- * @throws ENOMEM The process could not allocate sufficient amount of memory.
- */
-wchar_t* wmemdup(const wchar_t* segment, size_t size)
-{
- wchar_t* r = malloc(size * sizeof(wchar_t));
- return r == NULL ? NULL : wmemcpy(r, segment, size);
-}
-
diff --git a/src/wchar/wcsends.c b/src/wchar/wcsends.c
new file mode 100644
index 0000000..2f585f4
--- /dev/null
+++ b/src/wchar/wcsends.c
@@ -0,0 +1,41 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Check whether a string ends with a specific string.
+ * This check is case sensitive.
+ *
+ * This is a slibc extension.
+ *
+ * @param string The string to inspect.
+ * @param desired The desired ending of the string.
+ * @return The `string`, where `desired` beings if
+ * `string` ends with `desired`, `NULL` otherwise.
+ */
+wchar_t* (wcsends)(const wchar_t* string, const wchar_t* desired)
+{
+ size_t n = wcslen(string);
+ size_t m = wcslen(desired);
+ if (n < m)
+ return NULL;
+ return wmemcmp(string + (n - m), desired, m) ? NULL : (string + n);
+}
+
diff --git a/src/wchar/wcslen.c b/src/wchar/wcslen.c
index b4a07c6..5c0be9f 100644
--- a/src/wchar/wcslen.c
+++ b/src/wchar/wcslen.c
@@ -33,19 +33,3 @@ size_t wcslen(const wchar_t* str)
return (size_t)(s - 1 - str);
}
-
-/**
- * `wchar_t` version of `strnlen`.
- *
- * @param str The string.
- * @param maxlen The number of bytes to inspect, at most.
- * @return The number of `wchar_t`:s before the
- * first NUL character. `maxlen` if no
- * NUL character was found.
- */
-size_t wcsnlen(const wchar_t* str, size_t maxlen)
-{
- const wchar_t* end = wmemchr(str, 0, maxlen);
- return end == NULL ? maxlen : (size_t)(end - str);
-}
-
diff --git a/src/wchar/wcsmove.c b/src/wchar/wcsmove.c
index 4e2f773..377662c 100644
--- a/src/wchar/wcsmove.c
+++ b/src/wchar/wcsmove.c
@@ -34,191 +34,3 @@ wchar_t* wcsmove(wchar_t* whither, const wchar_t* whence)
return wmemmove(whither, whence, wcslen(whence) + 1);
}
-
-/**
- * Copy a memory segment to another, possibly overlapping, segment,
- * stop when a NUL wide character is encountered.
- *
- * This is a slibc extension added for completeness.
- *
- * @param whither The destination memory segment.
- * @param whence The source memory segment.
- * @return `whither + wcslen(whence)` is returned.
- */
-wchar_t* wcpmove(wchar_t* whither, const wchar_t* whence)
-{
- return wmempmove(whither, whence, wcslen(whence) + 1) - 1;
-}
-
-
-/**
- * Copy a memory segment to another, possibly overlapping, segment,
- * stop when a NUL wide character or a specified wide character
- * is encountered.
- *
- * This is a slibc extension added for completeness.
- *
- * @param whither The destination memory segment.
- * @param whence The source memory segment.
- * @param c The stop character.
- * @return `NULL` if `c` was not encountered, otherwise
- * the position of `c` translated to `whither`,
- * that is, the address of `whither` plus the
- * number of copied characters; the address of
- * one character passed the last written non-NUL
- * character.
- */
-wchar_t* wcscmove(wchar_t* whither, const wchar_t* whence, wchar_t c)
-{
- wchar_t* r = wmemcmove(whither, whence, c, wcslen(whence) + 1);
- if (r)
- *r = 0;
- return r;
-}
-
-
-/**
- * Copy a memory segment to another, possibly overlapping, segment,
- * stop when a NUL wide character or a specified substring is encountered.
- *
- * This is a slibc extension added for completeness.
- *
- * @param whither The destination memory segment.
- * @param whence The source memory segment.
- * @param str The substring, ignored if `NULL`.
- * @return `NULL` if `str` was not encountered, otherwise
- * the position of `str` translated to `whither`,
- * that is, the address of `whither` plus the
- * number of copied characters; the address of
- * one character passed the last written non-NUL
- * character.
- */
-wchar_t* wcsstrmove(wchar_t* whither, const wchar_t* whence, const wchar_t* restrict str)
-{
- const wchar_t* stop = str == NULL ? NULL : wcsstr(whence, str);
- size_t n = stop == NULL ? wcslen(whence) : (size_t)(stop - whence);
- wchar_t* r = stop == NULL ? NULL : (whither + n);
- wmemmove(whither, whence, n);
- whither[n] = 0;
- return r;
-}
-
-
-/**
- * Copy a memory segment to another, possibly overlapping, segment,
- * stop when a NUL wide character is encountered.
- *
- * @param whither The destination memory segment.
- * @param whence The source memory segment.
- * @param maxlen The maximum number of wide characters to copy.
- * NOTE that if the resulting string at least this
- * long, no NUL character will be written to `whither'.
- * On the otherhand, if the resultnig string is
- * shorter, `whither` will be filled with NUL characters
- * until this amount of characters have been written.
- * @return `whither` is returned.
- */
-wchar_t* wcsnmove(wchar_t* whither, const wchar_t* whence, size_t maxlen)
-{
- size_t n = wcsnlen(whence, maxlen);
- wmemmove(whither, whence, n);
- wmemset(whither, 0, maxlen - n);
- return whither;
-}
-
-
-/**
- * Copy a memory segment to another, possibly overlapping, segment,
- * stop when a NUL wide character is encountered.
- *
- * This is a slibc extension added for completeness.
- * It is only available if GNU extensions are available.
- *
- * @param whither The destination memory segment.
- * @param whence The source memory segment.
- * @param maxlen The maximum number of wide characters to copy.
- * NOTE that if the resulting string at least this
- * long, no NUL character will be written to `whither'.
- * On the otherhand, if the resultnig string is
- * shorter, `whither` will be filled with NUL characters
- * until this amount of characters have been written.
- * @return `whither` plus the number of written characters,
- * excluding NUL characters, is returned.
- */
-wchar_t* wcpnmove(wchar_t* whither, const wchar_t* whence, size_t maxlen)
-{
- size_t n = wcsnlen(whence, maxlen);
- wmemmove(whither, whence, n);
- wmemset(whither, 0, maxlen - n);
- return whither + n;
-}
-
-
-/**
- * Copy a memory segment to another, possibly overlapping, segment,
- * stop when a NUL wide character or a specified wide character
- * is encountered.
- *
- * This is a slibc extension added for completeness.
- * It is only available if GNU extensions are available.
- *
- * @param whither The destination memory segment.
- * @param whence The source memory segment.
- * @param c The stop character.
- * @param maxlen The maximum number of wide characters to copy.
- * NOTE that if the resulting string at least this
- * long, no NUL character will be written to `whither'.
- * On the otherhand, if the resultnig string is
- * shorter, `whither` will be filled with NUL characters
- * until this amount of characters have been written.
- * @return `NULL` if `c` was not encountered, otherwise
- * the position of `c` translated to `whither`,
- * that is, the address of `whither` plus the
- * number of copied characters; the address of
- * one character passed the last written non-NUL
- * character.
- */
-wchar_t* wcscnmove(wchar_t* whither, const wchar_t* whence, wchar_t c, size_t maxlen)
-{
- const wchar_t* stop = wmemchr(whence, c, maxlen);
- size_t n = stop == NULL ? wcsnlen(whence, maxlen) : (size_t)(stop - whence);
- wchar_t* r = stop == NULL ? NULL : (whither + n);
- wmemmove(whither, whence, n);
- wmemset(whither, 0, maxlen - n);
- return r;
-}
-
-
-/**
- * Copy a memory segment to another, possibly overlapping, segment,
- * stop when a NUL wide character or a specified substring is encountered.
- *
- * This is a slibc extension added for completeness.
- * It is only available if GNU extensions are available.
- *
- * @param whither The destination memory segment.
- * @param whence The source memory segment.
- * @param str The substring, ignored if `NULL`.
- * @param maxlen The maximum number of wide characters to copy.
- * NOTE that if the resulting string at least this
- * long, no NUL character will be written to `whither'.
- * On the otherhand, if the resultnig string is
- * shorter, `whither` will be filled with NUL characters
- * until this amount of characters have been written.
- * @return `NULL` if `str` was not encountered, otherwise
- * the position of `str` translated to `whither`,
- * that is, the address of `whither` plus the
- * number of copied chartacters; the address of
- * one character passed the last written non-NUL
- * character.
- */
-wchar_t* wcsstrnmove(wchar_t* whither, const wchar_t* whence, const wchar_t* restrict str, size_t maxlen)
-{
- const wchar_t* stop = wcsnstr(whence, str, maxlen);
- size_t n = stop == NULL ? wcsnlen(whence, maxlen) : (size_t)(stop - whence);
- wchar_t* r = stop == NULL ? NULL : (whither + n);
- wmemmove(whither, whence, n);
- wmemset(whither, 0, maxlen - n);
- return r;
-}
-
diff --git a/src/wchar/wcsncasecmp.c b/src/wchar/wcsncasecmp.c
new file mode 100644
index 0000000..69305ea
--- /dev/null
+++ b/src/wchar/wcsncasecmp.c
@@ -0,0 +1,52 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+/* TODO #include <wctype.h> */
+
+
+
+/**
+ * Compare two strings alphabetically in a case insensitive manner.
+ * Be aware, only ASCII characters are case insensitive, non-ASCII
+ * characters are case sensitive.
+ *
+ * This is a GNU-compliant slibc extension.
+ *
+ * @param a A negative value is returned if this is the lesser.
+ * @param b A positive value is returned if this is the lesser.
+ * @param length The maximum number of characters to compare.
+ * @return Zero is returned if `a` and `b` are equal, otherwise,
+ * see the specifications for `a` and `b`.
+ */
+int wcsncasecmp(const wchar_t* a, const wchar_t* b, size_t length)
+{
+ wchar_t c1, c2;
+ for (; length--; a++, b++)
+ if (*a != *b)
+ {
+ c1 = iswalpha(*a) ? towlower(*a) : *a;
+ c2 = iswalpha(*b) ? towlower(*b) : *b;
+ if (c1 < c2) return -1;
+ if (c1 > c2) return +1;
+ }
+ else if (!*a && !*b) return 0;
+ else if (!*a) return -1;
+ else if (!*b) return +1;
+ return 0;
+}
+
diff --git a/src/wchar/wcsncasestr.c b/src/wchar/wcsncasestr.c
new file mode 100644
index 0000000..9818de7
--- /dev/null
+++ b/src/wchar/wcsncasestr.c
@@ -0,0 +1,38 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Finds the first occurrence of a substring.
+ * This search is case insensitive.
+ *
+ * This is a slibc extension added for completeness.
+ *
+ * @param haystack The string to search.
+ * @param needle The sought after substring.
+ * @param maxlen The maximum number of character to search.
+ * @return Pointer to the first occurrence of the
+ * substring, `NULL` if not found.
+ */
+wchar_t* (wcsncasestr)(const wchar_t* haystack, const wchar_t* needle, size_t maxlen)
+{
+ return (wmemcasemem)(haystack, wcsnlen(haystack, maxlen), needle, wcslen(needle));
+}
+
diff --git a/src/wchar/wcsncat.c b/src/wchar/wcsncat.c
new file mode 100644
index 0000000..bd48265
--- /dev/null
+++ b/src/wchar/wcsncat.c
@@ -0,0 +1,43 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Concatenate a string to the end of another string.
+ * The resulting strings must not overlap with the appended string.
+ *
+ * The use of this function is often a really bad idea.
+ *
+ * @param whither The string to extend.
+ * @param whence The string to append.
+ * @param maxlen The maximum number of wide characters to copy.
+ * NOTE that if the resulting string at least this
+ * long, no NUL character will be written to `whither'.
+ * On the otherhand, if the resultnig string is
+ * shorter, `whither` will be filled with NUL characters
+ * until this amount of characters have been written.
+ * @return `whither` is returned.
+ */
+wchar_t* wcsncat(wchar_t* restrict whither, const wchar_t* restrict whence, size_t maxlen)
+{
+ wcsncpy(whither + wcslen(whither), whence, maxlen);
+ return whither;
+}
+
diff --git a/src/wchar/wcsncmp.c b/src/wchar/wcsncmp.c
new file mode 100644
index 0000000..c1e5707
--- /dev/null
+++ b/src/wchar/wcsncmp.c
@@ -0,0 +1,40 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Compare two strings alphabetically in a case sensitive manner.
+ *
+ * This is a GNU-compliant slibc extension.
+ *
+ * @param a A negative value is returned if this is the lesser.
+ * @param b A positive value is returned if this is the lesser.
+ * @param length The maximum number of characters to compare.
+ * @return Zero is returned if `a` and `b` are equal, otherwise,
+ * see the specifications for `a` and `b`.
+ */
+int wcsncmp(const wchar_t* a, const wchar_t* b, size_t length)
+{
+ size_t n = wcsnlen(a, length);
+ size_t m = wcsnlen(b, length);
+ int r = wmemcmp(a, b, (n < m ? n : m));
+ return r ? r : n == m ? 0 : n < m ? -1 : +1;
+}
+
diff --git a/src/wchar/wcsncpy.c b/src/wchar/wcsncpy.c
new file mode 100644
index 0000000..56f342d
--- /dev/null
+++ b/src/wchar/wcsncpy.c
@@ -0,0 +1,43 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Copy a memory segment to another, non-overlapping, segment,
+ * stop when a NUL wide character is encountered.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @param maxlen The maximum number of wide characters to copy.
+ * NOTE that if the resulting string at least this
+ * long, no NUL character will be written to `whither'.
+ * On the otherhand, if the resultnig string is
+ * shorter, `whither` will be filled with NUL characters
+ * until this amount of characters have been written.
+ * @return `whither` is returned.
+ */
+wchar_t* wcsncpy(wchar_t* restrict whither, const wchar_t* restrict whence, size_t maxlen)
+{
+ size_t n = wcsnlen(whence, maxlen);
+ wmemcpy(whither, whence, n);
+ wmemset(whither, 0, maxlen - n);
+ return whither;
+}
+
diff --git a/src/wchar/wcsndup.c b/src/wchar/wcsndup.c
new file mode 100644
index 0000000..db81f07
--- /dev/null
+++ b/src/wchar/wcsndup.c
@@ -0,0 +1,44 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+#include <stdlib.h>
+
+
+
+/**
+ * Duplicate a string.
+ *
+ * This is a slibc extension added for completeness.
+ * It is only available if GNU extensions are available.
+ *
+ * @param string The string to duplicate.
+ * @param maxlen Truncate the string to this length, if it is longer.
+ * A NUL wide character is guaranteed to always be
+ * written upon successful completion.
+ * @return The new string. `NULL` is returned on error
+ * and `errno` is set to indicate the error.
+ *
+ * @throws ENOMEM The process could not allocate sufficient amount of memory.
+ */
+wchar_t* wcsndup(const wchar_t* string, size_t maxlen)
+{
+ size_t n = wcsnlen(string, maxlen) + 1;
+ wchar_t* r = malloc(n * sizeof(wchar_t));
+ return r == NULL ? NULL : wmemcpy(r, string, n);
+}
+
diff --git a/src/wchar/wcsnlen.c b/src/wchar/wcsnlen.c
new file mode 100644
index 0000000..a094d28
--- /dev/null
+++ b/src/wchar/wcsnlen.c
@@ -0,0 +1,36 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * `wchar_t` version of `strnlen`.
+ *
+ * @param str The string.
+ * @param maxlen The number of bytes to inspect, at most.
+ * @return The number of `wchar_t`:s before the
+ * first NUL character. `maxlen` if no
+ * NUL character was found.
+ */
+size_t wcsnlen(const wchar_t* str, size_t maxlen)
+{
+ const wchar_t* end = wmemchr(str, 0, maxlen);
+ return end == NULL ? maxlen : (size_t)(end - str);
+}
+
diff --git a/src/wchar/wcsnmove.c b/src/wchar/wcsnmove.c
new file mode 100644
index 0000000..1abe3f0
--- /dev/null
+++ b/src/wchar/wcsnmove.c
@@ -0,0 +1,43 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Copy a memory segment to another, possibly overlapping, segment,
+ * stop when a NUL wide character is encountered.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @param maxlen The maximum number of wide characters to copy.
+ * NOTE that if the resulting string at least this
+ * long, no NUL character will be written to `whither'.
+ * On the otherhand, if the resultnig string is
+ * shorter, `whither` will be filled with NUL characters
+ * until this amount of characters have been written.
+ * @return `whither` is returned.
+ */
+wchar_t* wcsnmove(wchar_t* whither, const wchar_t* whence, size_t maxlen)
+{
+ size_t n = wcsnlen(whence, maxlen);
+ wmemmove(whither, whence, n);
+ wmemset(whither, 0, maxlen - n);
+ return whither;
+}
+
diff --git a/src/wchar/wcsnstr.c b/src/wchar/wcsnstr.c
new file mode 100644
index 0000000..266ebf4
--- /dev/null
+++ b/src/wchar/wcsnstr.c
@@ -0,0 +1,39 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Finds the first occurrence of a substring.
+ * This search is case sensitive.
+ *
+ * This is a slibc extension added for because it was useful
+ * in implementing slibc itself.
+ *
+ * @param haystack The string to search.
+ * @param needle The sought after substring.
+ * @param maxlen The maximum number of character to search.
+ * @return Pointer to the first occurrence of the
+ * substring, `NULL` if not found.
+ */
+wchar_t* (wcsnstr)(const wchar_t* haystack, const wchar_t* needle, size_t maxlen)
+{
+ return (wmemmem)(haystack, wcsnlen(haystack, maxlen), needle, wcslen(needle));
+}
+
diff --git a/src/wchar/wcspbrk.c b/src/wchar/wcspbrk.c
new file mode 100644
index 0000000..1cbb176
--- /dev/null
+++ b/src/wchar/wcspbrk.c
@@ -0,0 +1,42 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
+
+
+
+/**
+ * This function works like `strcspn`,
+ * except it returns the pointer to the
+ * location of the first found non-matching
+ * wide character.
+ *
+ * @param string The string.
+ * @param stopset Bytes disallowed in the substring.
+ * @return A pointer to the first occurrence in
+ * `string` of a character found in `stopset`.
+ * `NULL` is returned if none is found.
+ */
+wchar_t* (wcspbrk)(const wchar_t* string, const wchar_t* stopset)
+{
+ string += wcscspn(string, stopset);
+ return *string ? string : NULL;
+}
+
diff --git a/src/wchar/wcsrchr.c b/src/wchar/wcsrchr.c
new file mode 100644
index 0000000..3f6e84c
--- /dev/null
+++ b/src/wchar/wcsrchr.c
@@ -0,0 +1,48 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
+
+
+
+/**
+ * Find the last occurrence of a wide character in a string.
+ *
+ * For improved performace, use `wmemrchr` instead of
+ * this function if you already know the length of the
+ * string.
+ *
+ * @param string The string to search.
+ * The terminating NUL character is
+ * considered a part of the string.
+ * @param c The sought after character.
+ * @return Pointer to the last occurrence of `c`,
+ * `NULL` if none were found.
+ */
+wchar_t* (wcsrchr)(const wchar_t* string, wchar_t c)
+{
+ wchar_t* r = NULL;
+ for (;;)
+ if (*string == c)
+ r = string;
+ else if (!*string++)
+ return c ? r : (string - 1);
+}
+
diff --git a/src/wchar/wcssep.c b/src/wchar/wcssep.c
new file mode 100644
index 0000000..9e3f285
--- /dev/null
+++ b/src/wchar/wcssep.c
@@ -0,0 +1,53 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Tokenise a string.
+ *
+ * This is a slibc extension.
+ *
+ * @param string Pointer to the string to tokenise on the first call,
+ * will be updated to keep track of the state.
+ * All characters found in `delimiters` will
+ * be overriden with NUL characters.
+ * @param delimiters Delimiting characters.
+ * @return The next, possibly empty, string that does
+ * not contain a byte from `delimiters`. The
+ * returned string will be as long as possible.
+ * `NULL` is returned the search as reached
+ * the end of the string, and there therefore
+ * are no more tokens.
+ */
+wchar_t* wcssep(wchar_t** restrict string, const wchar_t* restrict delimiters)
+{
+ wchar_t* r = *string;
+ wchar_t* next;
+ if (r == NULL)
+ return NULL;
+
+ next = wcspbrk(r, delimiters);
+ if (next != NULL)
+ *next++ = 0;
+ *string = next;
+
+ return r;
+}
+
diff --git a/src/wchar/wcsspn.c b/src/wchar/wcsspn.c
index e4a1190..4a023d5 100644
--- a/src/wchar/wcsspn.c
+++ b/src/wchar/wcsspn.c
@@ -41,47 +41,3 @@ size_t wcsspn(const wchar_t* string, const wchar_t* skipset)
return (size_t)(s - 1 - string);
}
-
-/**
- * Returns length of the initial substring
- * that consists entirely of the complement
- * of a set of specified wide characters.
- *
- * @param string The string.
- * @param stopset Characters disallowed in the substring.
- * @return The length of the substring.
- */
-size_t wcscspn(const wchar_t* string, const wchar_t* stopset)
-{
- size_t i, end = wcslen(string);
- wchar_t* s;
- wchar_t c;
- while ((c = *stopset++))
- for (i = 0, s = string; *s && (i < end); i++, s++)
- if (*s == c)
- {
- end = (size_t)(s - string);
- break;
- }
- return end;
-}
-
-
-/**
- * This function works like `strcspn`,
- * except it returns the pointer to the
- * location of the first found non-matching
- * wide character.
- *
- * @param string The string.
- * @param stopset Bytes disallowed in the substring.
- * @return A pointer to the first occurrence in
- * `string` of a character found in `stopset`.
- * `NULL` is returned if none is found.
- */
-wchar_t* (wcspbrk)(const wchar_t* string, const wchar_t* stopset)
-{
- string += wcscspn(string, stopset);
- return *string ? string : NULL;
-}
-
diff --git a/src/wchar/wcsstarts.c b/src/wchar/wcsstarts.c
new file mode 100644
index 0000000..0b000af
--- /dev/null
+++ b/src/wchar/wcsstarts.c
@@ -0,0 +1,41 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Check whether a string starts with a specific string.
+ * This check is case sensitive.
+ *
+ * This is a slibc extension.
+ *
+ * @param string The string to inspect.
+ * @param desired The desired beginning of the string.
+ * @return `string` if `string` begins with
+ * `desired`, `NULL` otherwise.
+ */
+wchar_t* (wcsstarts)(const wchar_t* string, const wchar_t* desired)
+{
+ size_t n = wcslen(string);
+ size_t m = wcslen(desired);
+ if (n < m)
+ return NULL;
+ return wmemcmp(string, desired, m) ? NULL : string;
+}
+
diff --git a/src/wchar/wcsstr.c b/src/wchar/wcsstr.c
index b0600e1..e88530d 100644
--- a/src/wchar/wcsstr.c
+++ b/src/wchar/wcsstr.c
@@ -16,27 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <wchar.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <alloca.h>
-/* TODO #include <wctype.h> */
-#define WIDE
-
-
-# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
-
-
-
-/**
- * This function is identical to `wcsstr`.
- */
-wchar_t* (wcswcs)(const wchar_t* haystack, const wchar_t* needle)
-{
- if (*needle && !(needle[1]))
- return (wcschr)(haystack, *needle);
- return (wcsstr)(haystack, needle);
-}
/**
@@ -50,231 +30,8 @@ wchar_t* (wcswcs)(const wchar_t* haystack, const wchar_t* needle)
*/
wchar_t* (wcsstr)(const wchar_t* haystack, const wchar_t* needle)
{
+ if (*needle && !(needle[1]))
+ return (wcschr)(haystack, *needle);
return (wmemmem)(haystack, wcslen(haystack), needle, wcslen(needle));
}
-
-/**
- * Finds the first occurrence of a substring.
- * This search is case insensitive.
- *
- * This is a slibc extension.
- *
- * @param haystack The string to search.
- * @param needle The sought after substring.
- * @return Pointer to the first occurrence of the
- * substring, `NULL` if not found.
- */
-wchar_t* (wcscasestr)(const wchar_t* haystack, const wchar_t* needle)
-{
- return (wmemcasemem)(haystack, wcslen(haystack), needle, wcslen(needle));
-}
-
-
-/**
- * Finds the first occurrence of a substring.
- * This search is case sensitive.
- *
- * This is a slibc extension added for because it was useful
- * in implementing slibc itself.
- *
- * @param haystack The string to search.
- * @param needle The sought after substring.
- * @param maxlen The maximum number of character to search.
- * @return Pointer to the first occurrence of the
- * substring, `NULL` if not found.
- */
-wchar_t* (wcsnstr)(const wchar_t* haystack, const wchar_t* needle, size_t maxlen)
-{
- return (wmemmem)(haystack, wcsnlen(haystack, maxlen), needle, wcslen(needle));
-}
-
-
-/**
- * Finds the first occurrence of a substring.
- * This search is case insensitive.
- *
- * This is a slibc extension added for completeness.
- *
- * @param haystack The string to search.
- * @param needle The sought after substring.
- * @param maxlen The maximum number of character to search.
- * @return Pointer to the first occurrence of the
- * substring, `NULL` if not found.
- */
-wchar_t* (wcsncasestr)(const wchar_t* haystack, const wchar_t* needle, size_t maxlen)
-{
- return (wmemcasemem)(haystack, wcsnlen(haystack, maxlen), needle, wcslen(needle));
-}
-
-
-/**
- * Finds the first occurrence of a substring.
- * This search is case sensitive.
- * It must already be known that such a substring exists.
- *
- * This is a slibc extension.
- *
- * @param haystack The string to search.
- * @param needle The sought after substring.
- * @return Pointer to the first occurrence of the substring.
- */
-wchar_t* (rawwcsstr)(const wchar_t* haystack, const wchar_t* needle)
-{
- return (wmemmem)(haystack, SIZE_MAX, needle, wcslen(needle));
-}
-
-
-/**
- * Finds the first occurrence of a substring.
- * This search is case insensitive.
- * It must already be known that such a substring exists.
- *
- * This is a slibc extension.
- *
- * @param haystack The string to search.
- * @param needle The sought after substring.
- * @return Pointer to the first occurrence of the substring.
- */
-wchar_t* (rawwcscasestr)(const wchar_t* haystack, const wchar_t* needle)
-{
- return (wmemcasemem)(haystack, SIZE_MAX, needle, wcslen(needle));
-}
-
-
-/**
- * Finds the first occurrence of a substring.
- * This search is case sensitive.
- *
- * This is a slibc extension added for completeness,
- * and because it was it was useful in implementing
- * slibc itself.
- *
- * @param haystack The string to search.
- * @param haystack_length The number of character to search.
- * @param needle The sought after substring.
- * @param needle_length The length of `needle`.
- * @return Pointer to the first occurrence of
- * the substring, `NULL` if not found.
- */
-wchar_t* (wmemmem)(const wchar_t* haystack, size_t haystack_length,
- const wchar_t* needle, size_t needle_length)
-{
- if (haystack_length < needle_length)
- return NULL;
- if (haystack_length == needle_length)
- return !wmemcmp(haystack, needle, haystack_length) ? haystack : NULL;
-#include "../string/substring.h"
-}
-
-
-/**
- * Finds the first occurrence of a substring.
- * This search is case insensitive.
- *
- * This is a slibc extension added because it was useful
- * in implementing slibc itself.
- *
- * @param haystack The string to search.
- * @param haystack_length The number of character to search.
- * @param needle The sought after substring.
- * @param needle_length The length of `needle`.
- * @return Pointer to the first occurrence of
- * the substring, `NULL` if not found.
- */
-wchar_t* (wmemcasemem)(const wchar_t* haystack, size_t haystack_length,
- const wchar_t* needle, size_t needle_length)
-{
- if (haystack_length < needle_length)
- return NULL;
- if (haystack_length == needle_length)
- return !wmemcasecmp(haystack, needle, haystack_length) ? haystack : NULL;
-#define CASE
-#include "../string/substring.h"
-#undef CASE
-}
-
-
-/**
- * Check whether a string starts with a specific string.
- * This check is case sensitive.
- *
- * This is a slibc extension.
- *
- * @param string The string to inspect.
- * @param desired The desired beginning of the string.
- * @return `string` if `string` begins with
- * `desired`, `NULL` otherwise.
- */
-wchar_t* (wcsstarts)(const wchar_t* string, const wchar_t* desired)
-{
- size_t n = wcslen(string);
- size_t m = wcslen(desired);
- if (n < m)
- return NULL;
- return wmemcmp(string, desired, m) ? NULL : string;
-}
-
-
-/**
- * Check whether a string ends with a specific string.
- * This check is case sensitive.
- *
- * This is a slibc extension.
- *
- * @param string The string to inspect.
- * @param desired The desired ending of the string.
- * @return The `string`, where `desired` beings if
- * `string` ends with `desired`, `NULL` otherwise.
- */
-wchar_t* (wcsends)(const wchar_t* string, const wchar_t* desired)
-{
- size_t n = wcslen(string);
- size_t m = wcslen(desired);
- if (n < m)
- return NULL;
- return wmemcmp(string + (n - m), desired, m) ? NULL : (string + n);
-}
-
-
-/**
- * Check whether a string starts with a specific string.
- * This check is case insensitive.
- *
- * This is a slibc extension.
- *
- * @param string The string to inspect.
- * @param desired The desired beginning of the string.
- * @return `string` if `string` begins with
- * `desired`, `NULL` otherwise.
- */
-wchar_t* (wcscasestarts)(const wchar_t* string, const wchar_t* desired)
-{
- size_t n = wcslen(string);
- size_t m = wcslen(desired);
- if (n < m)
- return NULL;
- return wmemcasecmp(string, desired, m) ? NULL : string;
-}
-
-
-/**
- * Check whether a string ends with a specific string.
- * This check is case insensitive.
- *
- * This is a slibc extension.
- *
- * @param string The string to inspect.
- * @param desired The desired ending of the string.
- * @return The `string`, where `desired` beings if
- * `string` ends with `desired`, `NULL` otherwise.
- */
-wchar_t* (wcscaseends)(const wchar_t* string, const wchar_t* desired)
-{
- size_t n = wcslen(string);
- size_t m = wcslen(desired);
- if (n < m)
- return NULL;
- return wmemcasecmp(string + (n - m), desired, m) ? NULL : (string + n);
-}
-
diff --git a/src/wchar/wcsstrcpy.c b/src/wchar/wcsstrcpy.c
new file mode 100644
index 0000000..1b694b5
--- /dev/null
+++ b/src/wchar/wcsstrcpy.c
@@ -0,0 +1,47 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Copy a memory segment to another, non-overlapping, segment,
+ * stop when a NUL wide character or a specified substring is encountered.
+ *
+ * This is a slibc extension added for completeness.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @param str The substring, ignored if `NULL`.
+ * @return `NULL` if `str` was not encountered, otherwise
+ * the position of `str` translated to `whither`,
+ * that is, the address of `whither` plus the
+ * number of copied characters; the address of
+ * one character passed the last written non-NUL
+ * character.
+ */
+wchar_t* wcsstrcpy(wchar_t* restrict whither, const wchar_t* restrict whence, const wchar_t* restrict str)
+{
+ const wchar_t* stop = str == NULL ? NULL : wcsstr(whence, str);
+ size_t n = stop == NULL ? wcslen(whence) : (size_t)(stop - whence);
+ wchar_t* r = stop == NULL ? NULL : (whither + n);
+ wmemcpy(whither, whence, n);
+ whither[n] = 0;
+ return r;
+}
+
diff --git a/src/wchar/wcsstrmove.c b/src/wchar/wcsstrmove.c
new file mode 100644
index 0000000..9509a05
--- /dev/null
+++ b/src/wchar/wcsstrmove.c
@@ -0,0 +1,47 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Copy a memory segment to another, possibly overlapping, segment,
+ * stop when a NUL wide character or a specified substring is encountered.
+ *
+ * This is a slibc extension added for completeness.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @param str The substring, ignored if `NULL`.
+ * @return `NULL` if `str` was not encountered, otherwise
+ * the position of `str` translated to `whither`,
+ * that is, the address of `whither` plus the
+ * number of copied characters; the address of
+ * one character passed the last written non-NUL
+ * character.
+ */
+wchar_t* wcsstrmove(wchar_t* whither, const wchar_t* whence, const wchar_t* restrict str)
+{
+ const wchar_t* stop = str == NULL ? NULL : wcsstr(whence, str);
+ size_t n = stop == NULL ? wcslen(whence) : (size_t)(stop - whence);
+ wchar_t* r = stop == NULL ? NULL : (whither + n);
+ wmemmove(whither, whence, n);
+ whither[n] = 0;
+ return r;
+}
+
diff --git a/src/wchar/wcsstrncpy.c b/src/wchar/wcsstrncpy.c
new file mode 100644
index 0000000..89dd7f7
--- /dev/null
+++ b/src/wchar/wcsstrncpy.c
@@ -0,0 +1,55 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Copy a memory segment to another, non-overlapping, segment,
+ * stop when a NUL wide character or a specified substring is encountered.
+ *
+ * This is a slibc extension added for completeness.
+ * It is only available if GNU extensions are available.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @param str The substring, ignored if `NULL`.
+ * @param maxlen The maximum number of wide characters to copy.
+ * NOTE that if the resulting string at least this
+ * long, no NUL character will be written to `whither'.
+ * On the otherhand, if the resultnig string is
+ * shorter, `whither` will be filled with NUL characters
+ * until this amount of characters have been written.
+ * @return `NULL` if `str` was not encountered, otherwise
+ * the position of `str` translated to `whither`,
+ * that is, the address of `whither` plus the
+ * number of copied chartacters; the address of
+ * one character passed the last written non-NUL
+ * character.
+ */
+wchar_t* wcsstrncpy(wchar_t* restrict whither, const wchar_t* restrict whence,
+ const wchar_t* restrict str, size_t maxlen)
+{
+ const wchar_t* stop = wcsnstr(whence, str, maxlen);
+ size_t n = stop == NULL ? wcsnlen(whence, maxlen) : (size_t)(stop - whence);
+ wchar_t* r = stop == NULL ? NULL : (whither + n);
+ wmemcpy(whither, whence, n);
+ wmemset(whither, 0, maxlen - n);
+ return r;
+}
+
diff --git a/src/wchar/wcsstrnmove.c b/src/wchar/wcsstrnmove.c
new file mode 100644
index 0000000..f19b4f4
--- /dev/null
+++ b/src/wchar/wcsstrnmove.c
@@ -0,0 +1,54 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Copy a memory segment to another, possibly overlapping, segment,
+ * stop when a NUL wide character or a specified substring is encountered.
+ *
+ * This is a slibc extension added for completeness.
+ * It is only available if GNU extensions are available.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @param str The substring, ignored if `NULL`.
+ * @param maxlen The maximum number of wide characters to copy.
+ * NOTE that if the resulting string at least this
+ * long, no NUL character will be written to `whither'.
+ * On the otherhand, if the resultnig string is
+ * shorter, `whither` will be filled with NUL characters
+ * until this amount of characters have been written.
+ * @return `NULL` if `str` was not encountered, otherwise
+ * the position of `str` translated to `whither`,
+ * that is, the address of `whither` plus the
+ * number of copied chartacters; the address of
+ * one character passed the last written non-NUL
+ * character.
+ */
+wchar_t* wcsstrnmove(wchar_t* whither, const wchar_t* whence, const wchar_t* restrict str, size_t maxlen)
+{
+ const wchar_t* stop = wcsnstr(whence, str, maxlen);
+ size_t n = stop == NULL ? wcsnlen(whence, maxlen) : (size_t)(stop - whence);
+ wchar_t* r = stop == NULL ? NULL : (whither + n);
+ wmemmove(whither, whence, n);
+ wmemset(whither, 0, maxlen - n);
+ return r;
+}
+
diff --git a/src/wchar/wcstok.c b/src/wchar/wcstok.c
index 583defd..dbf0c5f 100644
--- a/src/wchar/wcstok.c
+++ b/src/wchar/wcstok.c
@@ -54,36 +54,3 @@ wchar_t* wcstok(wchar_t* restrict string, const wchar_t* restrict delimiters,
}
}
-
-/**
- * Tokenise a string.
- *
- * This is a slibc extension.
- *
- * @param string Pointer to the string to tokenise on the first call,
- * will be updated to keep track of the state.
- * All characters found in `delimiters` will
- * be overriden with NUL characters.
- * @param delimiters Delimiting characters.
- * @return The next, possibly empty, string that does
- * not contain a byte from `delimiters`. The
- * returned string will be as long as possible.
- * `NULL` is returned the search as reached
- * the end of the string, and there therefore
- * are no more tokens.
- */
-wchar_t* wcssep(wchar_t** restrict string, const wchar_t* restrict delimiters)
-{
- wchar_t* r = *string;
- wchar_t* next;
- if (r == NULL)
- return NULL;
-
- next = wcspbrk(r, delimiters);
- if (next != NULL)
- *next++ = 0;
- *string = next;
-
- return r;
-}
-
diff --git a/src/wchar/wcswcs.c b/src/wchar/wcswcs.c
new file mode 100644
index 0000000..339ec2f
--- /dev/null
+++ b/src/wchar/wcswcs.c
@@ -0,0 +1,29 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * This function is identical to `wcsstr`.
+ */
+wchar_t* (wcswcs)(const wchar_t* haystack, const wchar_t* needle)
+{
+ return (wcsstr)(haystack, needle);
+}
+
diff --git a/src/wchar/wmemcasecmp.c b/src/wchar/wmemcasecmp.c
new file mode 100644
index 0000000..8672bbb
--- /dev/null
+++ b/src/wchar/wmemcasecmp.c
@@ -0,0 +1,45 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+/* TODO #include <wctype.h> */
+
+
+
+/**
+ * Compare two memory segments alphabetically in a case insensitive manner.
+ *
+ * @param a A negative value is returned if this is the lesser.
+ * @param b A positive value is returned if this is the lesser.
+ * @param size The size of the segments.
+ * @return Zero is returned if `a` and `b` are equal, otherwise,
+ * see the specifications for `a` and `b`.
+ */
+int wmemcasecmp(const wchar_t* a, const wchar_t* b, size_t size)
+{
+ wchar_t c1, c2;
+ for (; size--; a++, b++)
+ if (*a != *b)
+ {
+ c1 = iswalpha(*a) ? towlower(*a) : *a;
+ c2 = iswalpha(*b) ? towlower(*b) : *b;
+ if (c1 != c2)
+ return c1 < c2 ? -1 : +1;
+ }
+ return 0;
+}
+
diff --git a/src/wchar/wmemcasemem.c b/src/wchar/wmemcasemem.c
new file mode 100644
index 0000000..824f917
--- /dev/null
+++ b/src/wchar/wmemcasemem.c
@@ -0,0 +1,54 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+#include <unistd.h>
+#include <alloca.h>
+/* TODO #include <wctype.h> */
+
+
+
+# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
+
+
+
+/**
+ * Finds the first occurrence of a substring.
+ * This search is case insensitive.
+ *
+ * This is a slibc extension added because it was useful
+ * in implementing slibc itself.
+ *
+ * @param haystack The string to search.
+ * @param haystack_length The number of character to search.
+ * @param needle The sought after substring.
+ * @param needle_length The length of `needle`.
+ * @return Pointer to the first occurrence of
+ * the substring, `NULL` if not found.
+ */
+wchar_t* (wmemcasemem)(const wchar_t* haystack, size_t haystack_length,
+ const wchar_t* needle, size_t needle_length)
+{
+ if (haystack_length < needle_length)
+ return NULL;
+ if (haystack_length == needle_length)
+ return !wmemcasecmp(haystack, needle, haystack_length) ? haystack : NULL;
+#define WIDE
+#define CASE
+#include "../string/substring.h"
+}
+
diff --git a/src/wchar/wmemccpy.c b/src/wchar/wmemccpy.c
index 498e4db..9e6f684 100644
--- a/src/wchar/wmemccpy.c
+++ b/src/wchar/wmemccpy.c
@@ -45,30 +45,3 @@ wchar_t* wmemccpy(wchar_t* restrict whither, const wchar_t* restrict whence, wch
return r;
}
-
-/**
- * Copy a memory segment to another, possibly overlapping, segment,
- * but stop if a specific byte is encountered.
- *
- * This is a slibc extension added for completeness.
- *
- * @param whither The destination memory segment.
- * @param whence The source memory segment.
- * @param c The character to stop at if encountered.
- * @param size The maximum number of wide characters to copy.
- * @return `NULL` if `c` was not encountered, otherwise
- * the possition of `c` translated to `whither`,
- * that is, the address of `whither` plus the
- * number of copied characters; the address of
- * one character passed the last written character.
- */
-wchar_t* wmemcmove(wchar_t* whither, const wchar_t* whence, wchar_t c, size_t size)
-{
- wchar_t* stop = (wmemchr)(whence, c, size);
- wchar_t* r = NULL;
- if (stop != NULL)
- size = (size_t)(stop - whence), r = whither + size;
- wmemmove(whither, whence, size);
- return r;
-}
-
diff --git a/src/wchar/wmemchr.c b/src/wchar/wmemchr.c
new file mode 100644
index 0000000..9dd3e5f
--- /dev/null
+++ b/src/wchar/wmemchr.c
@@ -0,0 +1,42 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
+
+
+
+/**
+ * Find the first occurrence of a wide character
+ * in a memory segment.
+ *
+ * @param segment The memory segment to search.
+ * @param c The sought after character.
+ * @param size The size of the memory segment.
+ * @return Pointer to the first occurrence of `c`,
+ * `NULL` if none were found.
+ */
+wchar_t* (wmemchr)(const wchar_t* segment, wchar_t c, size_t size)
+{
+ while (size--)
+ if (*segment++ == c)
+ return segment - 1;
+ return NULL;
+}
+
diff --git a/src/wchar/wmemcmove.c b/src/wchar/wmemcmove.c
new file mode 100644
index 0000000..65bf5c5
--- /dev/null
+++ b/src/wchar/wmemcmove.c
@@ -0,0 +1,47 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Copy a memory segment to another, possibly overlapping, segment,
+ * but stop if a specific byte is encountered.
+ *
+ * This is a slibc extension added for completeness.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @param c The character to stop at if encountered.
+ * @param size The maximum number of wide characters to copy.
+ * @return `NULL` if `c` was not encountered, otherwise
+ * the possition of `c` translated to `whither`,
+ * that is, the address of `whither` plus the
+ * number of copied characters; the address of
+ * one character passed the last written character.
+ */
+wchar_t* wmemcmove(wchar_t* whither, const wchar_t* whence, wchar_t c, size_t size)
+{
+ wchar_t* stop = (wmemchr)(whence, c, size);
+ wchar_t* r = NULL;
+ if (stop != NULL)
+ size = (size_t)(stop - whence), r = whither + size;
+ wmemmove(whither, whence, size);
+ return r;
+}
+
diff --git a/src/wchar/wmemcmp.c b/src/wchar/wmemcmp.c
new file mode 100644
index 0000000..9bfe6b3
--- /dev/null
+++ b/src/wchar/wmemcmp.c
@@ -0,0 +1,40 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Compare two memory segments alphabetically in a case sensitive manner.
+ *
+ * @param a A negative value is returned if this is the lesser.
+ * @param b A positive value is returned if this is the lesser.
+ * @param size The size of the segments.
+ * @return Zero is returned if `a` and `b` are equal, otherwise,
+ * see the specifications for `a` and `b`.
+ */
+int wmemcmp(const wchar_t* a, const wchar_t* b, size_t size)
+{
+ while (size--)
+ if (*a == *b)
+ a++, b++;
+ else
+ return *a < *b ? -1 : +1;
+ return 0;
+}
+
diff --git a/src/wchar/wmemcpy.c b/src/wchar/wmemcpy.c
index 5caef28..bcae22a 100644
--- a/src/wchar/wmemcpy.c
+++ b/src/wchar/wmemcpy.c
@@ -35,19 +35,3 @@ wchar_t* wmemcpy(wchar_t* restrict whither, const wchar_t* restrict whence, size
return r;
}
-
-/**
- * Copy a memory segment to another, non-overlapping, segment.
- *
- * This is a GNU extension.
- *
- * @param whither The destination memory segment.
- * @param whence The source memory segment.
- * @param size The number of wide characters to copy.
- * @return `whither + size` is returned.
- */
-wchar_t* wmempcpy(wchar_t* restrict whither, const wchar_t* restrict whence, size_t size)
-{
- return wmemcpy(whither, whence, size) + size;
-}
-
diff --git a/src/wchar/wmemdup.c b/src/wchar/wmemdup.c
new file mode 100644
index 0000000..196009b
--- /dev/null
+++ b/src/wchar/wmemdup.c
@@ -0,0 +1,40 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+#include <stdlib.h>
+
+
+
+/**
+ * Duplicate a memory segment.
+ *
+ * This is a slibc extension added for completeness.
+ *
+ * @param segment The memory segment to duplicate.
+ * @param size The size of the memory segment.
+ * @return The new segment. `NULL` is returned on error
+ * and `errno` is set to indicate the error.
+ *
+ * @throws ENOMEM The process could not allocate sufficient amount of memory.
+ */
+wchar_t* wmemdup(const wchar_t* segment, size_t size)
+{
+ wchar_t* r = malloc(size * sizeof(wchar_t));
+ return r == NULL ? NULL : wmemcpy(r, segment, size);
+}
+
diff --git a/src/wchar/wmemmem.c b/src/wchar/wmemmem.c
new file mode 100644
index 0000000..5c35a06
--- /dev/null
+++ b/src/wchar/wmemmem.c
@@ -0,0 +1,53 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+#include <unistd.h>
+#include <alloca.h>
+
+
+
+# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
+
+
+
+/**
+ * Finds the first occurrence of a substring.
+ * This search is case sensitive.
+ *
+ * This is a slibc extension added for completeness,
+ * and because it was it was useful in implementing
+ * slibc itself.
+ *
+ * @param haystack The string to search.
+ * @param haystack_length The number of character to search.
+ * @param needle The sought after substring.
+ * @param needle_length The length of `needle`.
+ * @return Pointer to the first occurrence of
+ * the substring, `NULL` if not found.
+ */
+wchar_t* (wmemmem)(const wchar_t* haystack, size_t haystack_length,
+ const wchar_t* needle, size_t needle_length)
+{
+ if (haystack_length < needle_length)
+ return NULL;
+ if (haystack_length == needle_length)
+ return !wmemcmp(haystack, needle, haystack_length) ? haystack : NULL;
+#define WIDE
+#include "../string/substring.h"
+}
+
diff --git a/src/wchar/wmemmove.c b/src/wchar/wmemmove.c
index c3cadbc..b531468 100644
--- a/src/wchar/wmemmove.c
+++ b/src/wchar/wmemmove.c
@@ -41,20 +41,3 @@ wchar_t* wmemmove(wchar_t* whither, const wchar_t* whence, size_t size)
return r;
}
-
-/**
- * Copy a memory segment to another, possibly overlapping, segment.
- *
- * This is a slibc extension added for completeness.
- * It is only available if GNU extensions are available.
- *
- * @param whither The destination memory segment.
- * @param whence The source memory segment.
- * @param size The number of wide characters to copy.
- * @return `whither + size` is returned.
- */
-wchar_t* wmempmove(wchar_t* whither, const wchar_t* whence, size_t size)
-{
- return wmemmove(whither, whence, size) + size;
-}
-
diff --git a/src/wchar/wmempcpy.c b/src/wchar/wmempcpy.c
new file mode 100644
index 0000000..0cd419c
--- /dev/null
+++ b/src/wchar/wmempcpy.c
@@ -0,0 +1,36 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Copy a memory segment to another, non-overlapping, segment.
+ *
+ * This is a GNU extension.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @param size The number of wide characters to copy.
+ * @return `whither + size` is returned.
+ */
+wchar_t* wmempcpy(wchar_t* restrict whither, const wchar_t* restrict whence, size_t size)
+{
+ return wmemcpy(whither, whence, size) + size;
+}
+
diff --git a/src/wchar/wmempmove.c b/src/wchar/wmempmove.c
new file mode 100644
index 0000000..2d5ecd4
--- /dev/null
+++ b/src/wchar/wmempmove.c
@@ -0,0 +1,37 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+
+/**
+ * Copy a memory segment to another, possibly overlapping, segment.
+ *
+ * This is a slibc extension added for completeness.
+ * It is only available if GNU extensions are available.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @param size The number of wide characters to copy.
+ * @return `whither + size` is returned.
+ */
+wchar_t* wmempmove(wchar_t* whither, const wchar_t* whence, size_t size)
+{
+ return wmemmove(whither, whence, size) + size;
+}
+
diff --git a/src/wchar/wmemrchr.c b/src/wchar/wmemrchr.c
new file mode 100644
index 0000000..b41e666
--- /dev/null
+++ b/src/wchar/wmemrchr.c
@@ -0,0 +1,48 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <wchar.h>
+
+
+# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
+
+
+
+/**
+ * Find the last occurrence of a wide character in
+ * a memory segment.
+ *
+ * For improved performace, use this function instead
+ * of `wcssrchr` if you already know the length of the
+ * string.
+ *
+ * This is a slibc extension added for completeness.
+ *
+ * @param segment The memory segment to search.
+ * @param c The sought after character.
+ * @param size The size of the memory segment.
+ * @return Pointer to the last occurrence of `c`,
+ * `NULL` if none were found.
+ */
+wchar_t* (wmemrchr)(const wchar_t* segment, wchar_t c, size_t size)
+{
+ while (size--)
+ if (segment[size] == c)
+ return segment + size;
+ return NULL;
+}
+