]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
seq: explicate incr
authorPaul Eggert <eggert@cs.ucla.edu>
Fri, 8 Nov 2024 17:35:35 +0000 (09:35 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Sat, 9 Nov 2024 07:41:18 +0000 (23:41 -0800)
* src/seq.c (incr): Change API to make the code easier to follow,
and also to avoid undefined behavior on hypothetical platforms
where '9' == INT_MAX (!).  Caller changed.

src/seq.c

index ad16f27018403ba041cdf7b941fa26f9b75b2bad..e0339c1fa214cb35abb39d352f89c3981a5cd163 100644 (file)
--- a/src/seq.c
+++ b/src/seq.c
@@ -403,24 +403,27 @@ get_default_format (operand first, operand step, operand last)
   return "%Lg";
 }
 
-/* The NUL-terminated string S0 of length S_LEN represents a valid
-   non-negative decimal integer.  Adjust the string and length so
-   that the pair describe the next-larger value.  */
-static void
-incr (char **s0, size_t *s_len)
+/* The nonempty char array P represents a valid non-negative decimal integer.
+   ENDP points just after the last char in P.
+   Adjust the array to describe the next-larger integer and return
+   whether this grows the array by one on the left.  */
+static bool
+incr_grows (char *p, char *endp)
 {
-  char *s = *s0;
-  char *endp = s + *s_len - 1;
-
   do
     {
-      if ((*endp)++ < '9')
-        return;
-      *endp-- = '0';
+      endp--;
+      if (*endp < '9')
+        {
+          (*endp)++;
+          return false;
+        }
+      *endp = '0';
     }
-  while (endp >= s);
-  *--(*s0) = '1';
-  ++*s_len;
+  while (p < endp);
+
+  p[-1] = '1';
+  return true;
 }
 
 /* Compare A and B (each a NUL-terminated digit string), with lengths
@@ -505,8 +508,10 @@ seq_fast (char const *a, char const *b, uintmax_t step)
       /* Append separator then number.  */
       while (true)
         {
+          char *endp = p + p_len;
           for (uintmax_t n_incr = step; n_incr; n_incr--)
-            incr (&p, &p_len);
+            p -= incr_grows (p, endp);
+          p_len = endp - p;
 
           if (! inf && 0 < cmp (p, p_len, q, q_len))
             break;