bc: code shrink in zbc_lex_number()
function old new delta zbc_lex_number 279 190 -89 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
b402ff844c
commit
c355c4a7d6
@ -2976,29 +2976,40 @@ static void bc_lex_whitespace(BcLex *l)
|
|||||||
static BC_STATUS zbc_lex_number(BcLex *l, char start)
|
static BC_STATUS zbc_lex_number(BcLex *l, char start)
|
||||||
{
|
{
|
||||||
const char *buf = l->buf + l->i;
|
const char *buf = l->buf + l->i;
|
||||||
size_t len, hits = 0, bslashes = 0, i = 0, j;
|
size_t len, bslashes, i, ccnt;
|
||||||
char c = buf[i];
|
bool pt;
|
||||||
bool last_pt, pt = start == '.';
|
|
||||||
|
|
||||||
last_pt = pt;
|
pt = (start == '.');
|
||||||
l->t.t = BC_LEX_NUMBER;
|
l->t.t = BC_LEX_NUMBER;
|
||||||
|
bslashes = 0;
|
||||||
while (c != 0 && (isdigit(c) || (c >= 'A' && c <= 'F') ||
|
ccnt = i = 0;
|
||||||
(c == '.' && !pt) || (c == '\\' && buf[i + 1] == '\n')))
|
for (;;) {
|
||||||
{
|
char c = buf[i];
|
||||||
if (c != '\\') {
|
if (c == '\0')
|
||||||
last_pt = c == '.';
|
break;
|
||||||
pt = pt || last_pt;
|
if (c == '\\' && buf[i + 1] == '\n') {
|
||||||
|
i += 2;
|
||||||
|
bslashes++;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
if (!isdigit(c) && (c < 'A' || c > 'F')) {
|
||||||
++i;
|
if (c != '.') break;
|
||||||
bslashes += 1;
|
// if '.' was already seen, stop on second one:
|
||||||
|
if (pt) break;
|
||||||
|
pt = 1;
|
||||||
}
|
}
|
||||||
|
// buf[i] is one of "0-9A-F."
|
||||||
c = buf[++i];
|
i++;
|
||||||
|
if (c != '.')
|
||||||
|
ccnt = i;
|
||||||
}
|
}
|
||||||
|
//i is buf[i] index of the first not-yet-parsed char
|
||||||
|
l->i += i;
|
||||||
|
|
||||||
|
//ccnt is the number of chars in the number string, excluding possible
|
||||||
|
//trailing "." and possible following trailing "\<newline>"(s).
|
||||||
|
len = ccnt - bslashes * 2 + 1; // +1 byte for NUL termination
|
||||||
|
|
||||||
len = i + !last_pt - bslashes * 2;
|
|
||||||
// This check makes sense only if size_t is (much) larger than BC_MAX_NUM.
|
// This check makes sense only if size_t is (much) larger than BC_MAX_NUM.
|
||||||
if (SIZE_MAX > (BC_MAX_NUM | 0xff)) {
|
if (SIZE_MAX > (BC_MAX_NUM | 0xff)) {
|
||||||
if (len > BC_MAX_NUM)
|
if (len > BC_MAX_NUM)
|
||||||
@ -3006,26 +3017,23 @@ static BC_STATUS zbc_lex_number(BcLex *l, char start)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bc_vec_pop_all(&l->t.v);
|
bc_vec_pop_all(&l->t.v);
|
||||||
bc_vec_expand(&l->t.v, len + 1);
|
bc_vec_expand(&l->t.v, 1 + len);
|
||||||
bc_vec_push(&l->t.v, &start);
|
bc_vec_push(&l->t.v, &start);
|
||||||
|
|
||||||
for (buf -= 1, j = 1; j < len + hits * 2; ++j) {
|
while (ccnt != 0) {
|
||||||
|
|
||||||
c = buf[j];
|
|
||||||
|
|
||||||
// If we have hit a backslash, skip it. We don't have
|
// If we have hit a backslash, skip it. We don't have
|
||||||
// to check for a newline because it's guaranteed.
|
// to check for a newline because it's guaranteed.
|
||||||
if (hits < bslashes && c == '\\') {
|
if (*buf == '\\') {
|
||||||
++hits;
|
buf += 2;
|
||||||
++j;
|
ccnt -= 2;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
bc_vec_push(&l->t.v, buf);
|
||||||
bc_vec_push(&l->t.v, &c);
|
buf++;
|
||||||
|
ccnt--;
|
||||||
}
|
}
|
||||||
|
|
||||||
bc_vec_pushZeroByte(&l->t.v);
|
bc_vec_pushZeroByte(&l->t.v);
|
||||||
l->i += i;
|
|
||||||
|
|
||||||
RETURN_STATUS(BC_STATUS_SUCCESS);
|
RETURN_STATUS(BC_STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user