bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RFE: brace expansion sequences should do zero padding [patch]


From: Martin von Gagern
Subject: RFE: brace expansion sequences should do zero padding [patch]
Date: Thu, 30 Aug 2007 02:12:27 +0200
User-agent: Thunderbird 2.0.0.6 (X11/20070817)

Hi!

Suppose you have a set of files numbered and those numbers zero padded.
Of course you can list them using some magic with printf or some such,
but I would really love a simple feature like this:

cat x{000..123}

to concatenate files x000 through x123, not x0 through x123 as bash
currently does.

The attached patch should do the trick. I hope you agree with the place
where I chose to implement this feature. Do you think this has a chance
of getting implemented into the official source tree? If so, what is
left to do? Documentation? Any kind of test cases? Anything else?

Greetings,
 Martin von Gagern

P.S.: This is the second time I post this message here.
      The first one was via NNTP and it seems like it didn't make it.
Patch by Martin von Gagern <address@hidden>
to allow zero-padded numbers in bash brace expansion sequences.

diff -pur bash-3.2/braces.c bash/braces.c
--- bash-3.2/braces.c   2006-09-09 04:57:17.000000000 +0200
+++ bash/braces.c       2007-08-29 23:02:02.000000000 +0200
@@ -61,7 +61,7 @@
 static int brace_gobbler __P((char *, size_t, int *, int));
 static char **expand_amble __P((char *, size_t, int));
 static char **expand_seqterm __P((char *, size_t));
-static char **mkseq __P((int, int, int, int));
+static char **mkseq __P((int, int, int, int, int));
 static char **array_concat __P((char **, char **));
 #else
 static int brace_gobbler ();
@@ -303,8 +303,8 @@ mkseq (start, end, incr, type)
 #define ST_CHAR        2
 
 static char **
-mkseq (start, end, incr, type)
-     int start, end, incr, type;
+mkseq (start, end, incr, type, width)
+     int start, end, incr, type, width;
 {
   int n, i;
   char **result, *t;
@@ -329,7 +329,7 @@ mkseq (start, end, incr, type)
       QUIT;            /* XXX - memory leak here */
 #endif
       if (type == ST_INT)
-       result[i++] = itos (n);
+       result[i++] = itospad (n, width, '0');
       else
        {
          t = (char *)xmalloc (2);
@@ -353,7 +353,7 @@ expand_seqterm (text, tlen)
      size_t tlen;
 {
   char *t, *lhs, *rhs;
-  int i, lhs_t, rhs_t, lhs_v, rhs_v;
+  int lhs_l, rhs_l, lhs_t, rhs_t, lhs_v, rhs_v, width;
   intmax_t tl, tr;
   char **result;
 
@@ -361,9 +361,9 @@ expand_seqterm (text, tlen)
   if (t == 0)
     return ((char **)NULL);
 
-  i = t - text;                /* index of start of BRACE_SEQ_SPECIFIER */
-  lhs = substring (text, 0, i);
-  rhs = substring (text, i + sizeof(BRACE_SEQ_SPECIFIER) - 1, tlen);
+  lhs_l = t - text;            /* index of start of BRACE_SEQ_SPECIFIER */
+  lhs = substring (text, 0, lhs_l);
+  rhs = substring (text, lhs_l + sizeof(BRACE_SEQ_SPECIFIER) - 1, tlen);
 
   if (lhs[0] == 0 || rhs[0] == 0)
     {
@@ -399,9 +399,21 @@ expand_seqterm (text, tlen)
     {
       lhs_v = tl;              /* integer truncation */
       rhs_v = tr;
+
+      /* find out if the user wants padding, and if so how much */
+      rhs_l = tlen - lhs_l - sizeof(BRACE_SEQ_SPECIFIER) + 1;
+      width = 0;
+      if (lhs_l > 1 && lhs[0] == '0')
+       width = lhs_l;
+      if (lhs_l > 2 && lhs[0] == '-' && lhs[1] == '0')
+       width = lhs_l;
+      if (rhs_l > 1 && rhs[0] == '0' && width < rhs_l)
+       width = rhs_l;
+      if (rhs_l > 2 && rhs[0] == '-' && rhs[1] == '0' && width < rhs_l)
+       width = rhs_l;
     }
 
-  result = mkseq (lhs_v, rhs_v, 1, lhs_t);
+  result = mkseq (lhs_v, rhs_v, 1, lhs_t, width);
 
   free (lhs);
   free (rhs);
diff -pur bash-3.2/externs.h bash/externs.h
--- bash-3.2/externs.h  2006-07-28 03:40:49.000000000 +0200
+++ bash/externs.h      2007-08-29 22:21:16.000000000 +0200
@@ -178,6 +178,7 @@ extern char *inttostr __P((intmax_t, cha
 extern char *itos __P((intmax_t));
 extern char *uinttostr __P((uintmax_t, char *, size_t));
 extern char *uitos __P((uintmax_t));
+extern char *itospad __P((intmax_t, int, char));
 
 /* declarations for functions defined in lib/sh/makepath.c */
 #define MP_DOTILDE     0x01
diff -pur bash-3.2/lib/sh/itos.c bash/lib/sh/itos.c
--- bash-3.2/lib/sh/itos.c      2002-01-02 20:38:10.000000000 +0100
+++ bash/lib/sh/itos.c  2007-08-29 23:01:01.000000000 +0200
@@ -70,3 +70,43 @@ uitos (i)
   p = fmtumax (i, 10, lbuf, sizeof(lbuf), FL_UNSIGNED);
   return (savestring (p));
 }
+
+/* Integer to string conversion with padding.  This conses the string; the
+   caller should free it. */
+char *
+itospad (i, width, padchar)
+     intmax_t i;
+     int width;
+     char padchar;
+{
+  char *p, *buf, lbuf[INT_STRLEN_BOUND(intmax_t) + 1];
+  size_t len;
+
+  if (width + 1 <= sizeof(lbuf)) {
+    len = sizeof(lbuf);
+    buf = lbuf;
+  }
+  else {
+    len = width + 1;
+    buf = (char *)xmalloc (len);
+  }
+
+  p = fmtumax (i, 10, buf, len, 0);
+  /* The following padding implementation relies on the fact
+     that fmtumax fills the buffer from its end. */
+
+  if (p[0] != '-') {
+    while (buf + len - p <= width)
+      *--p = padchar;
+  }
+  else {
+    while (buf + len - p <= width)
+      *p-- = padchar;
+    *p = '-';
+  }
+
+  if (buf == lbuf)
+    buf = savestring (p);
+
+  return (buf);
+}


reply via email to

[Prev in Thread] Current Thread [Next in Thread]