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

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: