* lib/add-one.c: new file, factoring decimal_absval_add_one () out of
find/getrlimits.c.
* lib/add-one.h: new file, declarations for add_one.c.
* find/getlimits.c: remove the factored-out function.
* lib/test-add-one.c: new file, test for decimal_absval_add_one ().
* lib/Makefile.am (check_PROGRAMS): add test-add-one.
(TESTS): add test-add-one.
(libfind_a_SOURCES): add test-add-one.[ch].
---
 find/getlimits.c   | 89 ++++++++--------------------------------------
 lib/Makefile.am    |  7 ++--
 lib/add-one.c      | 48 +++++++++++++++++++++++++
 lib/add-one.h      | 22 ++++++++++++
 lib/test-add-one.c | 65 +++++++++++++++++++++++++++++++++
 5 files changed, 154 insertions(+), 77 deletions(-)
 create mode 100644 lib/add-one.c
 create mode 100644 lib/add-one.h
 create mode 100644 lib/test-add-one.c

diff --git a/find/getlimits.c b/find/getlimits.c
index b8a74010..39920aee 100644
--- a/find/getlimits.c
+++ b/find/getlimits.c
@@ -17,12 +17,21 @@
 /* Based on 'getlimits' of GNU coreutils, written by Pádraig Brady.
  * Stripped down to a minimal version by Bernhard Voelker.  */
 
+/* Always include config.h first. */
 #include <config.h>             /* sets _FILE_OFFSET_BITS=64 etc. */
+
+/* system headers */
 #include <stdio.h>
 #include <sys/types.h>
 #include <stdlib.h>
 #include <stdint.h>
 
+/* gnulib headers */
+#include "intprops.h"
+#include "inttostr.h"
+
+/* findutils headers */
+#include "add-one.h"
 #include "system.h"
 #include "intprops.h"
 
@@ -34,86 +43,16 @@
 # define GID_T_MAX TYPE_MAXIMUM (gid_t)
 #endif
 
-#ifndef MIN
-# define MIN(a,b) (a<b?a:b)
-#endif
-
-/* Silence GCC 14.  */
-#if 14 <= __GNUC__
-# pragma GCC diagnostic ignored "-Wanalyzer-out-of-bounds"
-#endif
-
-/* Add one to the absolute value of the number whose textual
-   representation is BUF + 1.  Do this in-place, in the buffer.
-   Return a pointer to the result, which is normally BUF + 1, but is
-   BUF if the representation grew in size.  */
-static char const *
-decimal_absval_add_one (char *buf)
-{
-  bool negative = (buf[1] == '-');
-  char *absnum = buf + 1 + negative;
-  char *p = absnum + strlen (absnum);
-  absnum[-1] = '0';
-  while (*--p == '9')
-    *p = '0';
-  ++*p;
-  char *result = MIN (absnum, p);
-  if (negative)
-    *--result = '-';
-  return result;
-}
-
-
-static void
-check_add_one (const char *input, const char *expected)
-{
-  char buf[100];
-  buf[0] = ' ';
-  strcpy (&buf[1], input);
-  const char *result = decimal_absval_add_one (buf);
-  if (0 != strcmp (result, expected))
-    {
-      fprintf (stderr,
-               "check_add_one: wrong output for [%s]; expected [%s], got 
[%s]\n",
-               input, expected, result);
-      exit (EXIT_FAILURE);
-    }
-}
-
-static void
-self_test (void)
-{
-  check_add_one ("0", "1");
-  check_add_one ("1", "2");
-  check_add_one ("9", "10");
-  check_add_one ("10", "11");
-  check_add_one ("94", "95");
-  check_add_one ("199", "200");
-  check_add_one ("999", "1000");
-  check_add_one ("499999999999999999999999999999999",
-                 "500000000000000000000000000000000");
-
-  check_add_one ("-1", "-2");
-  check_add_one ("-9", "-10");
-  check_add_one ("-10", "-11");
-  check_add_one ("-94", "-95");
-  check_add_one ("-199", "-200");
-  check_add_one ("-999", "-1000");
-  check_add_one ("-499999999999999999999999999999999",
-                 "-500000000000000000000000000000000");
-}
-
 int
 main (int argc, char **argv)
 {
-  char limit[100];
-
-  self_test ();
+  char *printable;
+  char limit[1 + INT_BUFSIZE_BOUND (uintmax_t)];
 
 #define print_int(TYPE)                                      \
-  sprintf (limit + 1, "%" "ju", (uintmax_t) TYPE##_MAX);     \
-  printf (#TYPE"_MAX=%s\n", limit + 1);                      \
-  printf (#TYPE"_OFLOW=%s\n", decimal_absval_add_one (limit))
+  printable = umaxtostr((uintmax_t) TYPE##_MAX, limit+1);    \
+  printf (#TYPE"_MAX=%s\n", printable);                      \
+  printf (#TYPE"_OFLOW=%s\n", decimal_absval_add_one (printable-1))
 
   print_int (INT);
   print_int (UID_T);
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 2a6aec61..71572a1d 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -24,7 +24,7 @@ AM_CFLAGS = $(WARN_CFLAGS)
 
 noinst_LIBRARIES = libfind.a
 
-check_PROGRAMS = regexprops test_splitstring
+check_PROGRAMS = regexprops test_splitstring test-add-one
 check_SCRIPTS = check-regexprops
 regexprops_SOURCES = regexprops.c regextype.c
 
@@ -35,10 +35,12 @@ if CROSS_COMPILING
 # The regexprops program needs to be a native executable, so we
 # can't build it with a cross-compiler.
 else
-TESTS += check-regexprops test_splitstring
+TESTS += check-regexprops test_splitstring test-add-one
 endif
 
 libfind_a_SOURCES = \
+       add-one.c \
+       add-one.h \
        buildcmd.c \
        buildcmd.h \
        dircallback.c \
@@ -89,3 +91,4 @@ check-regexprops: check-regexprops.sh
        chmod +x check-regexprops
 
 test_splitstring_SOURCES = test_splitstring.c splitstring.c
+test_add_one_SOURCES = test-add-one.c
diff --git a/lib/add-one.c b/lib/add-one.c
new file mode 100644
index 00000000..ad2a9c72
--- /dev/null
+++ b/lib/add-one.c
@@ -0,0 +1,48 @@
+/* getlimits - print various platform dependent limits.
+   Copyright (C) 2023-2026 Free Software Foundation, Inc.
+
+   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 <https://www.gnu.org/licenses/>.  */
+
+/* Based on 'getlimits' of GNU coreutils, written by Pádraig Brady.
+ * Stripped down to a minimal version by Bernhard Voelker.  */
+
+#include <config.h>
+
+#include <string.h>
+
+#include "add-one.h"
+
+#ifndef MIN
+# define MIN(a,b) (a<b?a:b)
+#endif
+
+/* Add one to the absolute value of the number whose textual
+   representation is BUF + 1.  Do this in-place, in the buffer.
+   Return a pointer to the result, which is normally BUF + 1, but is
+   BUF if the representation grew in size.  */
+char const *
+decimal_absval_add_one (char *buf)
+{
+  bool negative = (buf[1] == '-');
+  char *absnum = buf + 1 + negative;
+  char *p = absnum + strlen (absnum);
+  absnum[-1] = '0';
+  while (*--p == '9')
+    *p = '0';
+  ++*p;
+  char *result = MIN (absnum, p);
+  if (negative)
+    *--result = '-';
+  return result;
+}
diff --git a/lib/add-one.h b/lib/add-one.h
new file mode 100644
index 00000000..ef0351b8
--- /dev/null
+++ b/lib/add-one.h
@@ -0,0 +1,22 @@
+/* getlimits - print various platform dependent limits.
+   Copyright (C) 2023-2026 Free Software Foundation, Inc.
+
+   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 <https://www.gnu.org/licenses/>.  */
+
+#ifndef INC_ADD_ONE_H
+# define INC_ADD_ONE_H 1
+
+char const *decimal_absval_add_one (char *buf);
+
+#endif
diff --git a/lib/test-add-one.c b/lib/test-add-one.c
new file mode 100644
index 00000000..de19d51c
--- /dev/null
+++ b/lib/test-add-one.c
@@ -0,0 +1,65 @@
+/* test_add_one - tests for add_one.c
+   Copyright (C) 2026 Free Software Foundation, Inc.
+
+   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 <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+
+#include <stdlib.h>             /* EXIT_FAILURE, exit */
+#include <stdio.h>              /* fprintf */
+#include <string.h>             /* strcpy, strcmp */
+
+#include "add-one.h"
+
+static void
+check_add_one (const char *input, const char *expected)
+{
+  char buf[100];
+  buf[0] = ' ';
+  strcpy (&buf[1], input);
+  const char *result = decimal_absval_add_one (buf);
+  if (0 != strcmp (result, expected))
+    {
+      fprintf (stderr,
+               "check_add_one: wrong output for [%s]; expected [%s], got 
[%s]\n",
+               input, expected, result);
+      exit (EXIT_FAILURE);
+    }
+}
+
+int
+main (int argc, char *argv[])
+{
+  check_add_one ("0", "1");
+  check_add_one ("1", "2");
+  check_add_one ("9", "10");
+  check_add_one ("10", "11");
+  check_add_one ("94", "95");
+  check_add_one ("199", "200");
+  check_add_one ("999", "1000");
+  check_add_one ("499999999999999999999999999999999",
+                 "500000000000000000000000000000000");
+
+  check_add_one ("-1", "-2");
+  check_add_one ("-9", "-10");
+  check_add_one ("-10", "-11");
+  check_add_one ("-94", "-95");
+  check_add_one ("-199", "-200");
+  check_add_one ("-999", "-1000");
+  check_add_one ("-499999999999999999999999999999999",
+                 "-500000000000000000000000000000000");
+
+  return EXIT_SUCCESS;
+}
-- 
2.47.3


Reply via email to