Bug#346077: busybox printf: support POSIX quoted-argument-character syntax
Package: busybox
Version: 1:1.01-3
Severity: wishlist
Tags: patch
POSIX documents [1] the following syntax for printf arguments:
The argument operands shall be treated as strings if the corresponding
conversion specifier is b, c, or s ; otherwise, it shall be evaluated
as a C constant, as described by the ISO C standard, with the
following extensions:
[...]
* If the leading character is a single-quote or double-quote, the
value shall be the numeric value in the underlying codeset of the
character following the single-quote or double-quote.
I found myself wanting this recently in order to convert non-devfs disk
device names into indices for display in partman (e.g. /dev/hde => "IDE2
master (hde)"). Lacking any other way to map from a-z to 0-25 in shell
that I can think of, it was going to have to be a messy sequence of sed
commands until somebody pointed out this syntax to me. With this patch,
I can just do:
printf '%d\n' "'$character"
... to map from a-z to 0-25, which is much nicer. The small attached
patch implements this feature; I've checked it against the printf
implementation in coreutils.
[1] http://www.opengroup.org/onlinepubs/009695399/utilities/printf.html
Thanks,
--
Colin Watson [cjwatson@debian.org]
--- busybox-1.01.orig/coreutils/printf.c
+++ busybox-1.01/coreutils/printf.c
@@ -281,7 +281,9 @@
static unsigned long xstrtoul(char *arg)
{
unsigned long result;
- if (safe_strtoul(arg, &result))
+ if (*arg == '"' || *arg == '\'')
+ result = (unsigned char) *(arg + 1);
+ else if (safe_strtoul(arg, &result))
fprintf(stderr, "%s", arg);
return result;
}
@@ -289,7 +291,9 @@
static long xstrtol(char *arg)
{
long result;
- if (safe_strtol(arg, &result))
+ if (*arg == '"' || *arg == '\'')
+ result = (unsigned char) *(arg + 1);
+ else if (safe_strtol(arg, &result))
fprintf(stderr, "%s", arg);
return result;
}
@@ -297,7 +301,9 @@
static double xstrtod(char *arg)
{
double result;
- if (safe_strtod(arg, &result))
+ if (*arg == '"' || *arg == '\'')
+ result = (unsigned char) *(arg + 1);
+ else if (safe_strtod(arg, &result))
fprintf(stderr, "%s", arg);
return result;
}
Reply to: