Add a command-line option for printing leading zeros

This was also requested by depler on GitHub. It took a bit of
refactoring, but it actually wasn't bad.

Later, I will add functions to the extended math library to either print
the leading zero for certain numbers, or not. To do that, I am going to
add builtin functions to query the global state. It makes sense to do so
since I already have other builtin functions for global state.

Signed-off-by: Gavin Howard <gavin@yzena.com>
line_libs
Gavin Howard 1 year ago
parent 7ae40616ec
commit a5e62d4e95
Signed by: gavin
GPG Key ID: C08038BDF280D33E
  1. 12
      include/vm.h
  2. 6
      src/args.c
  3. 1
      src/data.c
  4. 16
      src/num.c
  5. 12
      tests/other.sh

@ -164,14 +164,17 @@
/// The flag for read prompt. This is also reversed; the option clears the flag.
#define BC_FLAG_R (UINTMAX_C(1)<<8)
/// The flag for a leading zero.
#define BC_FLAG_Z (UINTMAX_C(1)<<9)
/// The flag for stdin being a TTY.
#define BC_FLAG_TTYIN (UINTMAX_C(1)<<9)
#define BC_FLAG_TTYIN (UINTMAX_C(1)<<10)
/// The flag for TTY mode.
#define BC_FLAG_TTY (UINTMAX_C(1)<<10)
#define BC_FLAG_TTY (UINTMAX_C(1)<<11)
/// The flag for reset on SIGINT.
#define BC_FLAG_SIGINT (UINTMAX_C(1)<<11)
#define BC_FLAG_SIGINT (UINTMAX_C(1)<<12)
/// A convenience macro for getting the TTYIN flag.
#define BC_TTYIN (vm.flags & BC_FLAG_TTYIN)
@ -214,6 +217,9 @@
/// A convenience macro for getting the read prompt flag.
#define BC_R (vm.flags & BC_FLAG_R)
/// A convenience macro for getting the leading zero flag.
#define BC_Z (vm.flags & BC_FLAG_Z)
#if BC_ENABLED
/// A convenience macro for checking if bc is in POSIX mode.

@ -171,6 +171,12 @@ void bc_args(int argc, char *argv[], bool exit_exprs) {
break;
}
case 'z':
{
vm.flags |= BC_FLAG_Z;
break;
}
case 'C':
{
vm.line_len = 0;

@ -141,6 +141,7 @@ const BcOptLong bc_args_lopt[] = {
{ "file", BC_OPT_REQUIRED, 'f' },
{ "help", BC_OPT_NONE, 'h' },
{ "interactive", BC_OPT_NONE, 'i' },
{ "leading-zero", BC_OPT_NONE, 'z' },
{ "no-char-limit", BC_OPT_NONE, 'C' },
{ "no-prompt", BC_OPT_NONE, 'P' },
{ "no-read-prompt", BC_OPT_NONE, 'R' },

@ -2475,9 +2475,6 @@ static void bc_num_printDecimal(const BcNum *restrict n, bool newline) {
bool zero = true;
size_t buffer[BC_BASE_DIGS];
// Print the sign.
if (BC_NUM_NEG(n)) bc_num_putchar('-', true);
// Print loop.
for (i = n->len - 1; i < n->len; --i) {
@ -2975,9 +2972,6 @@ static void bc_num_printBase(BcNum *restrict n, BcBigDig base, bool newline) {
BcNumDigitOp print;
bool neg = BC_NUM_NEG(n);
// Just take care of the sign right here.
if (neg) bc_num_putchar('-', true);
// Clear the sign because it makes the actual printing easier when we have
// to do math.
BC_NUM_NEG_CLR(n);
@ -3145,6 +3139,16 @@ void bc_num_print(BcNum *restrict n, BcBigDig base, bool newline) {
// We may need a newline, just to start.
bc_num_printNewline();
if (BC_NUM_NONZERO(n)) {
// Print the sign.
if (BC_NUM_NEG(n)) bc_num_putchar('-', true);
// Print the leading zero if necessary.
if (BC_Z && BC_NUM_RDX_VAL(n) == n->len)
bc_num_printHex(0, 1, false, !newline);
}
// Short-circuit 0.
if (BC_NUM_ZERO(n)) bc_num_printHex(0, 1, false, !newline);
else if (base == BC_BASE) bc_num_printDecimal(n, newline);

@ -287,6 +287,18 @@ checktest_retcode "$d" "$?" "arg"
printf '%s\n' "$halt" | "$exe" "$@" -V > /dev/null
checktest_retcode "$d" "$?" "arg"
out=$(printf '0.1\n-0.1\n1.1\n-1.1\n0.1\n-0.1\n')
printf '%s\n' "$out" > "$out1"
if [ "$d" = "bc" ]; then
data=$(printf '0.1\n-0.1\n1.1\n-1.1\n.1\n-.1\n')
else
data=$(printf '0.1pR\n_0.1pR\n1.1pR\n_1.1pR\n.1pR\n_.1pR\n')
fi
printf '%s\n' "$data" | "$exe" "$@" -z > "$out2"
checktest "$d" "$?" "leading zero" "$out1" "$out2"
"$exe" "$@" -f "saotehasotnehasthistohntnsahxstnhalcrgxgrlpyasxtsaosysxsatnhoy.txt" > /dev/null 2> "$out2"
err="$?"

Loading…
Cancel
Save