Hi Steffen,

On Wed, 31 Aug 2022 01:43:26 +0200
Steffen Nurpmeso <[email protected]> wrote:

> The former implementation was not correct regarding whiteouts in
> ?: conditional branches.  The new one also parses a bit better, in
> effect on equal level than bash with its recursive descendent parser.

Please provide bloat-o-meter output.
i.e.
make baseline
# apply patch
make bloatcheck

> diff --git a/shell/math.c b/shell/math.c
> index 76d22c9bd5..8ba0d2f7fb 100644
> --- a/shell/math.c
> +++ b/shell/math.c

> +#define su_ienc_s64(X,Y,Z) (sprintf(X, ARITH_FMT, Y), X)
> +#define n_var_vlook(X,Y) (*self->sac_cookie->lookupvar)(X)
> +#define n_var_vset(X,Y,Z) (*self->sac_cookie->setvar)(X, (char*)(Y))
> +#define su_idec_cp(A,B,C,D,E) a_idec_x(A, B, E)

Can you drop the unused parameters?

> +
> +static inline uint32_t a_idec_x(void *resp, char const *cbuf,
> +             char const **endptr_or_nil){
> +     uint32_t rv;
> +     arith_t res;
> +     char const *eptr;
> +
> +     if(endptr_or_nil == NULL)
> +             endptr_or_nil = &eptr;

Space after if please.

> diff --git a/shell/shexp-arith.h b/shell/shexp-arith.h
> new file mode 100644
> index 0000000000..5f3655b456
> --- /dev/null
> +++ b/shell/shexp-arith.h
> @@ -0,0 +1,1292 @@
> +/*@ S-nail - a mail user agent derived from Berkeley Mail.

Missing license statement here?

> + *@ Signed 64-bit sh(1)ell-style $(( ARITH ))metic expression evaluator.
> + *@ POW2 bases are parsed as unsigned, operation overflow -> limit 
> constant(s),
> + *@ saturated mode is not supported, division by zero is handled via error.
> + *@ The expression length limit is ~100.000.000 on 32-bit, U32_MAX otherwise.
> + *@ After reading on Dijkstra's two stack algorithm, as well as bash:expr.c.
> + *@ Most heavily inspired by busybox -- conclusion: the Dijkstra algorithm
> + *@ scales very badly to ternary as are used to implement conditionals and
> + *@ their ignored sub-expressions.
> + *@
> + *@ #define's:
> + *@ - a_SHEXP_ARITH_COMPAT_SHIMS: for inclusion in other code bases, setting
> + *@   this defines most necessary compat macros.

these defines

> + *@   We still need s64, u64, S64_MIN, savestr(CP) <> strdup(3) that does not
> + *@   return NIL (only with _ERROR_TRACK).  Plus stdint.h, ctype.h, string.h.
> + *@   We need su_idec_cp(), su_ienc_s64(), n_var_vlook() and n_var_vset().
> + *@   We need su_IDEC_STATE_EMASK (= 1) and su_IDEC_STATE_CONSUMED (= 2), 
> e.g.:
> + *@     errno = 0;
> + *@     res = strto_arith_t(cbuf, (char**)endptr_or_nil);
> + *@     rv = 0;
> + *@     if(errno == 0){
> + *@       if(**endptr_or_nil == '\0')
> + *@         rv = su_IDEC_STATE_CONSUMED;
> + *@     }else{
> + *@       rv = su_IDEC_STATE_EMASK;
> + *@       res = 0;
> + *@     }
> + *@     *S(s64*,resp) = res;
> + *@ - a_SHEXP_ARITH_COOKIE: adds struct a_shexp_arith_ctx:sac_cookie, and
> + *@   a cookie arg to a_shexp_arith_eval().
> + *@ - a_SHEXP_ARITH_ERROR_TRACK: add "char **error_track_or_nil" to
> + *@   a_shexp_arith_eval(), and according error stack handling, so that users
> + *@   can be given hint where an error occurred.  ("Three stack algorithm.")
> + *
> + * Copyright (c) 2022 Steffen Nurpmeso <[email protected]>.
> + * SPDX-License-Identifier: ISC
> + *
> + * Permission to use, copy, modify, and/or distribute this software for any
> + * purpose with or without fee is hereby granted, provided that the above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */

Ah, here is the license. Please move it to line 2 ?

> +static void
> +a_shexp__arith_eval(struct a_shexp_arith_ctx *self,
> +      char const *exp_buf, uz exp_len){
> +   char *ep, *varp, *cp, c;
> +   u16 lop;
> +   struct a_shexp_arith_stack *sasp;
> +   void *mem_p;
> +   NYD2_IN;

What's NYD2_IN supposed to accomplish? Delete.

> +
> +   a_SHEXP_ARITH_L((" > _arith_eval %zu <%.*s>\n",
> +      exp_len, S(int,exp_len != UZ_MAX ? exp_len : su_cs_len(exp_buf)),
> +      exp_buf));
> +
> +   mem_p = NIL;
> +   sasp = self->sac_stack;
> +
> +   /* Create a single continuous allocation for anything */
> +   /* C99 */{
> +      union {void *v; char *c;} p;
> +      uz i, j, a;
> +
> +      /* Done for empty expression */
> +      if((i = a_shexp__arith_ws_squeeze(self, exp_buf, exp_len, NIL)) == 0)
> +         goto jleave;
> +      ++i;
> +
> +      /* Overflow check: since arithmetic expressions are rarely long enough
> +       * to come near this limit, xxx laxe & fuzzy, not exact; max U32_MAX! 
> */
> +      if(su_64( i > U32_MAX || ) i >= UZ_MAX / 2 ||

I have to admit that the amount of macro maze makes it really hard to
read ;)

What was the initial expression that did not work properly with the old
implementation?

thanks,
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to