mirror of
https://github.com/sheumann/hush.git
synced 2024-12-28 07:30:23 +00:00
printf: fix printf -%s- foo, printf -- -%s- foo (bug 3354)
function old new delta printf_main 577 548 -29
This commit is contained in:
parent
29eb3599e4
commit
b6c4855f1d
@ -185,13 +185,10 @@ static void print_direc(char *start, size_t length, int field_width, int precisi
|
|||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print the text in FORMAT, using ARGV (with ARGC elements) for
|
/* Print the text in FORMAT, using ARGV for arguments to any '%' directives.
|
||||||
arguments to any '%' directives.
|
Return advanced ARGV. */
|
||||||
Return the number of elements of ARGV used. */
|
static char **print_formatted(char *format, char **argv)
|
||||||
|
|
||||||
static int print_formatted(char *format, int argc, char **argv)
|
|
||||||
{
|
{
|
||||||
int save_argc = argc; /* Preserve original value. */
|
|
||||||
char *f; /* Pointer into 'format'. */
|
char *f; /* Pointer into 'format'. */
|
||||||
char *direc_start; /* Start of % directive. */
|
char *direc_start; /* Start of % directive. */
|
||||||
size_t direc_length; /* Length of % directive. */
|
size_t direc_length; /* Length of % directive. */
|
||||||
@ -209,10 +206,9 @@ static int print_formatted(char *format, int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (*f == 'b') {
|
if (*f == 'b') {
|
||||||
if (argc > 0) {
|
if (*argv) {
|
||||||
print_esc_string(*argv);
|
print_esc_string(*argv);
|
||||||
++argv;
|
++argv;
|
||||||
--argc;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -223,10 +219,9 @@ static int print_formatted(char *format, int argc, char **argv)
|
|||||||
if (*f == '*') {
|
if (*f == '*') {
|
||||||
++f;
|
++f;
|
||||||
++direc_length;
|
++direc_length;
|
||||||
if (argc > 0) {
|
if (*argv) {
|
||||||
field_width = my_xstrtoul(*argv);
|
field_width = my_xstrtoul(*argv);
|
||||||
++argv;
|
++argv;
|
||||||
--argc;
|
|
||||||
} else
|
} else
|
||||||
field_width = 0;
|
field_width = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -241,10 +236,9 @@ static int print_formatted(char *format, int argc, char **argv)
|
|||||||
if (*f == '*') {
|
if (*f == '*') {
|
||||||
++f;
|
++f;
|
||||||
++direc_length;
|
++direc_length;
|
||||||
if (argc > 0) {
|
if (*argv) {
|
||||||
precision = my_xstrtoul(*argv);
|
precision = my_xstrtoul(*argv);
|
||||||
++argv;
|
++argv;
|
||||||
--argc;
|
|
||||||
} else
|
} else
|
||||||
precision = 0;
|
precision = 0;
|
||||||
} else
|
} else
|
||||||
@ -262,11 +256,10 @@ static int print_formatted(char *format, int argc, char **argv)
|
|||||||
fprintf(stderr, "%%%c: invalid directive", *f);
|
fprintf(stderr, "%%%c: invalid directive", *f);
|
||||||
*/
|
*/
|
||||||
++direc_length;
|
++direc_length;
|
||||||
if (argc > 0) {
|
if (*argv) {
|
||||||
print_direc(direc_start, direc_length, field_width,
|
print_direc(direc_start, direc_length, field_width,
|
||||||
precision, *argv);
|
precision, *argv);
|
||||||
++argv;
|
++argv;
|
||||||
--argc;
|
|
||||||
} else
|
} else
|
||||||
print_direc(direc_start, direc_length, field_width,
|
print_direc(direc_start, direc_length, field_width,
|
||||||
precision, "");
|
precision, "");
|
||||||
@ -282,32 +275,35 @@ static int print_formatted(char *format, int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return save_argc - argc;
|
return argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
int printf_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
int printf_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||||
int printf_main(int argc, char **argv)
|
int printf_main(int argc ATTRIBUTE_UNUSED, char **argv)
|
||||||
{
|
{
|
||||||
char *format;
|
char *format;
|
||||||
int args_used;
|
char **argv2;
|
||||||
|
|
||||||
if (argc <= 1 || argv[1][0] == '-') {
|
/* bash builtin errors out on "printf '-%s-\n' foo",
|
||||||
|
* coreutils-6.9 works. Both work with "printf -- '-%s-\n' foo".
|
||||||
|
* We will mimic coreutils. */
|
||||||
|
if (argv[1] && argv[1][0] == '-' && argv[1][1] == '-' && argv[1][2] == '\0')
|
||||||
|
argv++;
|
||||||
|
if (!argv[1])
|
||||||
bb_show_usage();
|
bb_show_usage();
|
||||||
}
|
|
||||||
|
|
||||||
format = argv[1];
|
format = argv[1];
|
||||||
argc -= 2;
|
argv2 = argv + 2;
|
||||||
argv += 2;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
args_used = print_formatted(format, argc, argv);
|
argv = argv2;
|
||||||
argc -= args_used;
|
argv2 = print_formatted(format, argv);
|
||||||
argv += args_used;
|
} while (argv2 != argv && *argv2);
|
||||||
} while (args_used > 0 && argc > 0);
|
|
||||||
|
|
||||||
/* if (argc > 0)
|
/* coreutils compat (bash doesn't do this):
|
||||||
|
if (*argv)
|
||||||
fprintf(stderr, "excess args ignored");
|
fprintf(stderr, "excess args ignored");
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user