From d683c5c2f1493c2b0856a5f8751508836b0988d5 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Mon, 26 Oct 2015 10:10:28 +0100 Subject: tr: support octal ranges now, we can do printf "a\tb\tcdef\n" | ./busybox tr -d "\1-\14b-e" af and bonus, we save some bytes. function old new delta expand 718 699 -19 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-19) Total: -19 bytes Signed-off-by: Richard Genoud Signed-off-by: Denys Vlasenko --- coreutils/tr.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'coreutils/tr.c') diff --git a/coreutils/tr.c b/coreutils/tr.c index e67948a36..2f49d5a86 100644 --- a/coreutils/tr.c +++ b/coreutils/tr.c @@ -91,7 +91,6 @@ static void map(char *pvector, * Character classes, e.g. [:upper:] ==> A...Z * Equiv classess, e.g. [=A=] ==> A (hmmmmmmm?) * not supported: - * \ooo-\ooo - octal ranges * [x*N] - repeat char x N times * [x*] - repeat char x until it fills STRING2: * # echo qwe123 | /usr/bin/tr 123456789 '[d]' @@ -99,7 +98,7 @@ static void map(char *pvector, * # echo qwe123 | /usr/bin/tr 123456789 '[d*]' * qweddd */ -static unsigned expand(const char *arg, char **buffer_p) +static unsigned expand(char *arg, char **buffer_p) { char *buffer = *buffer_p; unsigned pos = 0; @@ -113,9 +112,17 @@ static unsigned expand(const char *arg, char **buffer_p) *buffer_p = buffer = xrealloc(buffer, size); } if (*arg == '\\') { + const char *z; arg++; - buffer[pos++] = bb_process_escape_sequence(&arg); - continue; + z = arg; + ac = bb_process_escape_sequence(&z); + arg = (char *)z; + arg--; + *arg = ac; + /* + * fall through, there may be a range. + * If not, current char will be treated anyway. + */ } if (arg[1] == '-') { /* "0-9..." */ ac = arg[2]; @@ -124,9 +131,15 @@ static unsigned expand(const char *arg, char **buffer_p) continue; /* next iter will copy '-' and stop */ } i = (unsigned char) *arg; + arg += 3; /* skip 0-9 or 0-\ */ + if (ac == '\\') { + const char *z; + z = arg; + ac = bb_process_escape_sequence(&z); + arg = (char *)z; + } while (i <= ac) /* ok: i is unsigned _int_ */ buffer[pos++] = i++; - arg += 3; /* skip 0-9 */ continue; } if ((ENABLE_FEATURE_TR_CLASSES || ENABLE_FEATURE_TR_EQUIV) -- cgit v1.2.3