RE: [PATCH] Add bc (Last patch)

2018-10-31 Thread dietmar.schindler
> From: busybox  On Behalf Of Gavin Howard
> Sent: Tuesday, October 30, 2018 12:30 AM
>
> On Mon, Oct 29, 2018 at 4:46 PM Denys Vlasenko  
> wrote:
> >
> > On Mon, Oct 29, 2018 at 4:55 PM Gavin Howard  
> > wrote:
> > >...
> > +if (!(v->v = malloc(esize * BC_VEC_START_CAP))) return 
> > BC_STATUS_ALLOC_ERR;
> >
> > (1) Please do not nest assignments:
> >
> > v->v = malloc(esize * BC_VEC_START_CAP);
> > if (!v->v)
> > return BC_STATUS_ALLOC_ERR;
>
> Oh boy. I was afraid of this.
>
> The problem is that I am also trying to get this bc into toybox (might
> as well reduce duplication of effort), and as I am sure you know,
> Landley is very particular about the line count of commands. To be
> honest, I would prefer your style (except for putting if statements
> that on one line if possible), but this reduces line count.
>
> I don't really know what to do here.

If by "nest" is meant "nest in another pair of parentheses", the two 
requirements are accordable:

if (v->v = malloc(esize * BC_VEC_START_CAP), !v->v) ...
--
Regards,
Dietmar Schindler

manroland Goss web systems GmbH | Managing Director: Alexander Wassermann
Registered Office: Augsburg | Trade Register: AG Augsburg | HRB-No.: 32609 | 
VAT: DE815764857

Confidentiality note:
This message and any attached documents may contain confidential or proprietary 
information of manroland|Goss. These materials are intended only for the use of 
the intended recipient. If you are not the intended recipient of this 
transmission, you are hereby notified that any distribution, disclosure, 
printing, copying, storage, modification or the taking of any action in 
reliance upon this transmission is strictly prohibited. Delivery of this 
message to any person other than the intended recipient shall not compromise or 
waive such confidentiality, privilege or exemption from disclosure as to this 
communication. If you have received this communication in error, please 
immediately notify the sender and delete the message from your system. All 
liability for viruses is excluded to the fullest extent permitted by law.

___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [PATCH] Add bc (Last patch)

2018-10-30 Thread Gavin Howard
On Tue, Oct 30, 2018 at 3:32 AM Denys Vlasenko  wrote:
>
> On Tue, Oct 30, 2018 at 12:30 AM Gavin Howard  
> wrote:
> > On Mon, Oct 29, 2018 at 4:46 PM Denys Vlasenko  
> > wrote:
> > > > Because my patch is so large, I cannot get it through the mailing list
> > > > filter. Therefore, I have pasted it on pastebin, instead.
> > > >
> > > > The link is https://pastebin.com/PJa2vaUR and the raw version can be
> > > > found at https://pastebin.com/raw/PJa2vaUR
> > >
> > > Probably could send it bzipped.
> >
> > I tried, unfortunately. Even though it was under the limit, the
> > mailing list software rejected.
>
> Ok, pastebin would work for the time being.
>
>
> > > +if (!(v->v = malloc(esize * BC_VEC_START_CAP))) return 
> > > BC_STATUS_ALLOC_ERR;
> > >
> > > (1) Please do not nest assignments:
> > >
> > > v->v = malloc(esize * BC_VEC_START_CAP);
> > > if (!v->v)
> > > return BC_STATUS_ALLOC_ERR;
> >
> > Oh boy. I was afraid of this.
> >
> > The problem is that I am also trying to get this bc into toybox (might
> > as well reduce duplication of effort), and as I am sure you know,
> > Landley is very particular about the line count of commands. To be
> > honest, I would prefer your style (except for putting if statements
> > that on one line if possible), but this reduces line count.
> >
> > I don't really know what to do here.
>
> I can rewrite these constructs after patch is merged.
>
>
> > > +BcStatus bc_vec_pushByte(BcVec *v, uint8_t data) {
> > > +return bc_vec_push(v, );
> > > +}
> > >
> > > The entire bbox code base uses this formatting of function body:
> > >
> > > BcStatus bc_vec_pushByte(BcVec *v, uint8_t data)
> > > {
> > > return bc_vec_push(v, );
> > > }
> >
> > This one might be a little harder.
>
> I can rewrite these constructs after patch is merged.
>
>
> > > +if (!v->len && (s = bc_vec_pushByte(v, '\0'))) return s;
> > >
> > > len is not boolean or a pointer. !foo is usually used with those.
> > > len is an integer. You are testing whether it's zero. Why obfuscate?
> > > For readability, should be:
> > >if (v->len == 0) {
> > >s = bc_vec_pushByte(v, '\0');
> > >if (s)
> > >return s;
> > > }
>
> One-line "if (s) return s;" is okay too, when both if-expression and
> statement are simple.
>
>
> > > +static void bc_vm_sig(int sig) {
> > > +if (sig == SIGINT) {
> > > +size_t len = strlen(bcg.sig_msg);
> > > +if (write(2, bcg.sig_msg, len) == (ssize_t) len)
> > > +bcg.sig += (bcg.signe = bcg.sig == bcg.sigc);
> > > +}
> > > +else bcg.sig_other = 1;
> > > +}
> > >
> > > +sa.sa_handler = bc_vm_sig;
> > > +sa.sa_flags = 0;
> > > +
> > > +if (sigaction(SIGINT, , NULL) < 0 || sigaction(SIGPIPE, ,
> > > NULL) < 0 ||
> > > +sigaction(SIGHUP, , NULL) < 0 || sigaction(SIGTERM, , 
> > > NULL) < 0)
> > > +{
> > > +return BC_STATUS_EXEC_SIGACTION_FAIL;
> > > +}
> > >
> > > Calculator has signal handling?!
> > > siganction() never fails - no need to check result.
> >
> > GNU bc has signal handling. It is so users can stop long-running
> > calculations. This bc is meant to be compatible.
>
> Well, without signal handling ^C will stop long-running calculations
> too. :)
> I can imagine some users who use interactive bc *a lot* (scientist?),
> and who would want "^C abort calc but stays in bc" behavior,
> but they are likely a minority. Can you make signal handling optional?
>
>
> > Okay, as it stands, I see one big showstopper for getting this into
> > busybox: code style. I don't know how to fix code style with a script,
> > so if it is a showstopper for you
>
> It is not.

Thank you for being willing. I can work with this. It may take me a
few days to generate a new patch.

Gavin Howard
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [PATCH] Add bc (Last patch)

2018-10-30 Thread Denys Vlasenko
On Tue, Oct 30, 2018 at 12:30 AM Gavin Howard  wrote:
> On Mon, Oct 29, 2018 at 4:46 PM Denys Vlasenko  
> wrote:
> > > Because my patch is so large, I cannot get it through the mailing list
> > > filter. Therefore, I have pasted it on pastebin, instead.
> > >
> > > The link is https://pastebin.com/PJa2vaUR and the raw version can be
> > > found at https://pastebin.com/raw/PJa2vaUR
> >
> > Probably could send it bzipped.
>
> I tried, unfortunately. Even though it was under the limit, the
> mailing list software rejected.

Ok, pastebin would work for the time being.


> > +if (!(v->v = malloc(esize * BC_VEC_START_CAP))) return 
> > BC_STATUS_ALLOC_ERR;
> >
> > (1) Please do not nest assignments:
> >
> > v->v = malloc(esize * BC_VEC_START_CAP);
> > if (!v->v)
> > return BC_STATUS_ALLOC_ERR;
>
> Oh boy. I was afraid of this.
>
> The problem is that I am also trying to get this bc into toybox (might
> as well reduce duplication of effort), and as I am sure you know,
> Landley is very particular about the line count of commands. To be
> honest, I would prefer your style (except for putting if statements
> that on one line if possible), but this reduces line count.
>
> I don't really know what to do here.

I can rewrite these constructs after patch is merged.


> > +BcStatus bc_vec_pushByte(BcVec *v, uint8_t data) {
> > +return bc_vec_push(v, );
> > +}
> >
> > The entire bbox code base uses this formatting of function body:
> >
> > BcStatus bc_vec_pushByte(BcVec *v, uint8_t data)
> > {
> > return bc_vec_push(v, );
> > }
>
> This one might be a little harder.

I can rewrite these constructs after patch is merged.


> > +if (!v->len && (s = bc_vec_pushByte(v, '\0'))) return s;
> >
> > len is not boolean or a pointer. !foo is usually used with those.
> > len is an integer. You are testing whether it's zero. Why obfuscate?
> > For readability, should be:
> >if (v->len == 0) {
> >s = bc_vec_pushByte(v, '\0');
> >if (s)
> >return s;
> > }

One-line "if (s) return s;" is okay too, when both if-expression and
statement are simple.


> > +static void bc_vm_sig(int sig) {
> > +if (sig == SIGINT) {
> > +size_t len = strlen(bcg.sig_msg);
> > +if (write(2, bcg.sig_msg, len) == (ssize_t) len)
> > +bcg.sig += (bcg.signe = bcg.sig == bcg.sigc);
> > +}
> > +else bcg.sig_other = 1;
> > +}
> >
> > +sa.sa_handler = bc_vm_sig;
> > +sa.sa_flags = 0;
> > +
> > +if (sigaction(SIGINT, , NULL) < 0 || sigaction(SIGPIPE, ,
> > NULL) < 0 ||
> > +sigaction(SIGHUP, , NULL) < 0 || sigaction(SIGTERM, , NULL) 
> > < 0)
> > +{
> > +return BC_STATUS_EXEC_SIGACTION_FAIL;
> > +}
> >
> > Calculator has signal handling?!
> > siganction() never fails - no need to check result.
>
> GNU bc has signal handling. It is so users can stop long-running
> calculations. This bc is meant to be compatible.

Well, without signal handling ^C will stop long-running calculations
too. :)
I can imagine some users who use interactive bc *a lot* (scientist?),
and who would want "^C abort calc but stays in bc" behavior,
but they are likely a minority. Can you make signal handling optional?


> Okay, as it stands, I see one big showstopper for getting this into
> busybox: code style. I don't know how to fix code style with a script,
> so if it is a showstopper for you

It is not.
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [PATCH] Add bc (Last patch)

2018-10-30 Thread Lauri Kasanen
On Mon, 29 Oct 2018 17:30:09 -0600
Gavin Howard  wrote:

> Okay, as it stands, I see one big showstopper for getting this into
> busybox: code style. I don't know how to fix code style with a script,
> so if it is a showstopper for you (and if it is, I don't blame you), I
> guess I have to respectfully withdraw my patch and apologize for
> wasting your time.
> 
> If, however, it is not, we can talk about what to do about it. And I
> will get started on changing the other things.

Install GNU indent. It has an option for where to put the braces.

- Lauri
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [PATCH] Add bc (Last patch)

2018-10-29 Thread Gavin Howard
On Mon, Oct 29, 2018 at 4:46 PM Denys Vlasenko  wrote:
>
> On Mon, Oct 29, 2018 at 4:55 PM Gavin Howard  wrote:
> >
> > Hello,
> >
> > Because my patch is so large, I cannot get it through the mailing list
> > filter. Therefore, I have pasted it on pastebin, instead.
> >
> > The link is https://pastebin.com/PJa2vaUR and the raw version can be
> > found at https://pastebin.com/raw/PJa2vaUR
>
> Probably could send it bzipped.

I tried, unfortunately. Even though it was under the limit, the
mailing list software rejected.

> All functions except bc_main() should be static.
> Check with nm --size-sort bc.o

I will see what I can do about that.

> Use : the entire
>
> +BcStatus bc_read_file(const char *path, char **buf) {
> +
> +BcStatus s = BC_STATUS_IO_ERR;
> +FILE *f;
> +size_t size, read;
> +long res;
> +struct stat pstat;
> +
> +if (!(f = fopen(path, "r"))) return BC_STATUS_EXEC_FILE_ERR;
> +
> +if (fstat(fileno(f), ) == -1) goto malloc_err;
> +
> +if (S_ISDIR(pstat.st_mode)) {
> +s = BC_STATUS_PATH_IS_DIR;
> +goto malloc_err;
> +}
> +
> +if (fseek(f, 0, SEEK_END) == -1) goto malloc_err;
> +if ((res = ftell(f)) < 0) goto malloc_err;
> +if (fseek(f, 0, SEEK_SET) == -1) goto malloc_err;
> +
> +if (!(*buf = malloc((size = (size_t) res) + 1))) {
> +s = BC_STATUS_ALLOC_ERR;
> +goto malloc_err;
> +}
> +
> +if ((read = fread(*buf, 1, size, f)) != size) goto read_err;
>
> can be replaced by single xmalloc_open_read_close()!

Will do.

> (The entire
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> should be replaced by
> #include "libbb.h"
> #include 
> )

Sorry about that. I tried to follow the documentation as exactly as I could.

> +while ((c = getopt_long(argc, argv, bc_args_opt, bc_args_lopt,
> )) != -1)
> +{
>
> Use getopt32() ?

Okay. Will do.

> +typedef struct BcResult {
> +
> +BcResultType t;
> +BcResultData d;
> +
> +} BcResult;
>
> Lets drop these extra empty lines.

Will do.

> +#ifdef CONFIG_BC
> +BcStatus bc_vm_posixError(BcStatus s, const char *file,
> +  size_t line, const char *msg);
> +#endif // CONFIG_BC
>
> "ifdef CONFIG_foo" is unsafe versus typos. Use "if ENABLE_foo" - it
> gives warnings
> for typos.

Oh? Did not know that.

> +#ifdef CONFIG_BC
> +
> +#endif // CONFIG_BC
>
> Why these empty ifdef blocks?

This was caused by bugs in my release script that have been fixed.

> +const char bc_name[] = "bc";
>
> static
>
>
> +const char *bc_errs[] = {
>
> static const char *const bc_errs[] = {

Will do.

> +if (!(v->v = malloc(esize * BC_VEC_START_CAP))) return 
> BC_STATUS_ALLOC_ERR;
>
> (1) Please do not nest assignments:
>
> v->v = malloc(esize * BC_VEC_START_CAP);
> if (!v->v)
> return BC_STATUS_ALLOC_ERR;

Oh boy. I was afraid of this.

The problem is that I am also trying to get this bc into toybox (might
as well reduce duplication of effort), and as I am sure you know,
Landley is very particular about the line count of commands. To be
honest, I would prefer your style (except for putting if statements
that on one line if possible), but this reduces line count.

I don't really know what to do here.

> (2) Use xmalloc/xzalloc/xrealloc which never return NULL.
> We do not try to survive out-of-memory. No check is necessary.

Will do. I was not aware of those functions. bc does have to print a
diagnostic message (see
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html#tag_20_09_15),
but I checked that those procedures do that.

> +BcStatus bc_vec_pushByte(BcVec *v, uint8_t data) {
> +return bc_vec_push(v, );
> +}
>
> The entire bbox code base uses this formatting of function body:
>
> BcStatus bc_vec_pushByte(BcVec *v, uint8_t data)
> {
> return bc_vec_push(v, );
> }

This one might be a little harder.

> +if (!v->len && (s = bc_vec_pushByte(v, '\0'))) return s;
>
> len is not boolean or a pointer. !foo is usually used with those.
> len is an integer. You are testing whether it's zero. Why obfuscate?
> For readability, should be:
>if (v->len == 0) {
>s = bc_vec_pushByte(v, '\0');
>if (s)
>return s;
> }
>
>
> +if (a == b) return 0;
> +else if (!a->len) return BC_NUM_NEG(!!b->len, !b->neg);
> +else if (!b->len) return BC_NUM_NEG(1, a->neg);
> +else if (a->neg) {
> +if (b->neg) neg = true;
> +else return -1;
> +}
> +else if (b->neg) return 1;
>
> "else" after exiting code in preceding "if" is not necessary.
> Can rewrite as:
>
> if (a == b) return 0;
> if (!a->len) return BC_NUM_NEG(!!b->len, !b->neg);
> if (!b->len) return BC_NUM_NEG(1, a->neg);
> if (a->neg) {
> if (!b->neg) return -1;
> neg = true;
> }
> else if (b->neg) return 1;

You are correct.

> 

Re: [PATCH] Add bc (Last patch)

2018-10-29 Thread Denys Vlasenko
On Mon, Oct 29, 2018 at 4:55 PM Gavin Howard  wrote:
>
> Hello,
>
> Because my patch is so large, I cannot get it through the mailing list
> filter. Therefore, I have pasted it on pastebin, instead.
>
> The link is https://pastebin.com/PJa2vaUR and the raw version can be
> found at https://pastebin.com/raw/PJa2vaUR

Probably could send it bzipped.

All functions except bc_main() should be static.
Check with nm --size-sort bc.o


Use : the entire

+BcStatus bc_read_file(const char *path, char **buf) {
+
+BcStatus s = BC_STATUS_IO_ERR;
+FILE *f;
+size_t size, read;
+long res;
+struct stat pstat;
+
+if (!(f = fopen(path, "r"))) return BC_STATUS_EXEC_FILE_ERR;
+
+if (fstat(fileno(f), ) == -1) goto malloc_err;
+
+if (S_ISDIR(pstat.st_mode)) {
+s = BC_STATUS_PATH_IS_DIR;
+goto malloc_err;
+}
+
+if (fseek(f, 0, SEEK_END) == -1) goto malloc_err;
+if ((res = ftell(f)) < 0) goto malloc_err;
+if (fseek(f, 0, SEEK_SET) == -1) goto malloc_err;
+
+if (!(*buf = malloc((size = (size_t) res) + 1))) {
+s = BC_STATUS_ALLOC_ERR;
+goto malloc_err;
+}
+
+if ((read = fread(*buf, 1, size, f)) != size) goto read_err;

can be replaced by single xmalloc_open_read_close()!
(The entire
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
should be replaced by
#include "libbb.h"
#include 
)


+while ((c = getopt_long(argc, argv, bc_args_opt, bc_args_lopt,
)) != -1)
+{

Use getopt32() ?


+typedef struct BcResult {
+
+BcResultType t;
+BcResultData d;
+
+} BcResult;

Lets drop these extra empty lines.


+#ifdef CONFIG_BC
+BcStatus bc_vm_posixError(BcStatus s, const char *file,
+  size_t line, const char *msg);
+#endif // CONFIG_BC

"ifdef CONFIG_foo" is unsafe versus typos. Use "if ENABLE_foo" - it
gives warnings
for typos.


+#ifdef CONFIG_BC
+
+#endif // CONFIG_BC

Why these empty ifdef blocks?


+const char bc_name[] = "bc";

static


+const char *bc_errs[] = {

static const char *const bc_errs[] = {


+if (!(v->v = malloc(esize * BC_VEC_START_CAP))) return BC_STATUS_ALLOC_ERR;

(1) Please do not nest assignments:

v->v = malloc(esize * BC_VEC_START_CAP);
if (!v->v)
return BC_STATUS_ALLOC_ERR;

(2) Use xmalloc/xzalloc/xrealloc which never return NULL.
We do not try to survive out-of-memory. No check is necessary.


+BcStatus bc_vec_pushByte(BcVec *v, uint8_t data) {
+return bc_vec_push(v, );
+}

The entire bbox code base uses this formatting of function body:

BcStatus bc_vec_pushByte(BcVec *v, uint8_t data)
{
return bc_vec_push(v, );
}


+if (!v->len && (s = bc_vec_pushByte(v, '\0'))) return s;

len is not boolean or a pointer. !foo is usually used with those.
len is an integer. You are testing whether it's zero. Why obfuscate?
For readability, should be:
   if (v->len == 0) {
   s = bc_vec_pushByte(v, '\0');
   if (s)
   return s;
}


+if (a == b) return 0;
+else if (!a->len) return BC_NUM_NEG(!!b->len, !b->neg);
+else if (!b->len) return BC_NUM_NEG(1, a->neg);
+else if (a->neg) {
+if (b->neg) neg = true;
+else return -1;
+}
+else if (b->neg) return 1;

"else" after exiting code in preceding "if" is not necessary.
Can rewrite as:

if (a == b) return 0;
if (!a->len) return BC_NUM_NEG(!!b->len, !b->neg);
if (!b->len) return BC_NUM_NEG(1, a->neg);
if (a->neg) {
if (!b->neg) return -1;
neg = true;
}
else if (b->neg) return 1;


+static void bc_vm_sig(int sig) {
+if (sig == SIGINT) {
+size_t len = strlen(bcg.sig_msg);
+if (write(2, bcg.sig_msg, len) == (ssize_t) len)
+bcg.sig += (bcg.signe = bcg.sig == bcg.sigc);
+}
+else bcg.sig_other = 1;
+}

+sa.sa_handler = bc_vm_sig;
+sa.sa_flags = 0;
+
+if (sigaction(SIGINT, , NULL) < 0 || sigaction(SIGPIPE, ,
NULL) < 0 ||
+sigaction(SIGHUP, , NULL) < 0 || sigaction(SIGTERM, , NULL) < 0)
+{
+return BC_STATUS_EXEC_SIGACTION_FAIL;
+}

Calculator has signal handling?!
siganction() never fails - no need to check result.
Better yet, use read_line_input() from libbb.h:
/*
 * maxsize must be >= 2.
 * Returns:
 * -1 on read errors or EOF, or on bare Ctrl-D,
 * 0  on ctrl-C (the line entered is still returned in 'command'),
 * >0 length of input string, including terminating '\n'
 */
int read_line_input(line_input_t *st, const char *prompt, char
*command, int maxsize) FAST_FUNC;

- it already has Ctrl-C handling, and drop entire signal handling mess.
(It's buggy: write() can modify errno).
Let bc just die on SIGPIPE, SIGTERM and SIGHUP.
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


[PATCH] Add bc (Last patch)

2018-10-29 Thread Gavin Howard
Hello,

Because my patch is so large, I cannot get it through the mailing list
filter. Therefore, I have pasted it on pastebin, instead.

The link is https://pastebin.com/PJa2vaUR and the raw version can be
found at https://pastebin.com/raw/PJa2vaUR

I look forward to working with the maintainers on getting this added.
(And sorry for the moderator approval spam.)

Gavin Howard
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox