[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 <Martin.vGagern@gmx.net>
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);
+}