|
Message-Id: <c166b0a43bfeb6f50b341d752ba0230d42eb08ab.1684932942.git.Jens.Gustedt@inria.fr> Date: Thu, 25 May 2023 16:45:00 +0200 From: Jens Gustedt <Jens.Gustedt@...ia.fr> To: musl@...ts.openwall.com Subject: [C23 const 2/2] C23: change string.h and wchar.h interfaces to macros that respects the const contract This adds a macro interfaces to those string functions that search for a string position. This has an additional cast of the return value to `void const*` for the case that the argument to the call was also const-qualified. Nothing changes for the correspondin function itself, only the identifier has to be protected with (), such that the macro does not expand for the function declaration or definition. --- include/string.h | 54 ++++++++++++++++++++++++++++++++++++++----- include/wchar.h | 55 +++++++++++++++++++++++++++++++++++++++----- src/include/string.h | 6 +++++ src/include/wchar.h | 6 +++++ src/string/memchr.c | 2 +- src/string/strchr.c | 2 +- src/string/strpbrk.c | 2 +- src/string/strrchr.c | 2 +- src/string/strstr.c | 2 +- src/string/wcschr.c | 2 +- src/string/wcspbrk.c | 2 +- src/string/wcsrchr.c | 2 +- src/string/wcsstr.c | 2 +- src/string/wmemchr.c | 2 +- 14 files changed, 119 insertions(+), 22 deletions(-) diff --git a/include/string.h b/include/string.h index 7df7a402..05019c03 100644 --- a/include/string.h +++ b/include/string.h @@ -28,7 +28,54 @@ void *memcpy (void *__restrict, const void *__restrict, size_t); void *memmove (void *, const void *, size_t); void *memset (void *, int, size_t); int memcmp (const void *, const void *, size_t); -void *memchr (const void *, int, size_t); + +void *(memchr) (const void *, int, size_t); +char *(strchr) (const char *, int); +char *(strrchr) (const char *, int); +char *(strpbrk) (const char *, const char *); +char *(strstr) (const char *, const char *); +#if __STDC_VERSION__ > 201112L +# define memchr(S, C, N) \ + _Generic( \ + /* ensure conversion to a void pointer */ \ + 1 ? (S) : (void*)1, \ + void const*: (void const*)memchr((void const*)(S), (C), (N)), \ + /* volatile qualification of *S is an error for this call */ \ + default: memchr((S), (C), (N)) \ +) +# define strchr(S, C) \ + _Generic( \ + /* ensure conversion to a void pointer */ \ + 1 ? (S) : (void*)1, \ + void const*: (char const*)strchr((char const*){ (S) }, (C)), \ + /* volatile qualification of *S is an error for this call */ \ + default: strchr((S), (C)) \ +) +# define strrchr(S, C) \ + _Generic( \ + /* ensure conversion to a void pointer */ \ + 1 ? (S) : (void*)1, \ + void const*: (char const*)strrchr((char const*){ (S) }, (C)), \ + /* volatile qualification of *S is an error for this call */ \ + default: strrchr((S), (C)) \ +) +# define strpbrk(S, A) \ + _Generic( \ + /* ensure conversion to a void pointer */ \ + 1 ? (S) : (void*)1, \ + void const*: (char const*)strpbrk((char const*){ (S) }, (A)), \ + /* volatile qualification of *S is an error for this call */ \ + default: strpbrk((S), (A)) \ +) +# define strstr(H, N) \ + _Generic( \ + /* ensure conversion to a void pointer */ \ + 1 ? (H) : (void*)1, \ + void const*: (char const*)strstr((char const*){ (H) }, (N)), \ + /* volatile qualification of *S is an error for this call */ \ + default: strstr((H), (N)) \ +) +#endif char *strcpy (char *__restrict, const char *__restrict); char *strncpy (char *__restrict, const char *__restrict, size_t); @@ -42,13 +89,8 @@ int strncmp (const char *, const char *, size_t); int strcoll (const char *, const char *); size_t strxfrm (char *__restrict, const char *__restrict, size_t); -char *strchr (const char *, int); -char *strrchr (const char *, int); - size_t strcspn (const char *, const char *); size_t strspn (const char *, const char *); -char *strpbrk (const char *, const char *); -char *strstr (const char *, const char *); char *strtok (char *__restrict, const char *__restrict); size_t strlen (const char *); diff --git a/include/wchar.h b/include/wchar.h index ed5d774d..3816a7cd 100644 --- a/include/wchar.h +++ b/include/wchar.h @@ -61,21 +61,64 @@ int wcsncmp (const wchar_t *, const wchar_t *, size_t); int wcscoll(const wchar_t *, const wchar_t *); size_t wcsxfrm (wchar_t *__restrict, const wchar_t *__restrict, size_t); -wchar_t *wcschr (const wchar_t *, wchar_t); -wchar_t *wcsrchr (const wchar_t *, wchar_t); - size_t wcscspn (const wchar_t *, const wchar_t *); size_t wcsspn (const wchar_t *, const wchar_t *); -wchar_t *wcspbrk (const wchar_t *, const wchar_t *); wchar_t *wcstok (wchar_t *__restrict, const wchar_t *__restrict, wchar_t **__restrict); size_t wcslen (const wchar_t *); -wchar_t *wcsstr (const wchar_t *__restrict, const wchar_t *__restrict); wchar_t *wcswcs (const wchar_t *, const wchar_t *); -wchar_t *wmemchr (const wchar_t *, wchar_t, size_t); +wchar_t *(wmemchr) (const wchar_t *, wchar_t, size_t); +wchar_t *(wcschr) (const wchar_t *, wchar_t); +wchar_t *(wcsrchr) (const wchar_t *, wchar_t); +wchar_t *(wcspbrk) (const wchar_t *, const wchar_t *); +wchar_t *(wcsstr) (const wchar_t *__restrict, const wchar_t *__restrict); +#if __STDC_VERSION__ > 201112L +# define wmemchr(S, C, N) \ + _Generic( \ + /* ensure conversion to a void pointer */ \ + 1 ? (S) : (void*)1, \ + void const*: (wchar_t const*)wmemchr((wchar_t const*){ (S) }, (C), (N)), \ + /* volatile qualification of *S is an error for this call */ \ + default: wmemchr((S), (C), (N)) \ +) +# define wcschr(S, C) \ + _Generic( \ + /* ensure conversion to a void pointer */ \ + 1 ? (S) : (void*)1, \ + void const*: (wchar_t const*)wcschr((wchar_t const*){ (S) }, (C)), \ + /* volatile qualification of *S is an error for this call */ \ + default: wcschr((S), (C)) \ +) +# define wcsrchr(S, C) \ + _Generic( \ + /* ensure conversion to a void pointer */ \ + 1 ? (S) : (void*)1, \ + void const*: (wchar_t const*)wcsrchr((wchar_t const*){ (S) }, (C)), \ + /* volatile qualification of *S is an error for this call */ \ + default: wcsrchr((S), (C)) \ +) +# define wcspbrk(S, A) \ + _Generic( \ + /* ensure conversion to a void pointer */ \ + 1 ? (S) : (void*)1, \ + void const*: (wchar_t const*)wcspbrk((wchar_t const*){ (S) }, (A)), \ + /* volatile qualification of *S is an error for this call */ \ + default: wcspbrk((S), (A)) \ +) +# define wcsstr(H, N) \ + _Generic( \ + /* ensure conversion to a void pointer */ \ + 1 ? (H) : (void*)1, \ + void const*: (wchar_t const*)wcsstr((wchar_t const*){ (H) }, (N)), \ + /* volatile qualification of *S is an error for this call */ \ + default: wcsstr((H), (N)) \ +) +#endif + + int wmemcmp (const wchar_t *, const wchar_t *, size_t); wchar_t *wmemcpy (wchar_t *__restrict, const wchar_t *__restrict, size_t); wchar_t *wmemmove (wchar_t *, const wchar_t *, size_t); diff --git a/src/include/string.h b/src/include/string.h index 2133b5c1..f536c26b 100644 --- a/src/include/string.h +++ b/src/include/string.h @@ -8,4 +8,10 @@ hidden char *__stpcpy(char *, const char *); hidden char *__stpncpy(char *, const char *, size_t); hidden char *__strchrnul(const char *, int); +#undef memchr +#undef strchr +#undef strrchr +#undef strpbrk +#undef strstr + #endif diff --git a/src/include/wchar.h b/src/include/wchar.h index 79f5d0e7..dcd1cce1 100644 --- a/src/include/wchar.h +++ b/src/include/wchar.h @@ -5,5 +5,11 @@ #include "../../include/wchar.h" +#undef wmemchr +#undef wcschr +#undef wcsrchr +#undef wcspbrk +#undef wcsstr + #endif diff --git a/src/string/memchr.c b/src/string/memchr.c index 65f0d789..f11c0573 100644 --- a/src/string/memchr.c +++ b/src/string/memchr.c @@ -8,7 +8,7 @@ #define HIGHS (ONES * (UCHAR_MAX/2+1)) #define HASZERO(x) ((x)-ONES & ~(x) & HIGHS) -void *memchr(const void *src, int c, size_t n) +void *(memchr)(const void *src, int c, size_t n) { const unsigned char *s = src; c = (unsigned char)c; diff --git a/src/string/strchr.c b/src/string/strchr.c index 3cbc828b..3a86beeb 100644 --- a/src/string/strchr.c +++ b/src/string/strchr.c @@ -1,6 +1,6 @@ #include <string.h> -char *strchr(const char *s, int c) +char *(strchr)(const char *s, int c) { char *r = __strchrnul(s, c); return *(unsigned char *)r == (unsigned char)c ? r : 0; diff --git a/src/string/strpbrk.c b/src/string/strpbrk.c index 55947c64..0941fc51 100644 --- a/src/string/strpbrk.c +++ b/src/string/strpbrk.c @@ -1,6 +1,6 @@ #include <string.h> -char *strpbrk(const char *s, const char *b) +char *(strpbrk)(const char *s, const char *b) { s += strcspn(s, b); return *s ? (char *)s : 0; diff --git a/src/string/strrchr.c b/src/string/strrchr.c index 98ad1b04..908fd8d4 100644 --- a/src/string/strrchr.c +++ b/src/string/strrchr.c @@ -1,6 +1,6 @@ #include <string.h> -char *strrchr(const char *s, int c) +char *(strrchr)(const char *s, int c) { return __memrchr(s, c, strlen(s) + 1); } diff --git a/src/string/strstr.c b/src/string/strstr.c index 96657bc2..5c622a82 100644 --- a/src/string/strstr.c +++ b/src/string/strstr.c @@ -135,7 +135,7 @@ static char *twoway_strstr(const unsigned char *h, const unsigned char *n) } } -char *strstr(const char *h, const char *n) +char *(strstr)(const char *h, const char *n) { /* Return immediately on empty needle */ if (!n[0]) return (char *)h; diff --git a/src/string/wcschr.c b/src/string/wcschr.c index 8dfc2f31..2bf7a111 100644 --- a/src/string/wcschr.c +++ b/src/string/wcschr.c @@ -1,6 +1,6 @@ #include <wchar.h> -wchar_t *wcschr(const wchar_t *s, wchar_t c) +wchar_t *(wcschr)(const wchar_t *s, wchar_t c) { if (!c) return (wchar_t *)s + wcslen(s); for (; *s && *s != c; s++); diff --git a/src/string/wcspbrk.c b/src/string/wcspbrk.c index 0c72c197..eb76b5ff 100644 --- a/src/string/wcspbrk.c +++ b/src/string/wcspbrk.c @@ -1,6 +1,6 @@ #include <wchar.h> -wchar_t *wcspbrk(const wchar_t *s, const wchar_t *b) +wchar_t *(wcspbrk)(const wchar_t *s, const wchar_t *b) { s += wcscspn(s, b); return *s ? (wchar_t *)s : NULL; diff --git a/src/string/wcsrchr.c b/src/string/wcsrchr.c index 8961b9e2..889303f3 100644 --- a/src/string/wcsrchr.c +++ b/src/string/wcsrchr.c @@ -1,6 +1,6 @@ #include <wchar.h> -wchar_t *wcsrchr(const wchar_t *s, wchar_t c) +wchar_t *(wcsrchr)(const wchar_t *s, wchar_t c) { const wchar_t *p; for (p=s+wcslen(s); p>=s && *p!=c; p--); diff --git a/src/string/wcsstr.c b/src/string/wcsstr.c index 4caaef3c..8f27dbea 100644 --- a/src/string/wcsstr.c +++ b/src/string/wcsstr.c @@ -90,7 +90,7 @@ static wchar_t *twoway_wcsstr(const wchar_t *h, const wchar_t *n) } } -wchar_t *wcsstr(const wchar_t *restrict h, const wchar_t *restrict n) +wchar_t *(wcsstr)(const wchar_t *restrict h, const wchar_t *restrict n) { /* Return immediately on empty needle or haystack */ if (!n[0]) return (wchar_t *)h; diff --git a/src/string/wmemchr.c b/src/string/wmemchr.c index 2bc2c270..3d761488 100644 --- a/src/string/wmemchr.c +++ b/src/string/wmemchr.c @@ -1,6 +1,6 @@ #include <wchar.h> -wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n) +wchar_t *(wmemchr)(const wchar_t *s, wchar_t c, size_t n) { for (; n && *s != c; n--, s++); return n ? (wchar_t *)s : 0; -- 2.34.1
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.