aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/string/memcasemem.c55
-rw-r--r--src/string/memchr.c42
-rw-r--r--src/string/memmem.c52
-rw-r--r--src/string/memrchr.c46
-rw-r--r--src/string/rawmemchr.c42
-rw-r--r--src/string/rawstrcasestr.c38
-rw-r--r--src/string/rawstrstr.c37
-rw-r--r--src/string/strcaseends.c41
-rw-r--r--src/string/strcasestarts.c41
-rw-r--r--src/string/strcasestr.c35
-rw-r--r--src/string/strchr.c110
-rw-r--r--src/string/strchrnul.c47
-rw-r--r--src/string/strends.c41
-rw-r--r--src/string/strncasestr.c38
-rw-r--r--src/string/strnstr.c39
-rw-r--r--src/string/strrchr.c48
-rw-r--r--src/string/strstarts.c41
-rw-r--r--src/string/strstr.c233
18 files changed, 683 insertions, 343 deletions
diff --git a/src/string/memcasemem.c b/src/string/memcasemem.c
new file mode 100644
index 0000000..3fb24dc
--- /dev/null
+++ b/src/string/memcasemem.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>
+#include <unistd.h>
+#include <alloca.h>
+#include <ctype.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.
+ */
+void* (memcasemem)(const void* __haystack, size_t haystack_length,
+ const void* __needle, size_t needle_length)
+{
+ const char* haystack = __haystack;
+ const char* needle = __needle;
+ if (haystack_length < needle_length)
+ return NULL;
+ if (haystack_length == needle_length)
+ return !(memcasecmp)(haystack, needle, haystack_length) ? haystack : NULL;
+#define CASE
+#include "substring.h"
+#undef CASE
+}
+
diff --git a/src/string/memchr.c b/src/string/memchr.c
new file mode 100644
index 0000000..380fa0f
--- /dev/null
+++ b/src/string/memchr.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 <string.h>
+
+
+# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
+
+
+
+/**
+ * Find the first occurrence of a byte 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.
+ */
+void* (memchr)(const void* segment, int c, size_t size)
+{
+ char* s = segment;
+ while (size--)
+ if (*s++ == c)
+ return s - 1;
+ return NULL;
+}
+
diff --git a/src/string/memmem.c b/src/string/memmem.c
new file mode 100644
index 0000000..62739d4
--- /dev/null
+++ b/src/string/memmem.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 <string.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 GNU-compliant slibc extension. 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.
+ */
+void* (memmem)(const void* __haystack, size_t haystack_length,
+ const void* __needle, size_t needle_length)
+{
+ const char* haystack = __haystack;
+ const char* needle = __needle;
+ if (haystack_length < needle_length)
+ return NULL;
+ if (haystack_length == needle_length)
+ return !(memcmp)(haystack, needle, haystack_length) ? haystack : NULL;
+#include "substring.h"
+}
+
diff --git a/src/string/memrchr.c b/src/string/memrchr.c
new file mode 100644
index 0000000..7325049
--- /dev/null
+++ b/src/string/memrchr.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 last occurrence of a byte in a memory segment.
+ *
+ * For improved performace, use this function instead
+ * of `strrchr` if you already know the length of the
+ * string.
+ *
+ * @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.
+ */
+void* (memrchr)(const void* segment, int c, size_t size)
+{
+ char* s = segment;
+ while (size--)
+ if (s[size] == c)
+ return s + size;
+ return NULL;
+}
+
diff --git a/src/string/rawmemchr.c b/src/string/rawmemchr.c
new file mode 100644
index 0000000..8f5c03e
--- /dev/null
+++ b/src/string/rawmemchr.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 <string.h>
+
+
+# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
+
+
+
+/**
+ * Find the first occurrence of a byte in a memory segment.
+ * The memory segment must be known to contain the sought after byte.
+ *
+ * This is a GNU-compliant slibc extension.
+ *
+ * @param segment The memory segment to search.
+ * @param c The sought after character.
+ * @return Pointer to the first occurrence of `c`.
+ */
+void* (rawmemchr)(const void* segment, int c)
+{
+ char* s = segment;
+ for (;;)
+ if (*s++ == c)
+ return s - 1;
+}
+
diff --git a/src/string/rawstrcasestr.c b/src/string/rawstrcasestr.c
new file mode 100644
index 0000000..7e4cf9b
--- /dev/null
+++ b/src/string/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/rawstrstr.c b/src/string/rawstrstr.c
new file mode 100644
index 0000000..9c3f186
--- /dev/null
+++ b/src/string/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/strcaseends.c b/src/string/strcaseends.c
new file mode 100644
index 0000000..9155ea8
--- /dev/null
+++ b/src/string/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/strcasestarts.c b/src/string/strcasestarts.c
new file mode 100644
index 0000000..f584da4
--- /dev/null
+++ b/src/string/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/strcasestr.c b/src/string/strcasestr.c
new file mode 100644
index 0000000..6468750
--- /dev/null
+++ b/src/string/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/strchr.c b/src/string/strchr.c
index 06f3ee6..0ed53b4 100644
--- a/src/string/strchr.c
+++ b/src/string/strchr.c
@@ -23,67 +23,6 @@
/**
- * Find the first occurrence of a byte 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.
- */
-void* (memchr)(const void* segment, int c, size_t size)
-{
- char* s = segment;
- while (size--)
- if (*s++ == c)
- return s - 1;
- return NULL;
-}
-
-
-/**
- * Find the first occurrence of a byte in a memory segment.
- * The memory segment must be known to contain the sought after byte.
- *
- * This is a GNU-compliant slibc extension.
- *
- * @param segment The memory segment to search.
- * @param c The sought after character.
- * @return Pointer to the first occurrence of `c`.
- */
-void* (rawmemchr)(const void* segment, int c)
-{
- char* s = segment;
- for (;;)
- if (*s++ == c)
- return s - 1;
-}
-
-
-/**
- * Find the last occurrence of a byte in a memory segment.
- *
- * For improved performace, use this function instead
- * of `strrchr` if you already know the length of the
- * string.
- *
- * @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.
- */
-void* (memrchr)(const void* segment, int c, size_t size)
-{
- char* s = segment;
- while (size--)
- if (s[size] == c)
- return s + size;
- return NULL;
-}
-
-
-/**
* Find the first occurrence of a byte in a string.
*
* `s = strchr(s, 0)` is a faster alternative to
@@ -105,52 +44,3 @@ char* (strchr)(const char* string, int c)
return NULL;
}
-
-/**
- * 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;
-}
-
-
-/**
- * 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/strchrnul.c b/src/string/strchrnul.c
new file mode 100644
index 0000000..50dedfe
--- /dev/null
+++ b/src/string/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/strends.c b/src/string/strends.c
new file mode 100644
index 0000000..957301c
--- /dev/null
+++ b/src/string/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/strncasestr.c b/src/string/strncasestr.c
new file mode 100644
index 0000000..e95dc4b
--- /dev/null
+++ b/src/string/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/strnstr.c b/src/string/strnstr.c
new file mode 100644
index 0000000..8db61ac
--- /dev/null
+++ b/src/string/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/strrchr.c b/src/string/strrchr.c
new file mode 100644
index 0000000..716a442
--- /dev/null
+++ b/src/string/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/strstarts.c b/src/string/strstarts.c
new file mode 100644
index 0000000..e132b68
--- /dev/null
+++ b/src/string/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/strstr.c b/src/string/strstr.c
index f396570..dadbc73 100644
--- a/src/string/strstr.c
+++ b/src/string/strstr.c
@@ -16,13 +16,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <alloca.h>
-#include <ctype.h>
-
-
-# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
@@ -42,229 +35,3 @@ char* (strstr)(const char* haystack, const char* needle)
return (memmem)(haystack, strlen(haystack), needle, strlen(needle));
}
-
-/**
- * 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));
-}
-
-
-/**
- * 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));
-}
-
-
-/**
- * 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));
-}
-
-
-/**
- * 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));
-}
-
-
-/**
- * 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));
-}
-
-
-/**
- * Finds the first occurrence of a substring.
- * This search is case sensitive.
- *
- * This is a GNU-compliant slibc extension. 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.
- */
-void* (memmem)(const void* __haystack, size_t haystack_length,
- const void* __needle, size_t needle_length)
-{
- const char* haystack = __haystack;
- const char* needle = __needle;
- if (haystack_length < needle_length)
- return NULL;
- if (haystack_length == needle_length)
- return !(memcmp)(haystack, needle, haystack_length) ? haystack : NULL;
-#include "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.
- */
-void* (memcasemem)(const void* __haystack, size_t haystack_length,
- const void* __needle, size_t needle_length)
-{
- const char* haystack = __haystack;
- const char* needle = __needle;
- if (haystack_length < needle_length)
- return NULL;
- if (haystack_length == needle_length)
- return !(memcasecmp)(haystack, needle, haystack_length) ? haystack : NULL;
-#define CASE
-#include "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.
- */
-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;
-}
-
-
-/**
- * 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);
-}
-
-
-/**
- * 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;
-}
-
-
-/**
- * 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);
-}
-