- /* Remove size modifiers - "%Ld" would try to printf
- * long long, we pass long, and it spews garbage */
- if ((*f | 0x20) == 'l' || *f == 'h' || *f == 'z') {
- strcpy(f, f + 1);
- }
-//FIXME: actually, the same happens with bare "%d":
-//it printfs an int, but we pass long!
-//What saves us is that on most arches stack slot
-//is pointer-sized -> long-sized -> ints are promoted to longs
-// for variadic functions -> printf("%d", int_v) is in reality
-// indistinqushable from printf("%d", long_v) ->
-// since printf("%d", int_v) works, printf("%d", long_v) has to work.
-//But "clean" solution would be to add "l" to d,i,o,x,X.
-//Probably makes sense to go all the way to "ll" then.
-//Coreutils support long long-sized arguments.
-
- /* needed - try "printf %" without it */
- if (!strchr("diouxXfeEgGcs", *f)) {
- bb_error_msg("%s: invalid format", direc_start);
- /* causes main() to exit with error */
- return saved_argv - 1;
+
+ /* Remove "lLhz" size modifiers, repeatedly.
+ * bash does not like "%lld", but coreutils
+ * happily takes even "%Llllhhzhhzd"!
+ * We are permissive like coreutils */
+ while ((*f | 0x20) == 'l' || *f == 'h' || *f == 'z') {
+ overlapping_strcpy(f, f + 1);