aboutsummaryrefslogtreecommitdiffstats
path: root/src/string/str
diff options
context:
space:
mode:
Diffstat (limited to 'src/string/str')
-rw-r--r--src/string/str/rawstrcasestr.c38
-rw-r--r--src/string/str/rawstrstr.c37
-rw-r--r--src/string/str/stpcpy.c34
-rw-r--r--src/string/str/stpmove.c37
-rw-r--r--src/string/str/stpncpy.c46
-rw-r--r--src/string/str/stpnmove.c47
-rw-r--r--src/string/str/strcasecmp.c37
-rw-r--r--src/string/str/strcaseends.c41
-rw-r--r--src/string/str/strcasestarts.c41
-rw-r--r--src/string/str/strcasestr.c35
-rw-r--r--src/string/str/strcat.c37
-rw-r--r--src/string/str/strccpy.c45
-rw-r--r--src/string/str/strchr.c46
-rw-r--r--src/string/str/strchrnul.c47
-rw-r--r--src/string/str/strcmove.c45
-rw-r--r--src/string/str/strcmp.c36
-rw-r--r--src/string/str/strcncpy.c54
-rw-r--r--src/string/str/strcnmove.c54
-rw-r--r--src/string/str/strcpy.c34
-rw-r--r--src/string/str/strcspn.c44
-rw-r--r--src/string/str/strdup.c38
-rw-r--r--src/string/str/strends.c41
-rw-r--r--src/string/str/strlen.c35
-rw-r--r--src/string/str/strmove.c36
-rw-r--r--src/string/str/strncasecmp.c50
-rw-r--r--src/string/str/strncasestr.c38
-rw-r--r--src/string/str/strncat.c43
-rw-r--r--src/string/str/strncmp.c39
-rw-r--r--src/string/str/strncpy.c43
-rw-r--r--src/string/str/strndup.c43
-rw-r--r--src/string/str/strnlen.c36
-rw-r--r--src/string/str/strnmove.c43
-rw-r--r--src/string/str/strnstr.c39
-rw-r--r--src/string/str/strpbrk.c47
-rw-r--r--src/string/str/strrchr.c48
-rw-r--r--src/string/str/strsep.c51
-rw-r--r--src/string/str/strset.c39
-rw-r--r--src/string/str/strspn.c44
-rw-r--r--src/string/str/strstarts.c41
-rw-r--r--src/string/str/strstr.c37
-rw-r--r--src/string/str/strstrcpy.c47
-rw-r--r--src/string/str/strstrmove.c47
-rw-r--r--src/string/str/strstrncpy.c55
-rw-r--r--src/string/str/strstrnmove.c54
-rw-r--r--src/string/str/strtok.c44
-rw-r--r--src/string/str/strtok_r.c56
46 files changed, 1969 insertions, 0 deletions
diff --git a/src/string/str/rawstrcasestr.c b/src/string/str/rawstrcasestr.c
new file mode 100644
index 0000000..7e4cf9b
--- /dev/null
+++ b/src/string/str/rawstrcasestr.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 <string.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.
+ */
+char* (rawstrcasestr)(const char* haystack, const char* needle)
+{
+ return (memcasemem)(haystack, SIZE_MAX, needle, strlen(needle));
+}
+
diff --git a/src/string/str/rawstrstr.c b/src/string/str/rawstrstr.c
new file mode 100644
index 0000000..9c3f186
--- /dev/null
+++ b/src/string/str/rawstrstr.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 <string.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.
+ */
+char* (rawstrstr)(const char* haystack, const char* needle)
+{
+ return (memmem)(haystack, SIZE_MAX, needle, strlen(needle));
+}
+
diff --git a/src/string/str/stpcpy.c b/src/string/str/stpcpy.c
new file mode 100644
index 0000000..a0d5f79
--- /dev/null
+++ b/src/string/str/stpcpy.c
@@ -0,0 +1,34 @@
+/**
+ * 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 <string.h>
+
+
+
+/**
+ * Copy a memory segment to another, non-overlapping, segment,
+ * stop when a NUL byte is encountered.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @return `whither + strlen(whence)` is returned.
+ */
+char* stpcpy(char* restrict whither, const char* restrict whence)
+{
+ return mempcpy(whither, whence, strlen(whence) + 1) - 1;
+}
+
diff --git a/src/string/str/stpmove.c b/src/string/str/stpmove.c
new file mode 100644
index 0000000..8818c30
--- /dev/null
+++ b/src/string/str/stpmove.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 <string.h>
+
+
+
+/**
+ * Copy a memory segment to another, possibly overlapping, segment,
+ * stop when a NUL byte is encountered.
+ *
+ * This is a slibc extension added for completeness.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @return `whither + strlen(whence)` is returned.
+ */
+char* stpmove(char* whither, const char* whence)
+{
+ return mempmove(whither, whence, strlen(whence) + 1) - 1;
+}
+
+
diff --git a/src/string/str/stpncpy.c b/src/string/str/stpncpy.c
new file mode 100644
index 0000000..876eaf0
--- /dev/null
+++ b/src/string/str/stpncpy.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 <string.h>
+
+
+
+/**
+ * Copy a memory segment to another, non-overlapping, segment,
+ * stop when a NUL byte 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 bytes to copy.
+ * NOTE that if the resulting string at least this
+ * long, no NUL byte will be written to `whither'.
+ * On the otherhand, if the resultnig string is
+ * shorter, `whither` will be filled with NUL bytes
+ * until this amount of bytes have been written.
+ * @return `whither` plus the number of written bytes,
+ * excluding NUL bytes, is returned.
+ */
+char* stpncpy(char* restrict whither, const char* restrict whence, size_t maxlen)
+{
+ size_t n = strnlen(whence, maxlen);
+ memcpy(whither, whence, n);
+ memset(whither, 0, maxlen - n);
+ return whither + n;
+}
+
diff --git a/src/string/str/stpnmove.c b/src/string/str/stpnmove.c
new file mode 100644
index 0000000..a0a0de9
--- /dev/null
+++ b/src/string/str/stpnmove.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 <string.h>
+
+
+
+/**
+ * Copy a memory segment to another, possibly overlapping, segment,
+ * stop when a NUL byte 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 bytes to copy.
+ * NOTE that if the resulting string at least this
+ * long, no NUL byte will be written to `whither'.
+ * On the otherhand, if the resultnig string is
+ * shorter, `whither` will be filled with NUL bytes
+ * until this amount of bytes have been written.
+ * @return `whither` plus the number of written bytes,
+ * excluding NUL bytes, is returned.
+ */
+char* stpnmove(char* whither, const char* whence, size_t maxlen)
+{
+ size_t n = strnlen(whence, maxlen);
+ memmove(whither, whence, n);
+ memset(whither, 0, maxlen - n);
+ return whither + n;
+}
+
diff --git a/src/string/str/strcasecmp.c b/src/string/str/strcasecmp.c
new file mode 100644
index 0000000..eb02084
--- /dev/null
+++ b/src/string/str/strcasecmp.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 <string.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.
+ *
+ * @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 strcasecmp(const char* a, const char* b)
+{
+ return strncasecmp(a, b, SIZE_MAX);
+}
+
diff --git a/src/string/str/strcaseends.c b/src/string/str/strcaseends.c
new file mode 100644
index 0000000..9155ea8
--- /dev/null
+++ b/src/string/str/strcaseends.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 <string.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.
+ */
+char* (strcaseends)(const char* string, const char* desired)
+{
+ size_t n = strlen(string);
+ size_t m = strlen(desired);
+ if (n < m)
+ return NULL;
+ return (memcasecmp)(string + (n - m), desired, m) ? NULL : (string + n);
+}
+
diff --git a/src/string/str/strcasestarts.c b/src/string/str/strcasestarts.c
new file mode 100644
index 0000000..f584da4
--- /dev/null
+++ b/src/string/str/strcasestarts.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 <string.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.
+ */
+char* (strcasestarts)(const char* string, const char* desired)
+{
+ size_t n = strlen(string);
+ size_t m = strlen(desired);
+ if (n < m)
+ return NULL;
+ return (memcasecmp)(string, desired, m) ? NULL : string;
+}
+
diff --git a/src/string/str/strcasestr.c b/src/string/str/strcasestr.c
new file mode 100644
index 0000000..6468750
--- /dev/null
+++ b/src/string/str/strcasestr.c
@@ -0,0 +1,35 @@
+/**
+ * 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 <string.h>
+
+
+
+/**
+ * Finds the first occurrence of a substring.
+ * This search is case insensitive.
+ *
+ * @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.
+ */
+char* (strcasestr)(const char* haystack, const char* needle)
+{
+ return (memcasemem)(haystack, strlen(haystack), needle, strlen(needle));
+}
+
diff --git a/src/string/str/strcat.c b/src/string/str/strcat.c
new file mode 100644
index 0000000..de5c63e
--- /dev/null
+++ b/src/string/str/strcat.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 <string.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 bad idea.
+ *
+ * @param whither The string to extend.
+ * @param whence The string to append.
+ * @return `whither` is returned.
+ */
+char* strcat(char* restrict whither, const char* restrict whence)
+{
+ strcpy(whither + strlen(whither), whence);
+ return whither;
+}
+
diff --git a/src/string/str/strccpy.c b/src/string/str/strccpy.c
new file mode 100644
index 0000000..2d1bcd8
--- /dev/null
+++ b/src/string/str/strccpy.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 <string.h>
+
+
+
+/**
+ * Copy a memory segment to another, non-overlapping, segment,
+ * stop when a NUL byte or a specified 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 stop byte.
+ * @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.
+ */
+char* strccpy(char* restrict whither, const char* restrict whence, int c)
+{
+ char* r = memccpy(whither, whence, c, strlen(whence) + 1);
+ if (r)
+ *r = 0;
+ return r;
+}
+
diff --git a/src/string/str/strchr.c b/src/string/str/strchr.c
new file mode 100644
index 0000000..0ed53b4
--- /dev/null
+++ b/src/string/str/strchr.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 <string.h>
+
+
+# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
+
+
+
+/**
+ * Find the first occurrence of a byte in a string.
+ *
+ * `s = strchr(s, 0)` is a faster alternative to
+ * `s = s + strlen(s)`.
+ *
+ * @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`,
+ * `NULL` if none were found.
+ */
+char* (strchr)(const char* string, int c)
+{
+ for (;;)
+ if (*string == c)
+ return string;
+ else if (!*string++)
+ return NULL;
+}
+
diff --git a/src/string/str/strchrnul.c b/src/string/str/strchrnul.c
new file mode 100644
index 0000000..50dedfe
--- /dev/null
+++ b/src/string/str/strchrnul.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 <string.h>
+
+
+# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
+
+
+
+/**
+ * Find the first occurrence of a byte in a string, or
+ * if there is no such byte, 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.
+ */
+char* (strchrnul)(const char* string, int c)
+{
+ for (;; string++)
+ if (*string == c)
+ return string;
+ else if (!*string)
+ return string;
+}
+
diff --git a/src/string/str/strcmove.c b/src/string/str/strcmove.c
new file mode 100644
index 0000000..8310b27
--- /dev/null
+++ b/src/string/str/strcmove.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 <string.h>
+
+
+
+/**
+ * Copy a memory segment to another, possibly overlapping, segment,
+ * stop when a NUL byte or a specified 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 stop byte.
+ * @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.
+ */
+char* strcmove(char* whither, const char* whence, int c)
+{
+ char* r = memcmove(whither, whence, c, strlen(whence) + 1);
+ if (r)
+ *r = 0;
+ return r;
+}
+
diff --git a/src/string/str/strcmp.c b/src/string/str/strcmp.c
new file mode 100644
index 0000000..3099d71
--- /dev/null
+++ b/src/string/str/strcmp.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 <string.h>
+
+
+
+/**
+ * Compare two strings 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.
+ * @return Zero is returned if `a` and `b` are equal, otherwise,
+ * see the specifications for `a` and `b`.
+ */
+int strcmp(const char* a, const char* b)
+{
+ size_t n = strlen(a);
+ size_t m = strlen(b);
+ return memcmp(a, b, (n < m ? n : m) + 1);
+}
+
diff --git a/src/string/str/strcncpy.c b/src/string/str/strcncpy.c
new file mode 100644
index 0000000..5036c7d
--- /dev/null
+++ b/src/string/str/strcncpy.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 <string.h>
+
+
+
+/**
+ * Copy a memory segment to another, non-overlapping, segment,
+ * stop when a NUL byte or a specified byte 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 byte.
+ * @param maxlen The maximum number of bytes to copy.
+ * NOTE that if the resulting string at least this
+ * long, no NUL byte will be written to `whither'.
+ * On the otherhand, if the resultnig string is
+ * shorter, `whither` will be filled with NUL bytes
+ * until this amount of bytes 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.
+ */
+char* strcncpy(char* restrict whither, const char* restrict whence, int c, size_t maxlen)
+{
+ const char* stop = memchr(whence, c, maxlen);
+ size_t n = stop == NULL ? strnlen(whence, maxlen) : (size_t)(stop - whence);
+ char* r = stop == NULL ? NULL : (whither + n);
+ memcpy(whither, whence, n);
+ memset(whither, 0, maxlen - n);
+ return r;
+}
+
diff --git a/src/string/str/strcnmove.c b/src/string/str/strcnmove.c
new file mode 100644
index 0000000..f418e92
--- /dev/null
+++ b/src/string/str/strcnmove.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 <string.h>
+
+
+
+/**
+ * Copy a memory segment to another, possibly overlapping, segment,
+ * stop when a NUL byte or a specified byte 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 byte.
+ * @param maxlen The maximum number of bytes to copy.
+ * NOTE that if the resulting string at least this
+ * long, no NUL byte will be written to `whither'.
+ * On the otherhand, if the resultnig string is
+ * shorter, `whither` will be filled with NUL bytes
+ * until this amount of bytes 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.
+ */
+char* strcnmove(char* whither, const char* whence, int c, size_t maxlen)
+{
+ const char* stop = memchr(whence, c, maxlen);
+ size_t n = stop == NULL ? strnlen(whence, maxlen) : (size_t)(stop - whence);
+ char* r = stop == NULL ? NULL : (whither + n);
+ memmove(whither, whence, n);
+ memset(whither, 0, maxlen - n);
+ return r;
+}
+
diff --git a/src/string/str/strcpy.c b/src/string/str/strcpy.c
new file mode 100644
index 0000000..75d88e7
--- /dev/null
+++ b/src/string/str/strcpy.c
@@ -0,0 +1,34 @@
+/**
+ * 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 <string.h>
+
+
+
+/**
+ * Copy a memory segment to another, non-overlapping, segment,
+ * stop when a NUL byte is encountered.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @return `whither` is returned.
+ */
+char* strcpy(char* restrict whither, const char* restrict whence)
+{
+ return memcpy(whither, whence, strlen(whence) + 1);
+}
+
diff --git a/src/string/str/strcspn.c b/src/string/str/strcspn.c
new file mode 100644
index 0000000..35b3404
--- /dev/null
+++ b/src/string/str/strcspn.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 <string.h>
+
+
+
+/**
+ * Returns length of the initial substring
+ * that consists entirely of the complement
+ * of a set of specified bytes.
+ *
+ * @param string The string.
+ * @param stopset Bytes disallowed in the substring.
+ * @return The length of the substring.
+ */
+size_t strcspn(const char* string, const char* stopset)
+{
+ char set[256];
+ char c;
+ const char* s = string;
+ memset(set, 0, 256);
+ while ((c = *stopset++))
+ set[(size_t)c] = 1;
+ while ((c = *s++))
+ if (!set[(size_t)c])
+ break;
+ return (size_t)(s - 1 - string);
+}
+
diff --git a/src/string/str/strdup.c b/src/string/str/strdup.c
new file mode 100644
index 0000000..b7155d7
--- /dev/null
+++ b/src/string/str/strdup.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 <string.h>
+#include <stdlib.h>
+
+
+
+/**
+ * Duplicate a string.
+ *
+ * @param string The string to duplicate.
+ * @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.
+ */
+char* strdup(const char* string)
+{
+ size_t n = strlen(string) + 1;
+ char* r = malloc(n * sizeof(char));
+ return r == NULL ? NULL : memcpy(r, string, n * sizeof(char));
+}
+
diff --git a/src/string/str/strends.c b/src/string/str/strends.c
new file mode 100644
index 0000000..957301c
--- /dev/null
+++ b/src/string/str/strends.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 <string.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.
+ */
+char* (strends)(const char* string, const char* desired)
+{
+ size_t n = strlen(string);
+ size_t m = strlen(desired);
+ if (n < m)
+ return NULL;
+ return (memcmp)(string + (n - m), desired, m) ? NULL : (string + n);
+}
+
diff --git a/src/string/str/strlen.c b/src/string/str/strlen.c
new file mode 100644
index 0000000..2092ddc
--- /dev/null
+++ b/src/string/str/strlen.c
@@ -0,0 +1,35 @@
+/**
+ * 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 <string.h>
+
+
+
+/**
+ * Returns the number of bytes in a NUL-terminated
+ * string. This excludes the NUL byte.
+ *
+ * @param str The string.
+ * @return The number of bytes before the first NUL byte.
+ */
+size_t strlen(const char* str)
+{
+ const char* s = str;
+ while (*str++);
+ return (size_t)(s - 1 - str);
+}
+
diff --git a/src/string/str/strmove.c b/src/string/str/strmove.c
new file mode 100644
index 0000000..4bd52f4
--- /dev/null
+++ b/src/string/str/strmove.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 <string.h>
+
+
+
+/**
+ * Copy a memory segment to another, possibly overlapping, segment,
+ * stop when a NUL byte is encountered.
+ *
+ * This is a slibc extension added for completeness.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @return `whither` is returned.
+ */
+char* strmove(char* whither, const char* whence)
+{
+ return memmove(whither, whence, strlen(whence) + 1);
+}
+
diff --git a/src/string/str/strncasecmp.c b/src/string/str/strncasecmp.c
new file mode 100644
index 0000000..919ff36
--- /dev/null
+++ b/src/string/str/strncasecmp.c
@@ -0,0 +1,50 @@
+/**
+ * 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 <string.h>
+#include <ctype.h>
+
+
+
+/**
+ * Compare two strings alphabetically in a case insensitive manner.
+ * Be aware, only ASCII characters are case insensitive, non-ASCII
+ * characters are case sensitive.
+ *
+ * @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 strncasecmp(const char* a, const char* b, size_t length)
+{
+ int c1, c2;
+ for (; length--; a++, b++)
+ if (*a != *b)
+ {
+ c1 = isalpha(*a) ? tolower(*a) : (int)*a;
+ c2 = isalpha(*b) ? tolower(*b) : (int)*b;
+ if ((c1 -= c2))
+ return c1;
+ }
+ else if (!*a && !*b) return 0;
+ else if (!*a) return -1;
+ else if (!*b) return +1;
+ return 0;
+}
+
diff --git a/src/string/str/strncasestr.c b/src/string/str/strncasestr.c
new file mode 100644
index 0000000..e95dc4b
--- /dev/null
+++ b/src/string/str/strncasestr.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 <string.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.
+ */
+char* (strncasestr)(const char* haystack, const char* needle, size_t maxlen)
+{
+ return (memcasemem)(haystack, strnlen(haystack, maxlen), needle, strlen(needle));
+}
+
diff --git a/src/string/str/strncat.c b/src/string/str/strncat.c
new file mode 100644
index 0000000..e7db0f2
--- /dev/null
+++ b/src/string/str/strncat.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 <string.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 bytes to copy.
+ * NOTE that if the resulting string at least this
+ * long, no NUL byte will be written to `whither'.
+ * On the otherhand, if the resultnig string is
+ * shorter, `whither` will be filled with NUL bytes
+ * until this amount of bytes have been written.
+ * @return `whither` is returned.
+ */
+char* strncat(char* restrict whither, const char* restrict whence, size_t maxlen)
+{
+ strncpy(whither + strlen(whither), whence, maxlen);
+ return whither;
+}
+
diff --git a/src/string/str/strncmp.c b/src/string/str/strncmp.c
new file mode 100644
index 0000000..daf5be5
--- /dev/null
+++ b/src/string/str/strncmp.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 <string.h>
+
+
+
+/**
+ * Compare two strings 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 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 strncmp(const char* a, const char* b, size_t length)
+{
+ size_t n = strnlen(a, length);
+ size_t m = strnlen(b, length);
+ int r = memcmp(a, b, (n < m ? n : m));
+ return r ? r : n == m ? 0 : n < m ? -1 : +1;
+}
+
+
diff --git a/src/string/str/strncpy.c b/src/string/str/strncpy.c
new file mode 100644
index 0000000..f3eba84
--- /dev/null
+++ b/src/string/str/strncpy.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 <string.h>
+
+
+
+/**
+ * Copy a memory segment to another, non-overlapping, segment,
+ * stop when a NUL byte is encountered.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @param maxlen The maximum number of bytes to copy.
+ * NOTE that if the resulting string at least this
+ * long, no NUL byte will be written to `whither'.
+ * On the otherhand, if the resultnig string is
+ * shorter, `whither` will be filled with NUL bytes
+ * until this amount of bytes have been written.
+ * @return `whither` is returned.
+ */
+char* strncpy(char* restrict whither, const char* restrict whence, size_t maxlen)
+{
+ size_t n = strnlen(whence, maxlen);
+ memcpy(whither, whence, n);
+ memset(whither, 0, maxlen - n);
+ return whither;
+}
+
diff --git a/src/string/str/strndup.c b/src/string/str/strndup.c
new file mode 100644
index 0000000..ca3b3f0
--- /dev/null
+++ b/src/string/str/strndup.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 <string.h>
+#include <stdlib.h>
+
+
+
+/**
+ * Duplicate a string.
+ *
+ * This is a GNU extension.
+ *
+ * @param string The string to duplicate.
+ * @param maxlen Truncate the string to this length, if it is longer.
+ * A NUL byte 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.
+ */
+char* strndup(const char* string, size_t maxlen)
+{
+ size_t n = strnlen(string, maxlen) + 1;
+ char* r = malloc(n * sizeof(char));
+ return r == NULL ? NULL : memcpy(r, string, n * sizeof(char));
+}
+
diff --git a/src/string/str/strnlen.c b/src/string/str/strnlen.c
new file mode 100644
index 0000000..5473682
--- /dev/null
+++ b/src/string/str/strnlen.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 <string.h>
+
+
+
+/**
+ * Variant of `strlen` that only inspects the
+ * beginning of a string.
+ *
+ * @param str The string.
+ * @param maxlen The number of bytes to inspect, at most.
+ * @return The number of bytes before, the first NUL byte.
+ * `maxlen` if no NUL byte was found.
+ */
+size_t strnlen(const char* str, size_t maxlen)
+{
+ const char* end = memchr(str, 0, maxlen);
+ return end == NULL ? maxlen : (size_t)(end - str);
+}
+
diff --git a/src/string/str/strnmove.c b/src/string/str/strnmove.c
new file mode 100644
index 0000000..a7ec028
--- /dev/null
+++ b/src/string/str/strnmove.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 <string.h>
+
+
+
+/**
+ * Copy a memory segment to another, possibly overlapping, segment,
+ * stop when a NUL byte is encountered.
+ *
+ * @param whither The destination memory segment.
+ * @param whence The source memory segment.
+ * @param maxlen The maximum number of bytes to copy.
+ * NOTE that if the resulting string at least this
+ * long, no NUL byte will be written to `whither'.
+ * On the otherhand, if the resultnig string is
+ * shorter, `whither` will be filled with NUL bytes
+ * until this amount of bytes have been written.
+ * @return `whither` is returned.
+ */
+char* strnmove(char* whither, const char* whence, size_t maxlen)
+{
+ size_t n = strnlen(whence, maxlen);
+ memmove(whither, whence, n);
+ memset(whither, 0, maxlen - n);
+ return whither;
+}
+
diff --git a/src/string/str/strnstr.c b/src/string/str/strnstr.c
new file mode 100644
index 0000000..8db61ac
--- /dev/null
+++ b/src/string/str/strnstr.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 <string.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.
+ */
+char* (strnstr)(const char* haystack, const char* needle, size_t maxlen)
+{
+ return (memmem)(haystack, strnlen(haystack, maxlen), needle, strlen(needle));
+}
+
diff --git a/src/string/str/strpbrk.c b/src/string/str/strpbrk.c
new file mode 100644
index 0000000..8499d31
--- /dev/null
+++ b/src/string/str/strpbrk.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 <string.h>
+
+
+
+/**
+ * This function works like `strcspn`,
+ * except it returns the pointer to the
+ * location of the first found non-matching
+ * byte.
+ *
+ * @param string The string.
+ * @param stopset Bytes disallowed in the substring.
+ * @return A pointer to the first occurrence in
+ * `string` of a byte found in `stopset`.
+ * `NULL` is returned if none is found.
+ */
+char* (strpbrk)(const char* string, const char* stopset)
+{
+ char set[256];
+ char c;
+ const char* s = string;
+ memset(set, 0, 256);
+ while ((c = *stopset++))
+ set[(size_t)c] = 1;
+ while ((c = *s++))
+ if (!set[(size_t)c])
+ break;
+ return c ? (s - 1) : NULL;
+}
+
diff --git a/src/string/str/strrchr.c b/src/string/str/strrchr.c
new file mode 100644
index 0000000..716a442
--- /dev/null
+++ b/src/string/str/strrchr.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 <string.h>
+
+
+# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
+
+
+
+/**
+ * Find the last occurrence of a byte in a string.
+ *
+ * For improved performace, use `memrchr` 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.
+ */
+char* (strrchr)(const char* string, int c)
+{
+ char* r = NULL;
+ for (;;)
+ if (*string == c)
+ r = string;
+ else if (!*string++)
+ return c ? r : (string - 1);
+}
+
diff --git a/src/string/str/strsep.c b/src/string/str/strsep.c
new file mode 100644
index 0000000..9fa0cff
--- /dev/null
+++ b/src/string/str/strsep.c
@@ -0,0 +1,51 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <string.h>
+
+
+
+/**
+ * Tokenise a string.
+ *
+ * @param string Pointer to the string to tokenise on the first call,
+ * will be updated to keep track of the state.
+ * All bytes found in `delimiters` will
+ * be overriden with NUL bytes.
+ * @param delimiters Delimiting bytes (not 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.
+ */
+char* strsep(char** restrict string, const char* restrict delimiters)
+{
+ char* r = *string;
+ char* next;
+ if (r == NULL)
+ return NULL;
+
+ next = strpbrk(r, delimiters);
+ if (next != NULL)
+ *next++ = 0;
+ *string = next;
+
+ return r;
+}
+
diff --git a/src/string/str/strset.c b/src/string/str/strset.c
new file mode 100644
index 0000000..c1eca65
--- /dev/null
+++ b/src/string/str/strset.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 <string.h>
+
+
+
+/**
+ * Override a NUL byte-terminated memory segment
+ * with a repeated character.
+ *
+ * This is a slibc extension.
+ *
+ * @param str The beginning of the memory segment.
+ * @param c The character (8 bits wide.)
+ * @return `str` is returned.
+ */
+char* strset(char* str, int c)
+{
+ char* s = segment;
+ while (*s)
+ *s++ = (char)c;
+ return segment;
+}
+
diff --git a/src/string/str/strspn.c b/src/string/str/strspn.c
new file mode 100644
index 0000000..1b2e034
--- /dev/null
+++ b/src/string/str/strspn.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 <string.h>
+
+
+
+/**
+ * Returns length of the initial substring
+ * that consists entirely of a set of specified
+ * bytes.
+ *
+ * @param string The string.
+ * @param skipset Bytes allowed in the substring.
+ * @return The length of the substring.
+ */
+size_t strspn(const char* string, const char* skipset)
+{
+ char set[256];
+ char c;
+ const char* s = string;
+ memset(set, 0, 256);
+ while ((c = *skipset++))
+ set[(size_t)c] = 1;
+ while ((c = *s++))
+ if (set[(size_t)c])
+ break;
+ return (size_t)(s - 1 - string);
+}
+
diff --git a/src/string/str/strstarts.c b/src/string/str/strstarts.c
new file mode 100644
index 0000000..e132b68
--- /dev/null
+++ b/src/string/str/strstarts.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 <string.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.
+ */
+char* (strstarts)(const char* string, const char* desired)
+{
+ size_t n = strlen(string);
+ size_t m = strlen(desired);
+ if (n < m)
+ return NULL;
+ return (memcmp)(string, desired, m) ? NULL : string;
+}
+
diff --git a/src/string/str/strstr.c b/src/string/str/strstr.c
new file mode 100644
index 0000000..dadbc73
--- /dev/null
+++ b/src/string/str/strstr.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 <string.h>
+
+
+
+/**
+ * Finds the first occurrence of a substring.
+ * This search is case sensitive.
+ *
+ * @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.
+ */
+char* (strstr)(const char* haystack, const char* needle)
+{
+ if (*needle && !(needle[1]))
+ return (strchr)(haystack, *needle);
+ return (memmem)(haystack, strlen(haystack), needle, strlen(needle));
+}
+
diff --git a/src/string/str/strstrcpy.c b/src/string/str/strstrcpy.c
new file mode 100644
index 0000000..9dc9105
--- /dev/null
+++ b/src/string/str/strstrcpy.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 <string.h>
+
+
+
+/**
+ * Copy a memory segment to another, non-overlapping, segment,
+ * stop when a NUL byte 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.
+ */
+char* strstrcpy(char* restrict whither, const char* restrict whence, const char* restrict str)
+{
+ const char* stop = str == NULL ? NULL : strstr(whence, str);
+ size_t n = stop == NULL ? strlen(whence) : (size_t)(stop - whence);
+ char* r = stop == NULL ? NULL : (whither + n);
+ memcpy(whither, whence, n);
+ whither[n] = 0;
+ return r;
+}
+
diff --git a/src/string/str/strstrmove.c b/src/string/str/strstrmove.c
new file mode 100644
index 0000000..19969cd
--- /dev/null
+++ b/src/string/str/strstrmove.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 <string.h>
+
+
+
+/**
+ * Copy a memory segment to another, possibly overlapping, segment,
+ * stop when a NUL byte 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.
+ */
+char* strstrmove(char* whither, const char* whence, const char* restrict str)
+{
+ const char* stop = str == NULL ? NULL : strstr(whence, str);
+ size_t n = stop == NULL ? strlen(whence) : (size_t)(stop - whence);
+ char* r = stop == NULL ? NULL : (whither + n);
+ memmove(whither, whence, n);
+ whither[n] = 0;
+ return r;
+}
+
diff --git a/src/string/str/strstrncpy.c b/src/string/str/strstrncpy.c
new file mode 100644
index 0000000..0beb8ec
--- /dev/null
+++ b/src/string/str/strstrncpy.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 <string.h>
+
+
+
+/**
+ * Copy a memory segment to another, non-overlapping, segment,
+ * stop when a NUL byte 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`.
+ * NOTE that if the resulting string at least this
+ * long, no NUL byte will be written to `whither'.
+ * On the otherhand, if the resultnig string is
+ * shorter, `whither` will be filled with NUL bytes
+ * until this amount of bytes have been written.
+ * @param maxlen The maximum number of bytes to copy.
+ * @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.
+ */
+char* strstrncpy(char* restrict whither, const char* restrict whence,
+ const char* restrict str, size_t maxlen)
+{
+ const char* stop = strnstr(whence, str, maxlen);
+ size_t n = stop == NULL ? strnlen(whence, maxlen) : (size_t)(stop - whence);
+ char* r = stop == NULL ? NULL : (whither + n);
+ memcpy(whither, whence, n);
+ memset(whither, 0, maxlen - n);
+ return r;
+}
+
diff --git a/src/string/str/strstrnmove.c b/src/string/str/strstrnmove.c
new file mode 100644
index 0000000..9bec614
--- /dev/null
+++ b/src/string/str/strstrnmove.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 <string.h>
+
+
+
+/**
+ * Copy a memory segment to another, possibly overlapping, segment,
+ * stop when a NUL byte 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`.
+ * NOTE that if the resulting string at least this
+ * long, no NUL byte will be written to `whither'.
+ * On the otherhand, if the resultnig string is
+ * shorter, `whither` will be filled with NUL bytes
+ * until this amount of bytes have been written.
+ * @param maxlen The maximum number of bytes to copy.
+ * @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.
+ */
+char* strstrnmove(char* whither, const char* whence, const char* restrict str, size_t maxlen)
+{
+ const char* stop = strnstr(whence, str, maxlen);
+ size_t n = stop == NULL ? strnlen(whence, maxlen) : (size_t)(stop - whence);
+ char* r = stop == NULL ? NULL : (whither + n);
+ memmove(whither, whence, n);
+ memset(whither, 0, maxlen - n);
+ return r;
+}
+
diff --git a/src/string/str/strtok.c b/src/string/str/strtok.c
new file mode 100644
index 0000000..b1b56b9
--- /dev/null
+++ b/src/string/str/strtok.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 <string.h>
+
+
+
+/**
+ * Tokenise a string.
+ *
+ * @param string The string to tokenise on the first,
+ * `NULL` on subsequent calls.
+ * All bytes found in `delimiters` will
+ * be overriden with NUL bytes.
+ * @param delimiters Delimiting bytes (not characters).
+ * @return The next non-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.
+ */
+char* strtok(char* restrict string, const char* restrict delimiters)
+{
+ static char* state = NULL;
+ if (string == NULL)
+ state = NULL;
+ return strtok_r(string, delimiters, &state);
+}
+
diff --git a/src/string/str/strtok_r.c b/src/string/str/strtok_r.c
new file mode 100644
index 0000000..3005ac7
--- /dev/null
+++ b/src/string/str/strtok_r.c
@@ -0,0 +1,56 @@
+/**
+ * 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 <string.h>
+
+
+
+/**
+ * Tokenise a string.
+ *
+ * @param string The string to tokenise on the first,
+ * `NULL` on subsequent calls.
+ * All bytes found in `delimiters` will
+ * be overriden with NUL bytes.
+ * @param delimiters Delimiting bytes (not characters).
+ * @param state Pointer to a `char*` that the function
+ * can use to keep track of its state.
+ * It is reasonable to make it point to `NULL`
+ * on the first call.
+ * @return The next non-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.
+ */
+char* strtok_r(char* restrict string, const char* restrict delimiters,
+ char** restrict state)
+{
+ char* r;
+ if (string == NULL)
+ *state = string;
+ for (;;)
+ {
+ r = strsep(state, delimiters);
+ if (r == NULL)
+ return NULL;
+ if (*r)
+ return r;
+ }
+}
+