bc: speed up string printing, fix print ""

function                                             old     new   delta
static.esc                                             -       9      +9
zxc_program_print                                    681     683      +2
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/0 up/down: 11/0)               Total: 11 bytes
   text	   data	    bss	    dec	    hex	filename
 979144	    485	   7296	 986925	  f0f2d	busybox_old
 979062	    485	   7296	 986843	  f0edb	busybox_unstripped

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2019-01-02 05:03:53 +01:00
parent 2231468a2f
commit 266bec8ba7
2 changed files with 28 additions and 44 deletions

View File

@ -5359,7 +5359,7 @@ static char *xc_program_name(char *code, size_t *bgn)
static void xc_program_printString(const char *str) static void xc_program_printString(const char *str)
{ {
#if ENABLE_DC #if ENABLE_DC
if (!str[0]) { if (!str[0] && IS_DC) {
// Example: echo '[]ap' | dc // Example: echo '[]ap' | dc
// should print two bytes: 0x00, 0x0A // should print two bytes: 0x00, 0x0A
bb_putchar('\0'); bb_putchar('\0');
@ -5367,46 +5367,25 @@ static void xc_program_printString(const char *str)
} }
#endif #endif
while (*str) { while (*str) {
int c = *str++; char c = *str++;
if (c != '\\' || !*str) if (c == '\\') {
bb_putchar(c); static const char esc[] ALIGN1 = "nabfrt""e\\";
else { char *n;
c = *str++; c = *str++;
switch (c) { n = strchr(esc, c); // note: c can be NUL
case 'a': if (!n) {
bb_putchar('\a'); // Just print the backslash and following character
break;
case 'b':
bb_putchar('\b');
break;
case '\\':
case 'e':
bb_putchar('\\');
break;
case 'f':
bb_putchar('\f');
break;
case 'n':
bb_putchar('\n');
G.prog.nchars = SIZE_MAX;
break;
case 'r':
bb_putchar('\r');
break;
case 'q':
bb_putchar('"');
break;
case 't':
bb_putchar('\t');
break;
default:
// Just print the backslash and following character.
bb_putchar('\\'); bb_putchar('\\');
++G.prog.nchars; ++G.prog.nchars;
bb_putchar(c); } else {
break; if (n - esc == 0) // "\n" ?
G.prog.nchars = SIZE_MAX;
c = "\n\a\b\f\r\t""\\\\""\\"[n - esc];
// n a b f r t e \ \<end of line>
} }
} }
putchar(c);
++G.prog.nchars; ++G.prog.nchars;
} }
} }
@ -5631,16 +5610,15 @@ static BC_STATUS zxc_program_print(char inst, size_t idx)
str = *xc_program_str(idx); str = *xc_program_str(idx);
if (inst == XC_INST_PRINT_STR) { if (inst == XC_INST_PRINT_STR) {
for (;;) { char *nl;
char c = *str++; G.prog.nchars += printf("%s", str);
if (c == '\0') break; nl = strrchr(str, '\n');
bb_putchar(c); if (nl)
++G.prog.nchars; G.prog.nchars = strlen(nl + 1);
if (c == '\n') G.prog.nchars = 0;
}
} else { } else {
xc_program_printString(str); xc_program_printString(str);
if (inst == XC_INST_PRINT) bb_putchar('\n'); if (inst == XC_INST_PRINT)
bb_putchar('\n');
} }
} }

View File

@ -149,6 +149,12 @@ testing "bc (!a&&b)" \
"0\n" \ "0\n" \
"" "(!a&&b)" "" "(!a&&b)"
# check that dc code is not messing this up (no NUL printing!)
testing "bc print \"\"" \
"bc" \
"" \
"" "print \"\""
testing "bc print 1,2,3" \ testing "bc print 1,2,3" \
"bc" \ "bc" \
"123" \ "123" \