summaryrefslogtreecommitdiff
path: root/coreutils/printf.c
diff options
context:
space:
mode:
Diffstat (limited to 'coreutils/printf.c')
-rw-r--r--coreutils/printf.c31
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);
44static void print_direc(char *start, size_t length, 44static 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
47typedef int (*converter)(char *arg, void *result); 47typedef void (*converter)(char *arg, void *result);
48 48
49static void multiconvert(char *arg, void *result, converter convert) 49static 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
61static void conv_strtoul(char *arg, void *result)
62{
63 *(unsigned long*)result = bb_strtoul(arg, NULL, 10);
64}
65static void conv_strtol(char *arg, void *result)
66{
67 *(long*)result = bb_strtol(arg, NULL, 10);
68}
69static 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
60static unsigned long my_xstrtoul(char *arg) 78static 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
68static long my_xstrtol(char *arg) 85static 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
75static double my_xstrtod(char *arg) 92static 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