[PATCH] bc Version 1.1
Denys Vlasenko
vda.linux at googlemail.com
Mon Dec 3 18:02:39 UTC 2018
On Mon, Dec 3, 2018 at 6:49 PM Denys Vlasenko <vda.linux at googlemail.com> wrote:
> On Sat, Nov 3, 2018 at 6:17 PM Gavin Howard <gavin.d.howard at gmail.com> wrote:
> > After making changes to the bc for Denys' requests, I have a better
> > version of the bc.
> >
> > This version, pasted at https://pastebin.com/0M9sMhtM and raw at
> > https://pastebin.com/raw/0M9sMhtM, has fulfilled every one of Denys'
> > requests except for a few.
>
> +static BcStatus bc_lex_comment(BcLex *l)
> +{
> + size_t i, nls = 0;
> + const char *buf = l->buf;
> + bool end = false;
> + char c;
> +
> + l->t.t = BC_LEX_WHITESPACE;
> +
> + for (i = ++l->i; !end; i += !end) {
> +
> + for (c = buf[i]; c != '*' && c != 0; c = buf[++i]) nls += (c == '\n');
> +
> + if (c == 0 || buf[i + 1] == '\0') {
> + l->i = i;
> + return BC_STATUS_LEX_NO_COMMENT_END;
> + }
> +
> + end = buf[i + 1] == '/';
> + }
> This is rather unreadable.
After untangling unreadable for() statements and 'end' variable,
this is what it actually does:
{
size_t i, nls = 0;
const char *buf = l->buf;
l->t.t = BC_LEX_WHITESPACE;
i = ++l->i;
for (;;) {
for (;;) {
char c = buf[i];
if (c == '*')
break;
if (c == '\0') {
l->i = i;
return BC_STATUS_LEX_NO_COMMENT_END;
}
nls += (c == '\n');
i++;
}
i++;
if (buf[i] == '\0') {
l->i = i - 1;
return BC_STATUS_LEX_NO_COMMENT_END;
}
if (buf[i] == '/')
break;
}
and now, since inner for() has only one break, I can put
'/' check directly there, eliminating one for() altogether:
for (;;) {
char c = buf[i];
check_star:
if (c == '*') {
c = buf[++i];
if (c == '/')
break;
goto check_star;
}
if (c == '\0') {
l->i = i;
return BC_STATUS_LEX_NO_COMMENT_END;
}
nls += (c == '\n');
i++;
}
Now l->i on error might be different (+1) but this is likely should be that way.
More information about the busybox
mailing list