Mercurial > hg > octave-kai > gnulib-hg
changeset 13400:4a25c1663687
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.
author | Jim Meyering <meyering@redhat.com> |
---|---|
date | Wed, 09 Jun 2010 18:22:25 +0200 |
parents | aae05084c143 |
children | 7d14ab8b5c99 |
files | ChangeLog lib/anytostr.c 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 tests/test-inttostr.c |
diffstat | 12 files changed, 180 insertions(+), 70 deletions(-) [+] |
line wrap: on
line diff
--- 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>
new file mode 100644 --- /dev/null +++ b/lib/anytostr.c @@ -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; +}
--- a/lib/imaxtostr.c +++ b/lib/imaxtostr.c @@ -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"
--- a/lib/inttostr.c +++ b/lib/inttostr.c @@ -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"
--- a/lib/inttostr.h +++ b/lib/inttostr.h @@ -39,7 +39,8 @@ # define __attribute_warn_unused_result__ /* empty */ #endif +char *imaxtostr (intmax_t, char *) __attribute_warn_unused_result__; +char *inttostr (int, char *) __attribute_warn_unused_result__; char *offtostr (off_t, char *) __attribute_warn_unused_result__; -char *imaxtostr (intmax_t, char *) __attribute_warn_unused_result__; +char *uinttostr (unsigned int, char *) __attribute_warn_unused_result__; char *umaxtostr (uintmax_t, char *) __attribute_warn_unused_result__; -char *uinttostr (unsigned int, char *) __attribute_warn_unused_result__;
--- a/lib/offtostr.c +++ b/lib/offtostr.c @@ -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"
--- a/lib/uinttostr.c +++ b/lib/uinttostr.c @@ -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"
--- a/lib/umaxtostr.c +++ b/lib/umaxtostr.c @@ -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"
--- a/m4/inttostr.m4 +++ b/m4/inttostr.m4 @@ -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 @@ 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
--- a/modules/inttostr +++ b/modules/inttostr @@ -2,6 +2,7 @@ Convert integers to printable strings. Files: +lib/anytostr.c lib/imaxtostr.c lib/inttostr.c lib/inttostr.h @@ -19,6 +20,12 @@ gl_INTTOSTR Makefile.am: +lib_SOURCES += \ + imaxtostr.c \ + inttostr.c \ + offtostr.c \ + uinttostr.c \ + umaxtostr.c Include: "inttostr.h"
new file mode 100644 --- /dev/null +++ b/modules/inttostr-tests @@ -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
new file mode 100644 --- /dev/null +++ b/tests/test-inttostr.c @@ -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; +}