printf: code shrink by eliminating string alloc/copy

function                                             old     new   delta
print_direc                                          428     382     -46
This commit is contained in:
Denis Vlasenko 2008-05-31 11:41:50 +00:00
parent d12fcc20da
commit 1d1bba4e99

View File

@ -107,28 +107,28 @@ static void print_esc_string(char *str)
} }
} }
static void print_direc(char *start, size_t length, int field_width, int precision, static void print_direc(char *format, unsigned fmt_length,
int field_width, int precision,
const char *argument) const char *argument)
{ {
char *p; /* Null-terminated copy of % directive. */ char saved;
p = xmalloc((unsigned) (length + 1)); saved = format[fmt_length];
strncpy(p, start, length); format[fmt_length] = '\0';
p[length] = 0;
switch (p[length - 1]) { switch (p[fmt_length - 1]) {
case 'd': case 'd':
case 'i': case 'i':
if (field_width < 0) { if (field_width < 0) {
if (precision < 0) if (precision < 0)
printf(p, my_xstrtol(argument)); printf(format, my_xstrtol(argument));
else else
printf(p, precision, my_xstrtol(argument)); printf(format, precision, my_xstrtol(argument));
} else { } else {
if (precision < 0) if (precision < 0)
printf(p, field_width, my_xstrtol(argument)); printf(format, field_width, my_xstrtol(argument));
else else
printf(p, field_width, precision, my_xstrtol(argument)); printf(format, field_width, precision, my_xstrtol(argument));
} }
break; break;
case 'o': case 'o':
@ -137,14 +137,14 @@ static void print_direc(char *start, size_t length, int field_width, int precisi
case 'X': case 'X':
if (field_width < 0) { if (field_width < 0) {
if (precision < 0) if (precision < 0)
printf(p, my_xstrtoul(argument)); printf(format, my_xstrtoul(argument));
else else
printf(p, precision, my_xstrtoul(argument)); printf(format, precision, my_xstrtoul(argument));
} else { } else {
if (precision < 0) if (precision < 0)
printf(p, field_width, my_xstrtoul(argument)); printf(format, field_width, my_xstrtoul(argument));
else else
printf(p, field_width, precision, my_xstrtoul(argument)); printf(format, field_width, precision, my_xstrtoul(argument));
} }
break; break;
case 'f': case 'f':
@ -154,48 +154,47 @@ static void print_direc(char *start, size_t length, int field_width, int precisi
case 'G': case 'G':
if (field_width < 0) { if (field_width < 0) {
if (precision < 0) if (precision < 0)
printf(p, my_xstrtod(argument)); printf(format, my_xstrtod(argument));
else else
printf(p, precision, my_xstrtod(argument)); printf(format, precision, my_xstrtod(argument));
} else { } else {
if (precision < 0) if (precision < 0)
printf(p, field_width, my_xstrtod(argument)); printf(format, field_width, my_xstrtod(argument));
else else
printf(p, field_width, precision, my_xstrtod(argument)); printf(format, field_width, precision, my_xstrtod(argument));
} }
break; break;
case 'c': case 'c':
printf(p, *argument); printf(format, *argument);
break; break;
case 's': case 's':
if (field_width < 0) { if (field_width < 0) {
if (precision < 0) if (precision < 0)
printf(p, argument); printf(format, argument);
else else
printf(p, precision, argument); printf(format, precision, argument);
} else { } else {
if (precision < 0) if (precision < 0)
printf(p, field_width, argument); printf(format, field_width, argument);
else else
printf(p, field_width, precision, argument); printf(format, field_width, precision, argument);
} }
break; break;
} }
free(p); format[fmt_length] = saved;
} }
/* Print the text in FORMAT, using ARGV for arguments to any '%' directives. /* Print the text in FORMAT, using ARGV for arguments to any '%' directives.
Return advanced ARGV. */ Return advanced ARGV. */
static char **print_formatted(char *format, char **argv) static char **print_formatted(char *f, char **argv)
{ {
char *f; /* Pointer into 'format'. */
char *direc_start; /* Start of % directive. */ char *direc_start; /* Start of % directive. */
size_t direc_length; /* Length of % directive. */ unsigned direc_length; /* Length of % directive. */
int field_width; /* Arg to first '*', or -1 if none. */ int field_width; /* Arg to first '*', or -1 if none. */
int precision; /* Arg to second '*', or -1 if none. */ int precision; /* Arg to second '*', or -1 if none. */
for (f = format; *f; ++f) { for (; *f; ++f) {
switch (*f) { switch (*f) {
case '%': case '%':
direc_start = f++; direc_start = f++;