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 00:33:22 +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
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]