bc: shrink zdc_lex_string()

This actually fixes a rather obscure bug. This was failing to find
end of the string:

	$ echo -n '[foo]' | dc
	dc: string end could not be found

function                                             old     new   delta
zbc_lex_next                                        2230    2141     -89
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-89)             Total: -89 bytes
   text	   data	    bss	    dec	    hex	filename
 981461	    485	   7296	 989242	  f183a	busybox_old
 981372	    485	   7296	 989153	  f17e1	busybox_unstripped

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2018-12-18 13:48:37 +01:00
parent d4258dd321
commit ef271da33f

View File

@ -3272,25 +3272,31 @@ static BC_STATUS zdc_lex_register(BcLex *l)
static BC_STATUS zdc_lex_string(BcLex *l)
{
size_t depth = 1, nls = 0, i = l->i;
char c;
size_t depth, nls, i;
l->t.t = BC_LEX_STR;
bc_vec_pop_all(&l->t.v);
for (c = l->buf[i]; c != 0 && depth; c = l->buf[++i]) {
depth += (c == '[' && (i == l->i || l->buf[i - 1] != '\\'));
depth -= (c == ']' && (i == l->i || l->buf[i - 1] != '\\'));
nls = 0;
depth = 1;
i = l->i;
for (;;) {
char c = l->buf[i];
if (c == '\0') {
l->i = i;
RETURN_STATUS(bc_error("string end could not be found"));
}
nls += (c == '\n');
if (depth) bc_vec_push(&l->t.v, &c);
}
if (c == '\0') {
l->i = i;
RETURN_STATUS(bc_error("string end could not be found"));
if (i == l->i || l->buf[i - 1] != '\\') {
if (c == '[') depth++;
if (c == ']')
if (--depth == 0)
break;
}
bc_vec_push(&l->t.v, &l->buf[i]);
i++;
}
i++;
bc_vec_pushZeroByte(&l->t.v);
// This check makes sense only if size_t is (much) larger than BC_MAX_STRING.