diff options
Diffstat (limited to 'coreutils/printf.c')
-rw-r--r-- | coreutils/printf.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/coreutils/printf.c b/coreutils/printf.c index 1511034a1..0e818354f 100644 --- a/coreutils/printf.c +++ b/coreutils/printf.c | |||
@@ -44,38 +44,55 @@ static int print_formatted(char *format, int argc, char **argv); | |||
44 | static void print_direc(char *start, size_t length, | 44 | static void print_direc(char *start, size_t length, |
45 | int field_width, int precision, char *argument); | 45 | int field_width, int precision, char *argument); |
46 | 46 | ||
47 | typedef int (*converter)(char *arg, void *result); | 47 | typedef void (*converter)(char *arg, void *result); |
48 | 48 | ||
49 | static void multiconvert(char *arg, void *result, converter convert) | 49 | static void multiconvert(char *arg, void *result, converter convert) |
50 | { | 50 | { |
51 | char s[16]; | 51 | char s[16]; |
52 | if (*arg == '"' || *arg == '\'') { | 52 | if (*arg == '"' || *arg == '\'') { |
53 | sprintf(s, "%d", (unsigned)arg[1]); | 53 | sprintf(s, "%d", (unsigned char)arg[1]); |
54 | arg = s; | 54 | arg = s; |
55 | } | 55 | } |
56 | if (convert(arg, result)) | 56 | convert(arg, result); |
57 | if (errno) /* Huh, looks strange... bug? */ | ||
57 | fputs(arg, stderr); | 58 | fputs(arg, stderr); |
58 | } | 59 | } |
59 | 60 | ||
61 | static void conv_strtoul(char *arg, void *result) | ||
62 | { | ||
63 | *(unsigned long*)result = bb_strtoul(arg, NULL, 10); | ||
64 | } | ||
65 | static void conv_strtol(char *arg, void *result) | ||
66 | { | ||
67 | *(long*)result = bb_strtol(arg, NULL, 10); | ||
68 | } | ||
69 | static void conv_strtod(char *arg, void *result) | ||
70 | { | ||
71 | char *end; | ||
72 | /* Well, this one allows leading whitespace... so what */ | ||
73 | /* What I like much less is that "-" is accepted too! :( */ | ||
74 | *(double*)result = strtod(arg, &end); | ||
75 | if (end[0]) errno = ERANGE; | ||
76 | } | ||
77 | |||
60 | static unsigned long my_xstrtoul(char *arg) | 78 | static unsigned long my_xstrtoul(char *arg) |
61 | { | 79 | { |
62 | unsigned long result; | 80 | unsigned long result; |
63 | 81 | multiconvert(arg, &result, conv_strtoul); | |
64 | multiconvert(arg, &result, (converter)safe_strtoul); | ||
65 | return result; | 82 | return result; |
66 | } | 83 | } |
67 | 84 | ||
68 | static long my_xstrtol(char *arg) | 85 | static long my_xstrtol(char *arg) |
69 | { | 86 | { |
70 | long result; | 87 | long result; |
71 | multiconvert(arg, &result, (converter)safe_strtol); | 88 | multiconvert(arg, &result, conv_strtol); |
72 | return result; | 89 | return result; |
73 | } | 90 | } |
74 | 91 | ||
75 | static double my_xstrtod(char *arg) | 92 | static double my_xstrtod(char *arg) |
76 | { | 93 | { |
77 | double result; | 94 | double result; |
78 | multiconvert(arg, &result, (converter)safe_strtod); | 95 | multiconvert(arg, &result, conv_strtod); |
79 | return result; | 96 | return result; |
80 | } | 97 | } |
81 | 98 | ||