[Toybox] Graff and bc

Rob Landley rob at landley.net
Tue Mar 13 07:22:28 PDT 2018


On 03/12/2018 08:41 PM, Rob Landley wrote:> They're both intentionally small and simple, with descriptions in the commit
> messages. I'll just post the third one to the list...

Next pass, net deletion of 72 lines.

landley at driftwood:~/toybox/toy3$ git diff toys/*/bc.c | diffstat
 bc.c |  174 +++++++++++++++++++------------------------------------------------
 1 file changed, 51 insertions(+), 123 deletions(-)

Remove the globals bc_code, bc_std, and bc_warn. Just test toys.optflags
directly at the users instead.

Remove the redundant struct BcGlobals and use the generated struct bc_data
from generated/globals.h

Inline BC_NUM_ZERO(n) which is just !n->len

BC_NUM_POS_ONE() is only used once and BC_NUM_NEG_ONE() is never used,
inline the first, delete the second.

Toybox is built with -funsigned-char, so we don't have to say "unsigned char".
(Avoids spurious type collisions/casts.)

Remove "const" wherever it requires a gratuitous typecast, follow the chain
back removing "const" until the types stop complaining.

Inline bc_vm_init() and bc_exec() since each is only called once.

Set toys.exitval directly instead of having an intermediate "status" variable.
(In a future pass this can probably be inlined into the called functions.)

This little trick:

-  if (line) fprintf(stderr, ":%d\n\n", line);
-  else fprintf(stderr, "\n\n");
+  fprintf(stderr, ":%d\n\n"+3*!line, line);

STDIN_FILENO and STDOUT_FILENO have been 0 and 1 respectively since 1969.

todo: work out if bc_program_free() and bc_program_free() actually do anything
other than free memory (which gets freed automatically when we exit). If
so, they're if (CFG_TOYBOX_FREE) calls at best.

diff --git a/toys/pending/bc.c b/toys/pending/bc.c
index bd48b02..3ee9705 100644
--- a/toys/pending/bc.c
+++ b/toys/pending/bc.c
@@ -40,10 +40,7 @@ config BC
 #include "toys.h"
 
 GLOBALS(
-    long bc_code;
     long bc_interactive;
-    long bc_std;
-    long bc_warn;
 
     long bc_signal;
 )
@@ -143,18 +140,6 @@ typedef enum BcStatus {
 typedef void (*BcFreeFunc)(void*);
 typedef BcStatus (*BcCopyFunc)(void*, void*);
 
-// ** Exclude start.
-typedef struct BcGlobals {
-
-  long bc_code;
-  long bc_interactive;
-  long bc_std;
-  long bc_warn;
-
-  long bc_signal;
-
-} BcGlobals;
-
 void bc_error(BcStatus status);
 void bc_error_file(BcStatus status, const char *file, uint32_t line);
 
@@ -209,13 +194,8 @@ typedef struct BcNum {
 
 #define BC_NUM_PRINT_WIDTH (69)
 
-#define BC_NUM_ZERO(n) (!(n)->len)
-
 #define BC_NUM_ONE(n) ((n)->len == 1 && (n)->rdx == 0 && (n)->num[0] == 1)
 
-#define BC_NUM_POS_ONE(n) (BC_NUM_ONE(n) && !(n)->neg)
-#define BC_NUM_NEG_ONE(n) (BC_NUM_ONE(n) && (n)->neg)
-
 typedef BcStatus (*BcNumUnaryFunc)(BcNum*, BcNum*, size_t);
 typedef BcStatus (*BcNumBinaryFunc)(BcNum*, BcNum*, BcNum*, size_t);
 
@@ -579,7 +559,7 @@ typedef struct BcLex {
 typedef struct BcLexKeyword {
 
   const char name[9];
-  const unsigned char len;
+  const char len;
   const bool posix;
 
 } BcLexKeyword;
@@ -758,7 +738,7 @@ typedef struct BcVm {
   BcParse parse;
 
   int filec;
-  const char** filev;
+  char **filev;
 
 } BcVm;
 
@@ -1169,7 +1149,7 @@ const char *bc_program_ready_prompt = "ready for more input\n\n";
 const char *bc_program_sigint_msg = "\n\ninterrupt (type \"quit\" to exit)\n\n";
 const char *bc_lib_name = "lib.bc";
 
-const unsigned char bc_lib[] = {
+const char bc_lib[] = {
   115,99,97,108,101,61,50,48,10,100,101,102,105,110,101,32,101,40,120,41,123,
   10,9,97,117,116,111,32,98,44,115,44,110,44,114,44,100,44,105,44,112,44,102,
   44,118,10,9,98,61,105,98,97,115,101,10,9,105,98,97,115,101,61,65,10,9,105,102,
@@ -1559,11 +1539,11 @@ int bc_num_compareDigits(BcNum *a, BcNum *b, size_t *digits) {
   }
   else if (b->neg) return 1;
 
-  if (BC_NUM_ZERO(a)) {
+  if (!a->len) {
     cmp = b->neg ? 1 : -1;
-    return BC_NUM_ZERO(b) ? 0 : cmp;
+    return !b->len ? 0 : cmp;
   }
-  else if (BC_NUM_ZERO(b)) return a->neg ? -1 : 1;
+  else if (!b->len) return a->neg ? -1 : 1;
 
   a_int = a->len - a->rdx;
   b_int = b->len - b->rdx;
@@ -1820,12 +1800,12 @@ BcStatus bc_num_alg_s(BcNum *a, BcNum *b, BcNum *c, size_t sub) {
   // I am hijacking it to tell this function whether it is doing an add
   // or a subtract.
 
-  if (BC_NUM_ZERO(a)) {
+  if (!a->len) {
     status = bc_num_copy(c, b);
     c->neg = !b->neg;
     return status;
   }
-  else if (BC_NUM_ZERO(b)) return bc_num_copy(c, a);
+  else if (!b->len) return bc_num_copy(c, a);
 
   aneg = a->neg;
   bneg = b->neg;
@@ -1894,7 +1874,7 @@ BcStatus bc_num_alg_m(BcNum *a, BcNum *b, BcNum *c, size_t scale) {
   size_t j;
   size_t len;
 
-  if (BC_NUM_ZERO(a) || BC_NUM_ZERO(b)) {
+  if (!a->len || !b->len) {
     bc_num_zero(c);
     return BC_STATUS_SUCCESS;
   }
@@ -1960,8 +1940,8 @@ BcStatus bc_num_alg_d(BcNum *a, BcNum *b, BcNum *c, size_t scale) {
   size_t i;
   BcNum copy;
 
-  if (BC_NUM_ZERO(b)) return BC_STATUS_MATH_DIVIDE_BY_ZERO;
-  else if (BC_NUM_ZERO(a)) {
+  if (!b->len) return BC_STATUS_MATH_DIVIDE_BY_ZERO;
+  else if (!a->len) {
     bc_num_zero(c);
     return BC_STATUS_SUCCESS;
   }
@@ -2151,7 +2131,7 @@ BcStatus bc_num_alg_p(BcNum *a, BcNum *b, BcNum *c, size_t scale) {
     bc_num_one(c);
     return BC_STATUS_SUCCESS;
   }
-  else if (BC_NUM_ZERO(a)) {
+  else if (!a->len) {
     bc_num_zero(c);
     return BC_STATUS_SUCCESS;
   }
@@ -2274,11 +2254,12 @@ BcStatus bc_num_sqrt_newton(BcNum *a, BcNum *b, size_t scale) {
   size_t resrdx;
   int cmp;
 
-  if (BC_NUM_ZERO(a)) {
+  if (!a->len) {
     bc_num_zero(b);
     return BC_STATUS_SUCCESS;
   }
-  else if (BC_NUM_POS_ONE(a)) {
+  else if (BC_NUM_ONE(a) && !a->neg) {
+
     bc_num_one(b);
     return bc_num_extend(b, scale);
   }
@@ -2864,7 +2845,7 @@ BcStatus bc_num_printBase(BcNum *n, BcNum *base, size_t base_t, FILE* f) {
 
   if (status) goto frac_len_err;
 
-  while (!BC_NUM_ZERO(&intp)) {
+  while (intp.len) {
 
     unsigned long dig;
 
@@ -3066,7 +3047,7 @@ BcStatus bc_num_fprint(BcNum *n, BcNum *base, size_t base_t,
   if (base_t < BC_NUM_MIN_BASE || base_t > BC_NUM_MAX_OUTPUT_BASE)
     return BC_STATUS_EXEC_INVALID_OBASE;
 
-  if (BC_NUM_ZERO(n)) {
+  if (!n->len) {
     if (fputc('0', f) == EOF) return BC_STATUS_IO_ERR;
     status = BC_STATUS_SUCCESS;
   }
@@ -8759,7 +8740,7 @@ BcStatus bc_vm_execFile(BcVm *vm, int idx) {
   char *data;
   BcProgramExecFunc exec;
 
-  exec = TT.bc_code ? bc_program_print : bc_program_exec;
+  exec = (toys.optflags&FLAG_i) ? bc_program_print : bc_program_exec;
 
   file = vm->filev[idx];
   vm->program.file = file;
@@ -9050,7 +9031,7 @@ BcStatus bc_vm_execStdin(BcVm *vm) {
 
     if (BC_PARSE_CAN_EXEC(&vm->parse)) {
 
-      if (!TT.bc_code) {
+      if (!(toys.optflags&FLAG_i)) {
 
         status = bc_program_exec(&vm->program);
 
@@ -9113,33 +9094,6 @@ buf_err:
   return status;
 }
 
-BcStatus bc_vm_init(BcVm *vm, int filec, const char *filev[]) {
-
-  BcStatus status;
-  struct sigaction act;
-
-  sigemptyset(&act.sa_mask);
-  act.sa_handler = bc_vm_sigint;
-
-  if (sigaction(SIGINT, &act, NULL) < 0) return BC_STATUS_EXEC_SIGACTION_FAIL;
-
-  status = bc_program_init(&vm->program);
-
-  if (status) return status;
-
-  status = bc_parse_init(&vm->parse, &vm->program);
-
-  if (status) {
-    bc_program_free(&vm->program);
-    return status;
-  }
-
-  vm->filec = filec;
-  vm->filev = filev;
-
-  return BC_STATUS_SUCCESS;
-}
-
 void bc_vm_free(BcVm *vm) {
   bc_parse_free(&vm->parse);
   bc_program_free(&vm->program);
@@ -9206,92 +9160,66 @@ void bc_error_file(BcStatus status, const char *file, uint32_t line) {
           bc_err_descs[status]);
 
   fprintf(stderr, "    %s", file);
-
-  if (line) fprintf(stderr, ":%d\n\n", line);
-  else fprintf(stderr, "\n\n");
+  fprintf(stderr, ":%d\n\n"+3*!line, line);
 }
 
 BcStatus bc_posix_error(BcStatus status, const char *file,
                         uint32_t line, const char *msg)
 {
-  if (!(TT.bc_std || TT.bc_warn) ||
-      status < BC_STATUS_POSIX_NAME_LEN ||
-      !file)
-  {
+  int s = toys.optflags & FLAG_s, w = toys.optflags & FLAG_w;
+
+  if (!(s || w) || status<BC_STATUS_POSIX_NAME_LEN || !file)
     return BC_STATUS_SUCCESS;
-  }
 
   fprintf(stderr, "\n%s %s: %s\n", bc_err_types[status],
-          TT.bc_std ? "error" : "warning", bc_err_descs[status]);
+          s ? "error" : "warning", bc_err_descs[status]);
 
   if (msg) fprintf(stderr, "    %s\n", msg);
 
   fprintf(stderr, "    %s", file);
+  fprintf(stderr, ":%d\n\n"+3*!line, line);
 
-  if (line) fprintf(stderr, ":%d\n\n", line);
-  else fprintf(stderr, "\n\n");
-
-  return TT.bc_std ? status : BC_STATUS_SUCCESS;
+  return status*!!s;
 }
 
-BcStatus bc_exec(unsigned int flags, unsigned int filec, const char *filev[]) {
-
-  BcStatus status;
+void bc_main(void)
+{
+  struct sigaction act;
   BcVm vm;
 
-  if ((flags & FLAG_i) || (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO))) {
-    TT.bc_interactive = 1;
-  } else TT.bc_interactive = 0;
+  TT.bc_interactive = (toys.optflags & FLAG_i) || (isatty(0) && isatty(1));
 
-  TT.bc_code = flags & FLAG_i;
-  TT.bc_std = flags & FLAG_s;
-  TT.bc_warn = flags & FLAG_w;
+  if (!(toys.optflags & FLAG_q) && (toys.exitval = bc_print_version())) return;
 
-  if (!(flags & FLAG_q)) {
-
-    status = bc_print_version();
-
-    if (status) return status;
+  sigemptyset(&act.sa_mask);
+  act.sa_handler = bc_vm_sigint;
+  if (sigaction(SIGINT, &act, NULL) < 0) {
+    toys.exitval = BC_STATUS_EXEC_SIGACTION_FAIL;
+    return;
+  }
+  if ((toys.exitval = bc_program_init(&vm.program))) return;
+  if ((toys.exitval = bc_parse_init(&vm.parse, &vm.program))) {
+    bc_program_free(&vm.program);
+    return;
   }
 
-  status = bc_vm_init(&vm, filec, filev);
-
-  if (status) return status;
-
-  if (flags & FLAG_l) {
-
-    status = bc_parse_file(&vm.parse, bc_lib_name);
-
-    if (status) goto err;
-
-    status = bc_parse_text(&vm.parse, (const char*) bc_lib);
-
-    if (status) goto err;
+  vm.filec = toys.optc;
+  vm.filev = toys.optargs;
 
-    while (!status) status = bc_parse_parse(&vm.parse);
+  if (toys.optflags & FLAG_l) {
+    if ((toys.exitval = bc_parse_file(&vm.parse, bc_lib_name))
+        || (toys.exitval = bc_parse_text(&vm.parse, bc_lib))) goto err;
+    do toys.exitval = bc_parse_parse(&vm.parse); while (!toys.exitval);
 
-    if (status != BC_STATUS_LEX_EOF && status != BC_STATUS_PARSE_EOF) goto err;
+    if (toys.exitval!=BC_STATUS_LEX_EOF && toys.exitval!=BC_STATUS_PARSE_EOF)
+      goto err;
 
     // Make sure to execute the math library.
-    status = bc_program_exec(&vm.program);
-
-    if (status) goto err;
+    if ((toys.exitval = bc_program_exec(&vm.program))) goto err;
   }
 
-  status = bc_vm_exec(&vm);
+  toys.exitval = bc_vm_exec(&vm);
 
 err:
-
   bc_vm_free(&vm);
-
-  return status;
-}
-
-void bc_main(void) {
-
-  unsigned int flags;
-
-  flags = (unsigned int) toys.optflags;
-
-  toys.exitval = (char) bc_exec(flags, toys.optc, (const char**) toys.optargs);
 }



More information about the Toybox mailing list