X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=coreutils%2Fprintf.c;h=eb53fa490690f4264c76c50045b606bca662bb74;hb=8d680b51148b9cbe7dd3afd37022f3390dd999ef;hp=2beea71895e4a5d844deb8c28225162b3cfab714;hpb=71016baf5524d739d1dd4d9110b111a7c3ddcaf9;p=oweals%2Fbusybox.git diff --git a/coreutils/printf.c b/coreutils/printf.c index 2beea7189..eb53fa490 100644 --- a/coreutils/printf.c +++ b/coreutils/printf.c @@ -53,10 +53,7 @@ * (but negative numbers are not "bad"). * Both accept negative numbers for %u specifier. * - * We try to be compatible. We are not compatible here: - * - we do not accept -NUM for %u - * - exit code is 0 even if "invalid number" was seen (FIXME) - * See "if (errno)" checks in the code below. + * We try to be compatible. */ typedef void FAST_FUNC (*converter)(const char *arg, void *result); @@ -155,6 +152,8 @@ static void print_direc(char *format, unsigned fmt_length, if (have_width - 1 == have_prec) have_width = NULL; + errno = 0; + switch (format[fmt_length - 1]) { case 'c': printf(format, *argument); @@ -163,7 +162,6 @@ static void print_direc(char *format, unsigned fmt_length, case 'i': llv = my_xstrtoll(argument); print_long: - /* if (errno) return; - see comment at the top */ if (!have_width) { if (!have_prec) printf(format, llv); @@ -210,7 +208,6 @@ static void print_direc(char *format, unsigned fmt_length, case 'g': case 'G': dv = my_xstrtod(argument); - /* if (errno) return; */ if (!have_width) { if (!have_prec) printf(format, dv); @@ -241,7 +238,7 @@ static int get_width_prec(const char *str) /* Print the text in FORMAT, using ARGV for arguments to any '%' directives. Return advanced ARGV. */ -static char **print_formatted(char *f, char **argv) +static char **print_formatted(char *f, char **argv, int *conv_err) { char *direc_start; /* Start of % directive. */ unsigned direc_length; /* Length of % directive. */ @@ -299,8 +296,8 @@ static char **print_formatted(char *f, char **argv) /* Remove "lLhz" size modifiers, repeatedly. * bash does not like "%lld", but coreutils - * would happily take even "%Llllhhzhhzd"! - * We will be permissive like coreutils */ + * happily takes even "%Llllhhzhhzd"! + * We are permissive like coreutils */ while ((*f | 0x20) == 'l' || *f == 'h' || *f == 'z') { overlapping_strcpy(f, f + 1); } @@ -330,12 +327,12 @@ static char **print_formatted(char *f, char **argv) } if (*argv) { print_direc(direc_start, direc_length, field_width, - precision, *argv); - ++argv; + precision, *argv++); } else { print_direc(direc_start, direc_length, field_width, precision, ""); } + *conv_err |= errno; free(p); } break; @@ -356,6 +353,7 @@ static char **print_formatted(char *f, char **argv) int printf_main(int argc UNUSED_PARAM, char **argv) { + int conv_err; char *format; char **argv2; @@ -392,9 +390,10 @@ int printf_main(int argc UNUSED_PARAM, char **argv) format = argv[1]; argv2 = argv + 2; + conv_err = 0; do { argv = argv2; - argv2 = print_formatted(format, argv); + argv2 = print_formatted(format, argv, &conv_err); } while (argv2 > argv && *argv2); /* coreutils compat (bash doesn't do this): @@ -402,5 +401,6 @@ int printf_main(int argc UNUSED_PARAM, char **argv) fprintf(stderr, "excess args ignored"); */ - return (argv2 < argv); /* if true, print_formatted errored out */ + return (argv2 < argv) /* if true, print_formatted errored out */ + || conv_err; /* print_formatted saw invalid number */ }