|
|
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.