* 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