]> git.ipfire.org Git - thirdparty/gnulib.git/commitdiff
strnul: New module.
authorBruno Haible <bruno@clisp.org>
Sat, 21 Feb 2026 09:26:13 +0000 (10:26 +0100)
committerBruno Haible <bruno@clisp.org>
Sat, 21 Feb 2026 09:26:13 +0000 (10:26 +0100)
Suggested by Alejandro Colomar <alx@kernel.org> in
<https://lists.gnu.org/archive/html/bug-gnulib/2026-02/msg00121.html>.

* lib/string.in.h (gl_strnul): New function.
(strnul): New macro or template.
* lib/string.c: Update comment.
* m4/string_h.m4 (gl_STRING_H_REQUIRE_DEFAULTS): Initialize
GNULIB_STRNUL.
* modules/string-h (Makefile.am): Substitute GNULIB_STRNUL.
* modules/strnul: New file.

ChangeLog
lib/string.c
lib/string.in.h
m4/string_h.m4
modules/string-h
modules/strnul [new file with mode: 0644]

index 43929ca5a2251c7461cbd8bdba574b49639b512c..749d269dc1ac3d5af3d5d2925ba39f9837d0f107 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2026-02-21  Bruno Haible  <bruno@clisp.org>
+
+       strnul: New module.
+       Suggested by Alejandro Colomar <alx@kernel.org> in
+       <https://lists.gnu.org/archive/html/bug-gnulib/2026-02/msg00121.html>.
+       * lib/string.in.h (gl_strnul): New function.
+       (strnul): New macro or template.
+       * lib/string.c: Update comment.
+       * m4/string_h.m4 (gl_STRING_H_REQUIRE_DEFAULTS): Initialize
+       GNULIB_STRNUL.
+       * modules/string-h (Makefile.am): Substitute GNULIB_STRNUL.
+       * modules/strnul: New file.
+
 2026-02-21  Bruno Haible  <bruno@clisp.org>
 
        streq: Rename to streq-opt.
index c2e1b1f41840ae3af1b6aa2dd734811ce5b59abf..b8f079aa78fedbffa145bbdf134c06da3a277fe5 100644 (file)
@@ -1,4 +1,4 @@
-/* streq and memeq functions.
+/* streq, memeq, gl_strnul functions.
    Copyright (C) 2025-2026 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
index 1b391507f4947a5085da5054b56142ecc5d91701..599203c44db9e18c387a3b17847c62d6d18b88a8 100644 (file)
@@ -1230,6 +1230,58 @@ _GL_WARN_ON_USE (strtok_r, "strtok_r is unportable - "
 /* The following functions are not specified by POSIX.  They are gnulib
    extensions.  */
 
+#if @GNULIB_STRNUL@
+/* Returns a pointer to the terminating NUL byte of STRING.
+     strnul (string)
+   This is a type-generic macro:
+   If STRING is a 'const char *', the result is 'const char *'.
+   If STRING is a 'char *', the result is 'char *'.
+   It is equivalent to
+     string + strlen (string)
+   or to
+     strchr (string, '\0').  */
+# ifdef __cplusplus
+extern "C" {
+# endif
+_GL_STRING_INLINE const char *gl_strnul (const char *string)
+     _GL_ATTRIBUTE_PURE
+     _GL_ARG_NONNULL ((1));
+_GL_STRING_INLINE const char *gl_strnul (const char *string)
+{
+  /* In gcc >= 7 or clang >= 4, we could use the expression
+       strchr (string, '\0')
+     because these compiler versions produce identical code for both
+     expressions.  But this optimization in not available in older
+     compiler versions, and is also not available when the compiler
+     option '-fno-builtin' is in use.  */
+  return string + strlen (string);
+}
+# ifdef __cplusplus
+}
+# endif
+# ifdef __cplusplus
+template <typename T> T strnul (T);
+template <> inline const char *strnul<const char *> (const char *s)
+{ return gl_strnul (s); }
+template <> inline       char *strnul<      char *> (      char *s)
+{ return const_cast<char *>(gl_strnul (s)); }
+# else
+#  if (defined __GNUC__ && __GNUC__ + (__GNUC_MINOR__ >= 9) > 4 && !defined __cplusplus) \
+      || (defined __clang__ && __clang_major__ >= 3) \
+      || (defined __SUNPRO_C && __SUNPRO_C >= 0x5150) \
+      || (__STDC_VERSION__ >= 201112L && !defined __GNUC__)
+/* The compiler supports _Generic from ISO C11.  */
+#   define strnul(s) \
+      _Generic (s, \
+                char *       : (char *) gl_strnul (s), \
+                const char * : gl_strnul (s))
+#  else
+#   define strnul(s) \
+      ((char *) gl_strnul (s))
+#  endif
+# endif
+#endif
+
 #if @GNULIB_STR_STARTSWITH@
 /* Returns true if STRING starts with PREFIX.
    Returns false otherwise.  */
index 2a6e4db46ddb474465864e2a3c0ca14520de8942..93a5d354cf9684750313ac928d033d3464067b8a 100644 (file)
@@ -1,5 +1,5 @@
 # string_h.m4
-# serial 46
+# serial 47
 dnl Copyright (C) 2007-2026 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -73,6 +73,7 @@ AC_DEFUN([gl_STRING_H_REQUIRE_DEFAULTS],
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRSTR])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCASESTR])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOK_R])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNUL])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STR_STARTSWITH])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STR_ENDSWITH])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSLEN])
index 3e69040ea49cb874182417c9bb5a4c8c26caa483..68ed79b4620b1afaa202938e2c7dc4e59b4459ab 100644 (file)
@@ -68,6 +68,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
              -e 's/@''GNULIB_STRNCPY''@/$(GNULIB_STRNCPY)/g' \
              -e 's/@''GNULIB_STRNDUP''@/$(GNULIB_STRNDUP)/g' \
              -e 's/@''GNULIB_STRNLEN''@/$(GNULIB_STRNLEN)/g' \
+             -e 's/@''GNULIB_STRNUL''@/$(GNULIB_STRNUL)/g' \
              -e 's/@''GNULIB_STRPBRK''@/$(GNULIB_STRPBRK)/g' \
              -e 's/@''GNULIB_STRSEP''@/$(GNULIB_STRSEP)/g' \
              -e 's/@''GNULIB_STRSTR''@/$(GNULIB_STRSTR)/g' \
diff --git a/modules/strnul b/modules/strnul
new file mode 100644 (file)
index 0000000..52d6729
--- /dev/null
@@ -0,0 +1,23 @@
+Description:
+strnul() function: return pointer to terminating NUL byte.
+
+Files:
+lib/string.c
+
+Depends-on:
+string-h
+
+configure.ac:
+gl_STRING_MODULE_INDICATOR([strnul])
+
+Makefile.am:
+lib_SOURCES += string.c
+
+Include:
+<string.h>
+
+License:
+LGPLv2+
+
+Maintainer:
+all