GNU bug report logs - #7701
[PATCH] getlimits: port to hosts with very wide int, or non-ASCII

Previous Next

Package: coreutils;

Reported by: Paul Eggert <eggert <at> cs.ucla.edu>

Date: Tue, 21 Dec 2010 22:08:02 UTC

Severity: normal

Tags: patch

Done: Pádraig Brady <P <at> draigBrady.com>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 7701 in the body.
You can then email your comments to 7701 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org:
bug#7701; Package coreutils. (Tue, 21 Dec 2010 22:08:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Paul Eggert <eggert <at> cs.ucla.edu>:
New bug report received and forwarded. Copy sent to bug-coreutils <at> gnu.org. (Tue, 21 Dec 2010 22:08:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: bug-coreutils <at> gnu.org
Subject: [PATCH] getlimits: port to hosts with very wide int, or non-ASCII
Date: Tue, 21 Dec 2010 14:14:15 -0800
I haven't pushed this, since the portability bugs it fixes aren't triggered on
any hosts that I know of, and we're currently just fixing known bugs.


From dc02fc920e6f866e0e0ed407681ef5c4795e4e77 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert <at> cs.ucla.edu>
Date: Tue, 21 Dec 2010 13:53:34 -0800
Subject: [PATCH] getlimits: port to hosts with very wide int, or non-ASCII

* src/getlimits.c (decimal_ascii_add): Remove, replacing with ...
(decimal_absval_add_one): New function, with different signature,
which does not assume ASCII.  All callers changed.
(print_int): Remove assumptions that integers fit in 206 bits, and
that characters are ASCII.  These assumptions are portable in
practice but are easy to remove here.
---
 src/getlimits.c |   74 ++++++++++++++++++-------------------------------------
 1 files changed, 24 insertions(+), 50 deletions(-)

diff --git a/src/getlimits.c b/src/getlimits.c
index 93d4035..986a5d7 100644
--- a/src/getlimits.c
+++ b/src/getlimits.c
@@ -79,53 +79,31 @@ Output platform dependent limits in a format useful for shell scripts.\n\
   exit (status);
 }
 
-/* Add absolute values of ascii decimal strings.
- * Strings can have leading spaces.
- * If any string has a '-' it's preserved in the output:
- * I.E.
- *    1 +  1 ->  2
- *   -1 + -1 -> -2
- *   -1 +  1 -> -2
- *    1 + -1 -> -2
- */
-static char *
-decimal_ascii_add (const char *str1, const char *str2)
+/* 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)
 {
-  int len1 = strlen (str1);
-  int len2 = strlen (str2);
-  int rlen = MAX (len1, len2) + 3;  /* space for extra digit or sign + NUL */
-  char *result = xmalloc (rlen);
-  char *rp = result + rlen - 1;
-  const char *d1 = str1 + len1 - 1;
-  const char *d2 = str2 + len2 - 1;
-  int carry = 0;
-  *rp = '\0';
-
-  while (1)
-    {
-      char c1 = (d1 < str1 ? ' ' : (*d1 == '-' ? ' ' : *d1--));
-      char c2 = (d2 < str2 ? ' ' : (*d2 == '-' ? ' ' : *d2--));
-      char t1 = c1 + c2 + carry;    /* ASCII digits are BCD */
-      if (!c_isdigit (c1) && !c_isdigit (c2) && !carry)
-        break;
-      carry = t1 > '0' + '9' || t1 == ' ' + '9' + 1;
-      t1 += 6 * carry;
-      *--rp = (t1 & 0x0F) | 0x30;   /* top nibble to ASCII */
-    }
-  if ((d1 >= str1 && *d1 == '-') || (d2 >= str2 && (*d2 == '-')))
-    *--rp = '-';
-
-  if (rp != result)
-    memmove (result, rp, rlen - (rp - result));
-
+  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;
 }
 
 int
 main (int argc, char **argv)
 {
-  char limit[64];               /* big enough for 128 bit integers at least */
-  char *oflow;
+  char limit[1 + MAX (INT_BUFSIZE_BOUND (intmax_t),
+                      INT_BUFSIZE_BOUND (uintmax_t))];
 
   initialize_main (&argc, &argv);
   set_program_name (argv[0]);
@@ -140,18 +118,14 @@ main (int argc, char **argv)
                       usage, AUTHORS, (char const *) NULL);
 
 #define print_int(TYPE)                                                  \
-  snprintf (limit, sizeof limit, "%"PRIuMAX, (uintmax_t)TYPE##_MAX);     \
-  printf (#TYPE"_MAX=%s\n", limit);                                      \
-  oflow = decimal_ascii_add (limit, "1");                                \
-  printf (#TYPE"_OFLOW=%s\n", oflow);                                    \
-  free (oflow);                                                          \
+  sprintf (limit + 1, "%"PRIuMAX, (uintmax_t) TYPE##_MAX);               \
+  printf (#TYPE"_MAX=%s\n", limit + 1);                                  \
+  printf (#TYPE"_OFLOW=%s\n", decimal_absval_add_one (limit));           \
   if (TYPE##_MIN)                                                        \
     {                                                                    \
-      snprintf (limit, sizeof limit, "%"PRIdMAX, (intmax_t)TYPE##_MIN);  \
-      printf (#TYPE"_MIN=%s\n", limit);                                  \
-      oflow = decimal_ascii_add (limit, "-1");                           \
-      printf (#TYPE"_UFLOW=%s\n", oflow);                                \
-      free (oflow);                                                      \
+      sprintf (limit + 1, "%"PRIdMAX, (intmax_t) TYPE##_MIN);            \
+      printf (#TYPE"_MIN=%s\n", limit + 1);                              \
+      printf (#TYPE"_UFLOW=%s\n", decimal_absval_add_one (limit));       \
     }
 
 #define print_float(TYPE)                                                \
-- 
1.7.2





Reply sent to Pádraig Brady <P <at> draigBrady.com>:
You have taken responsibility. (Tue, 21 Dec 2010 22:56:02 GMT) Full text and rfc822 format available.

Notification sent to Paul Eggert <eggert <at> cs.ucla.edu>:
bug acknowledged by developer. (Tue, 21 Dec 2010 22:56:02 GMT) Full text and rfc822 format available.

Message #10 received at 7701-done <at> debbugs.gnu.org (full text, mbox):

From: Pádraig Brady <P <at> draigBrady.com>
To: Paul Eggert <eggert <at> cs.ucla.edu>
Cc: 7701-done <at> debbugs.gnu.org
Subject: Re: bug#7701: [PATCH] getlimits: port to hosts with very wide int,
	or non-ASCII
Date: Tue, 21 Dec 2010 22:58:33 +0000
On 21/12/10 22:14, Paul Eggert wrote:
> I haven't pushed this, since the portability bugs it fixes aren't triggered on
> any hosts that I know of, and we're currently just fixing known bugs.

Thanks for the cleanup Paul.
Your 'add' routine is less general
but also simpler, so you're free
to push that after the imminent release.

Mildly related to this is; speeding up seq.
That might be able to use the more general
routine (without allocs) in certain cases.
It might be simple/faster than using gmp?

cheers,
Pádraig.

p.s. savannah is down ATM




Message #11 received at 7701-done <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: Pádraig Brady <P <at> draigBrady.com>
Cc: 7701-done <at> debbugs.gnu.org
Subject: Re: bug#7701: [PATCH] getlimits: port to hosts with very wide int,
	or non-ASCII
Date: Tue, 21 Dec 2010 17:46:37 -0800
On 12/21/2010 02:58 PM, Pádraig Brady wrote:
> Mildly related to this is; speeding up seq.

Oh *yeah*.  Seq is abysmally slow, and could probably be
sped up by a factor of 10 without too much effort.  Maybe
I'll assign that to my students; it's a nice little project.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Wed, 19 Jan 2011 12:24:04 GMT) Full text and rfc822 format available.

This bug report was last modified 14 years and 155 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.