[PATCH] bc Version 1.1

Denys Vlasenko vda.linux at googlemail.com
Fri Nov 30 20:09:01 UTC 2018


On Sat, Nov 3, 2018 at 6:17 PM Gavin Howard <gavin.d.howard at gmail.com> wrote:
> Hello,
>
> 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.
>
> First, I still did not use read_line_input. The reason for this is
> because bc_read_line does some important error checking. I did,
> however, #if guard signal handling and add a config for it. And I made
> my signal handling function less buggy (in a single-threaded
> environment).
>
> I used getopt32 (and getopt32long behind a config option). I changed
> CONFIG_foo to ENABLE_foo. I made everything but bc_main and dc_main
> static. I called xmalloc_open_read_close in bc_read_file, but still
> kept error handling.
>
> I also tried to pull nested assignments out where I could, but there
> were a few places where doing so introduced bugs. That said, all of
> them are out (as far as I can tell), unless they could not be, so I
> would not mess with them any further if I were you.
>
> On that note, if you do mess with them, you want the full test suite
> while reviewing this code, which you can get by cloning my repo at
> https://github.com/gavinhoward/bc and then run the following commands:
>
> $ $BC_ROOT/tests/all.sh bc $BUSYBOX_ROOT/busybox bc
> $ $BC_ROOT/tests/all.sh dc $BUSYBOX_ROOT/busybox dc
>
> If you also want to test the Linux kernel timeconst script, you can run:
>
> $ $BC_ROOT/tests/bc/timeconst.sh ./path/to/timeconst.bc
> $BUSYBOX_ROOT/busybox bc
>
> I changed my code to call xmalloc and friends, which is actually what
> allowed me to pull out assignments. The code ended up *much* smaller
> than what I have already given to Landley for toybox, so I tried
> pulling them out, and when I did, the code was *still* smaller. We'll
> hope that is good enough for him. Also, because of clang-format, I was
> able to change the braces in my release script, thus making it work
> for both toybox and busybox.
>
> With that said, after testing this thing as hard as I can, I am
> supremely confident in it, and I believe that, barring any small bugs,
> it is feature-complete and basically finished.

Sorry for the delay in reviewing.

Let's take a look at bc_vm_printf(). Basically:
        bad = vfprintf(f, fmt, args) < 0;
        if (bad) bc_vm_exit(BC_STATUS_IO_ERR);

What does bc_vm_exit() do? -
static void bc_vm_exit(BcStatus s) {
        bc_vm_printf(stderr, bc_err_fmt, bc_errs[bc_err_ids[s]],
bc_err_msgs[s]);
        exit((int) s);
}

This would enter infinite loop if you bc_vm_printf(stderr) and meet IO error.


> $ $BC_ROOT/tests/all.sh bc $BUSYBOX_ROOT/busybox bc

Trying.... does this output means tests failed or succeeded?? -

Running bc limits tests...


BC_BASE_MAX     = 999
BC_DIM_MAX      = 2147483647
BC_SCALE_MAX    = 4294967295
BC_STRING_MAX   = 4294967294
BC_NAME_MAX     = 4294967294
BC_NUM_MAX      = 4294967294
Max Exponent    = 2147483647
Number of Vars  = 4294967294


Running bc tests...

Running bc decimal...
Running bc add...
Running bc subtract...
Running bc multiply...
Running bc divide...
Running bc modulus...
Running bc power...
Running bc sqrt...
Running bc vars...
Running bc boolean...
Running bc strings...
Generating bc parse...
Generating bc parse results...
Running bc parse...
Generating bc print...
Generating bc print results...
Running bc print...
Running bc exponent...
Running bc log...
Running bc pi...
Running bc arctangent...
Running bc sine...
Running bc cosine...
Generating bc bessel...
Generating bc bessel results...
(standard_in) 1: syntax error
Running bc bessel...
Running bc arrays...
Running bc misc...
Running bc misc1...
Running bc misc2...
Running bc script: array.bc
Running bc script: atan.bc
Running bc script: bessel.bc
Running bc script: parse.bc
Running bc script: print.bc
Running bc script: screen.bc
Running errors...

Lex error: bad character
    <stdin>:1


Lex error: bad character
    <stdin>:1


Lex error: bad character
    <stdin>:1


Lex error: bad character
    <stdin>:1


Lex error: bad character
    <stdin>:1


Lex error: bad character
    <stdin>:1


Lex error: string end could not be found
    <stdin>:1


Lex error: comment end could not be found
    <stdin>:1


Lex error: bad character
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: empty expression
    <stdin>:1


Parse error: empty expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad assignment: left side must be scale, ibase, obase,
last, var, or array element
    <stdin>:1


Parse error: bad assignment: left side must be scale, ibase, obase,
last, var, or array element
    <stdin>:1


Parse error: bad assignment: left side must be scale, ibase, obase,
last, var, or array element
    <stdin>:1


Parse error: bad assignment: left side must be scale, ibase, obase,
last, var, or array element
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad function definition
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Runtime error: variable is wrong type
    <stdin>


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: function parameter or auto var has the same name as another
    <stdin>:1


Parse error: function parameter or auto var has the same name as another
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad function definition
    <stdin>:1


Parse error: bad function definition
    <stdin>:1


Parse error: bad function definition
    <stdin>:1


Parse error: bad function definition
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad assignment: left side must be scale, ibase, obase,
last, var, or array element
    <stdin>:1


Parse error: bad assignment: left side must be scale, ibase, obase,
last, var, or array element
    <stdin>:1


Parse error: bad assignment: left side must be scale, ibase, obase,
last, var, or array element
    <stdin>:1


Parse error: bad assignment: left side must be scale, ibase, obase,
last, var, or array element
    <stdin>:1


Parse error: bad assignment: left side must be scale, ibase, obase,
last, var, or array element
    <stdin>:1


Parse error: bad assignment: left side must be scale, ibase, obase,
last, var, or array element
    <stdin>:1


Parse error: bad assignment: left side must be scale, ibase, obase,
last, var, or array element
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Math error: overflow
    <stdin>


Runtime error: mismatched parameters
    <stdin>


Runtime error: variable is wrong type
    <stdin>


Runtime error: undefined function
    <stdin>


Parse error: bad token
    <stdin>:1


Math error: overflow
    <stdin>


Math error: overflow
    <stdin>


Math error: overflow
    <stdin>


Lex error: bad character
    <stdin>:1


Math error: negative number
    <stdin>


Math error: negative number
    <stdin>


Math error: divide by zero
    <stdin>


Math error: divide by zero
    <stdin>


Math error: divide by zero
    <stdin>


Math error: divide by zero
    <stdin>


Math error: divide by zero
    <stdin>


Math error: divide by zero
    <stdin>


Math error: overflow
    <stdin>


Math error: overflow
    <stdin>


Math error: overflow
    <stdin>


Math error: overflow
    <stdin>


Math error: overflow
    <stdin>


Math error: divide by zero
    <stdin>


Math error: non integer number
    <stdin>


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Runtime error: variable is wrong type
    <stdin>


Runtime error: variable is wrong type
    <stdin>


Runtime error: variable is wrong type
    <stdin>


Runtime error: variable is wrong type
    <stdin>


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad expression
    <stdin>:1


Parse error: bad print statement
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad function definition
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Parse error: bad token
    <stdin>:1


Math error: divide by zero
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Math error: bad number string
    <stdin>


Lex error: bad character
    <stdin>:1


Lex error: bad character
    <stdin>:1


VM error: I/O error
    <stdin>


POSIX warning: POSIX does not allow the following keyword:
    last
    <stdin>:1

Running posix_errors...

Vector error: POSIX only allows one character names; the following is bad:
    aa = 0

    <stdin>:1


POSIX error: POSIX does not allow '#' script comments
    <stdin>:1


POSIX error: POSIX does not allow the following keyword:
    continue
    <stdin>:1


POSIX error: POSIX does not allow the following keyword:
    last
    <stdin>:1


POSIX error: POSIX does not allow the following keyword:
    print
    <stdin>:1


POSIX error: POSIX does not allow the following keyword:
    halt
    <stdin>:1


POSIX error: POSIX requires parentheses around return expressions
    <stdin>:1


POSIX error: POSIX requires parentheses around return expressions
    <stdin>:1


POSIX error: POSIX requires parentheses around return expressions
    <stdin>:1


POSIX error: POSIX does not allow the following keyword:
    limits
    <stdin>:1


POSIX error: POSIX does not allow a period ('.') as a shortcut for the
last result
    <stdin>:1


POSIX error: POSIX does not allow the following keyword:
    else
    <stdin>:1


POSIX error: POSIX does not allow comparison operators outside if or loops
    <stdin>:1


POSIX error: POSIX does not allow boolean operators; the following is bad:
    &&
    <stdin>:1


POSIX error: POSIX does not allow boolean operators; the following is bad:
    ||
    <stdin>:1


POSIX error: POSIX does not allow boolean operators; the following is bad:
    !
    <stdin>:1


POSIX error: POSIX does not allow an empty init expression in a for loop
    <stdin>:1


POSIX error: POSIX does not allow an empty condition expression in a for loop
    <stdin>:1


POSIX error: POSIX does not allow an empty update expression in a for loop
    <stdin>:1


POSIX error: POSIX does not allow an empty condition expression in a for loop
    <stdin>:1


POSIX error: POSIX does not allow an empty init expression in a for loop
    <stdin>:1


POSIX error: POSIX does not allow an empty init expression in a for loop
    <stdin>:1


POSIX error: POSIX does not allow an empty init expression in a for loop
    <stdin>:1

Running error file tests/bc/errors/01.txt...

Parse error: bad assignment: left side must be scale, ibase, obase,
last, var, or array element
    tests/bc/errors/01.txt:349

Running error file tests/bc/errors/01.txt through cat...
Running error file tests/bc/errors/02.txt...

VM error: file is not text:
    tests/bc/errors/02.txt

Running error file tests/bc/errors/02.txt through cat...
Running error file tests/bc/errors/03.txt...

Parse error: bad expression
    tests/bc/errors/03.txt:2

Running error file tests/bc/errors/03.txt through cat...
Running error file tests/bc/errors/04.txt...

Lex error: string end could not be found
    tests/bc/errors/04.txt:1

Running error file tests/bc/errors/04.txt through cat...
Running error file tests/bc/errors/05.txt...

Lex error: comment end could not be found
    tests/bc/errors/05.txt:1

Running error file tests/bc/errors/05.txt through cat...
Running error file tests/bc/errors/06.txt...

Parse error: bad token
    <stdin>:2

Running error file tests/bc/errors/06.txt through cat...

Running quit test...


More information about the busybox mailing list