diff options
-rw-r--r-- | src/string/memcasemem.c | 55 | ||||
-rw-r--r-- | src/string/memchr.c | 42 | ||||
-rw-r--r-- | src/string/memmem.c | 52 | ||||
-rw-r--r-- | src/string/memrchr.c | 46 | ||||
-rw-r--r-- | src/string/rawmemchr.c | 42 | ||||
-rw-r--r-- | src/string/rawstrcasestr.c | 38 | ||||
-rw-r--r-- | src/string/rawstrstr.c | 37 | ||||
-rw-r--r-- | src/string/strcaseends.c | 41 | ||||
-rw-r--r-- | src/string/strcasestarts.c | 41 | ||||
-rw-r--r-- | src/string/strcasestr.c | 35 | ||||
-rw-r--r-- | src/string/strchr.c | 110 | ||||
-rw-r--r-- | src/string/strchrnul.c | 47 | ||||
-rw-r--r-- | src/string/strends.c | 41 | ||||
-rw-r--r-- | src/string/strncasestr.c | 38 | ||||
-rw-r--r-- | src/string/strnstr.c | 39 | ||||
-rw-r--r-- | src/string/strrchr.c | 48 | ||||
-rw-r--r-- | src/string/strstarts.c | 41 | ||||
-rw-r--r-- | src/string/strstr.c | 233 |
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); -} - |