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