inttostr: add a new function, inttostr, and tests
authorJim Meyering <meyering@redhat.com>
Wed, 9 Jun 2010 16:22:25 +0000 (18:22 +0200)
committerJim Meyering <meyering@redhat.com>
Thu, 10 Jun 2010 13:16:51 +0000 (15:16 +0200)
The namesake function was not available.  The existence of the
template file, inttostr.c makes its addition nontrivial.
* lib/anytostr.c: Rename from inttostr.c.
(anytostr): Rename from inttostr.
* lib/inttostr.c: New file.
* modules/inttostr (Files): Add anytostr.c.
(Makefile.am): Set lib_SOURCES instead of ...
* m4/inttostr.m4: Remove uses of AC_LIBOBJ.
* lib/imaxtostr.c: Update use.  s/inttostr/anytostr/
* lib/offtostr.c: Likewise.
* lib/uinttostr.c: Likewise.
* lib/umaxtostr.c: Likewise.
* modules/inttostr-tests: New file.
* tests/test-inttostr.c: New file.  Test these functions.

12 files changed:
ChangeLog
lib/anytostr.c [new file with mode: 0644]
lib/imaxtostr.c
lib/inttostr.c
lib/inttostr.h
lib/offtostr.c
lib/uinttostr.c
lib/umaxtostr.c
m4/inttostr.m4
modules/inttostr
modules/inttostr-tests [new file with mode: 0644]
tests/test-inttostr.c [new file with mode: 0644]

index 71803c7ece20fa3a8355ba48917c0f45c202a5b6..8cfeff5bac18dca1fb9eaca4c32b3b917bb50a1a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2010-06-10  Jim Meyering  <meyering@redhat.com>
+
+       inttostr: add a new function, inttostr, and tests
+       The namesake function was not available.  The existence of the
+       template file, inttostr.c makes its addition nontrivial.
+       * lib/anytostr.c: Rename from inttostr.c.
+       (anytostr): Rename from inttostr.
+       * lib/inttostr.c: New file.
+       * modules/inttostr (Files): Add anytostr.c.
+       (Makefile.am): Set lib_SOURCES instead of ...
+       * m4/inttostr.m4: Remove uses of AC_LIBOBJ.
+       * lib/imaxtostr.c: Update use.  s/inttostr/anytostr/
+       * lib/offtostr.c: Likewise.
+       * lib/uinttostr.c: Likewise.
+       * lib/umaxtostr.c: Likewise.
+       * modules/inttostr-tests: New file.
+       * tests/test-inttostr.c: New file.  Test these functions.
+
 2010-06-09  Ben Pfaff  <blp@cs.stanford.edu>
             Bruno Haible  <bruno@clisp.org>
 
diff --git a/lib/anytostr.c b/lib/anytostr.c
new file mode 100644 (file)
index 0000000..27ad985
--- /dev/null
@@ -0,0 +1,54 @@
+/* anytostr.c -- convert integers to printable strings
+
+   Copyright (C) 2001, 2006, 2008, 2009, 2010 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 <http://www.gnu.org/licenses/>.  */
+
+/* Written by Paul Eggert */
+
+#include <config.h>
+
+#include "inttostr.h"
+#include "verify.h"
+
+/* Convert I to a printable string in BUF, which must be at least
+   INT_BUFSIZE_BOUND (INTTYPE) bytes long.  Return the address of the
+   printable string, which need not start at BUF.  */
+
+char * __attribute_warn_unused_result__
+anytostr (inttype i, char *buf)
+{
+  verify (TYPE_SIGNED (inttype) == inttype_is_signed);
+  char *p = buf + INT_STRLEN_BOUND (inttype);
+  *p = 0;
+
+#if inttype_is_signed
+  if (i < 0)
+    {
+      do
+        *--p = '0' - i % 10;
+      while ((i /= 10) != 0);
+
+      *--p = '-';
+    }
+  else
+#endif
+    {
+      do
+        *--p = '0' + i % 10;
+      while ((i /= 10) != 0);
+    }
+
+  return p;
+}
index 34ef96c4500968aad3d3972894dbd014d20ef274..d2a0429b0d3b682be78d827fa6f5cde91cbfe627 100644 (file)
@@ -1,4 +1,4 @@
-#define inttostr imaxtostr
+#define anytostr imaxtostr
 #define inttype intmax_t
 #define inttype_is_signed 1
-#include "inttostr.c"
+#include "anytostr.c"
index 7a4a47f5f67e42e2ec035f5031940b2354d57b57..14db9b8c11f6c426a7bd0d695ccd1da27a6aae9a 100644 (file)
@@ -1,54 +1,4 @@
-/* inttostr.c -- convert integers to printable strings
-
-   Copyright (C) 2001, 2006, 2008, 2009, 2010 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 <http://www.gnu.org/licenses/>.  */
-
-/* Written by Paul Eggert */
-
-#include <config.h>
-
-#include "inttostr.h"
-#include "verify.h"
-
-/* Convert I to a printable string in BUF, which must be at least
-   INT_BUFSIZE_BOUND (INTTYPE) bytes long.  Return the address of the
-   printable string, which need not start at BUF.  */
-
-char *
-inttostr (inttype i, char *buf)
-{
-  verify (TYPE_SIGNED (inttype) == inttype_is_signed);
-  char *p = buf + INT_STRLEN_BOUND (inttype);
-  *p = 0;
-
-#if inttype_is_signed
-  if (i < 0)
-    {
-      do
-        *--p = '0' - i % 10;
-      while ((i /= 10) != 0);
-
-      *--p = '-';
-    }
-  else
-#endif
-    {
-      do
-        *--p = '0' + i % 10;
-      while ((i /= 10) != 0);
-    }
-
-  return p;
-}
+#define anytostr inttostr
+#define inttype int
+#define inttype_is_signed 1
+#include "anytostr.c"
index f11a5ff6720e10cfc906593fe0960dd55dda695f..4f74968703fc92f8015c7095f5d0e6c476df0563 100644 (file)
@@ -39,7 +39,8 @@
 # define __attribute_warn_unused_result__ /* empty */
 #endif
 
-char *offtostr (off_t, char *) __attribute_warn_unused_result__;
 char *imaxtostr (intmax_t, char *) __attribute_warn_unused_result__;
-char *umaxtostr (uintmax_t, char *) __attribute_warn_unused_result__;
+char *inttostr (int, char *) __attribute_warn_unused_result__;
+char *offtostr (off_t, char *) __attribute_warn_unused_result__;
 char *uinttostr (unsigned int, char *) __attribute_warn_unused_result__;
+char *umaxtostr (uintmax_t, char *) __attribute_warn_unused_result__;
index 3a60c6e7445ca9691d1127cd40fd97c71bae7e71..68f2b695be1285b7777155dd6d1d2fef13e8d9b0 100644 (file)
@@ -1,4 +1,4 @@
-#define inttostr offtostr
+#define anytostr offtostr
 #define inttype off_t
 #define inttype_is_signed 1
-#include "inttostr.c"
+#include "anytostr.c"
index 1662985f4091331644bf217ff0b432a915b8e1f8..21fa3761a90fd1223cd3350d1b20d920ab532e32 100644 (file)
@@ -1,4 +1,4 @@
-#define inttostr uinttostr
+#define anytostr uinttostr
 #define inttype unsigned int
 #define inttype_is_signed 0
-#include "inttostr.c"
+#include "anytostr.c"
index 914f388d1b323d67486c1a9b478d4f6c2419efd2..7fd995084e76157d6cd60dae4dc0cbb3e4e7f7d9 100644 (file)
@@ -1,4 +1,4 @@
-#define inttostr umaxtostr
+#define anytostr umaxtostr
 #define inttype uintmax_t
 #define inttype_is_signed 0
-#include "inttostr.c"
+#include "anytostr.c"
index 3e17ed59f197eb15df08f966b42324e9e6b71edf..ff64ddbd3e226d908f8d5f3bdfa2432f9285242f 100644 (file)
@@ -1,4 +1,4 @@
-#serial 7
+#serial 8
 dnl Copyright (C) 2004, 2005, 2006, 2009, 2010 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -6,11 +6,6 @@ dnl with or without modifications, as long as this notice is preserved.
 
 AC_DEFUN([gl_INTTOSTR],
 [
-  AC_LIBOBJ([imaxtostr])
-  AC_LIBOBJ([offtostr])
-  AC_LIBOBJ([umaxtostr])
-  AC_LIBOBJ([uinttostr])
-
   gl_PREREQ_INTTOSTR
   gl_PREREQ_IMAXTOSTR
   gl_PREREQ_OFFTOSTR
index 2c2b76e5bbfa9931637bf612ade217ed56acab2e..495ef25cf57f43c7d8315bb2fcdc5d22aacf0593 100644 (file)
@@ -2,6 +2,7 @@ Description:
 Convert integers to printable strings.
 
 Files:
+lib/anytostr.c
 lib/imaxtostr.c
 lib/inttostr.c
 lib/inttostr.h
@@ -19,6 +20,12 @@ configure.ac:
 gl_INTTOSTR
 
 Makefile.am:
+lib_SOURCES += \
+  imaxtostr.c \
+  inttostr.c \
+  offtostr.c \
+  uinttostr.c \
+  umaxtostr.c
 
 Include:
 "inttostr.h"
diff --git a/modules/inttostr-tests b/modules/inttostr-tests
new file mode 100644 (file)
index 0000000..69716d2
--- /dev/null
@@ -0,0 +1,13 @@
+Files:
+tests/test-inttostr.c
+
+Depends-on:
+intprops
+inttypes
+snprintf-posix
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-inttostr
+check_PROGRAMS += test-inttostr
diff --git a/tests/test-inttostr.c b/tests/test-inttostr.c
new file mode 100644 (file)
index 0000000..e8149e4
--- /dev/null
@@ -0,0 +1,72 @@
+/* Test inttostr functions, and incidentally, INT_BUFSIZE_BOUND
+   Copyright (C) 2010 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 <http://www.gnu.org/licenses/>.  */
+
+/* Written by Jim Meyering.  */
+
+#include <config.h>
+
+#include "inttostr.h"
+#include "intprops.h"
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#define STREQ(a, b) (strcmp (a, b) == 0)
+#define FMT(T) (TYPE_SIGNED (T) ? "%jd" : "%ju")
+#define CAST_VAL(T,V) (TYPE_SIGNED (T) ? (intmax_t) (V) : (uintmax_t) (V))
+#define V_min(T) (CAST_VAL (T, TYPE_MINIMUM (T)))
+#define V_max(T) (CAST_VAL (T, TYPE_MAXIMUM (T)))
+#define IS_TIGHT(T) (signed_type_or_expr__(T) == TYPE_SIGNED (T))
+#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9)
+
+/* Verify that an inttostr function works as advertised.
+   Convert maximum and minimum (per-type, T) values using both snprintf --
+   with a cast to intmax_t or uintmax_t -- and FN, and compare the
+   resulting strings.  Use malloc for the inttostr buffer, so that if
+   we ever exceed the usually-tight INT_BUFSIZE_BOUND, tools like
+   valgrind will detect the failure. */
+#define CK(T, Fn)                                                       \
+  do                                                                    \
+    {                                                                   \
+      char ref[100];                                                    \
+      char *buf = malloc (INT_BUFSIZE_BOUND (T));                       \
+      char const *p;                                                    \
+      assert (buf);                                                     \
+      *buf = '\0';                                                      \
+      assert (snprintf (ref, sizeof ref, FMT (T), V_min (T)) < sizeof ref); \
+      assert (STREQ ((p = Fn (TYPE_MINIMUM (T), buf)), ref));           \
+      /* Ensure that INT_BUFSIZE_BOUND is tight for signed types.  */   \
+      assert (! TYPE_SIGNED (T) || (p == buf && *p == '-'));            \
+      assert (snprintf (ref, sizeof ref, FMT (T), V_max (T)) < sizeof ref); \
+      assert (STREQ ((p = Fn (TYPE_MAXIMUM (T), buf)), ref));           \
+      /* For unsigned types, the bound is not always tight.  */         \
+      assert (! IS_TIGHT (T) || TYPE_SIGNED (T)                         \
+              || (p == buf && ISDIGIT (*p)));                           \
+      free (buf);                                                       \
+    }                                                                   \
+  while (0)
+
+int
+main (void)
+{
+  CK (int,          inttostr);
+  CK (unsigned int, uinttostr);
+  CK (off_t,        offtostr);
+  CK (uintmax_t,    umaxtostr);
+  CK (intmax_t,     imaxtostr);
+  return 0;
+}