* [PATCH]: allow $(())
@ 2021-01-29 19:49 Vladimir N. Oleynik
2021-01-31 9:29 ` [PATCH]: allow recursive variable inderection in arith Vladimir N. Oleynik
0 siblings, 1 reply; 2+ messages in thread
From: Vladimir N. Oleynik @ 2021-01-29 19:49 UTC (permalink / raw)
To: dash
Hello.
My micro patch for allow $(( )) as 0
--- arith_yacc.orig.c 2020-12-23 11:58:12.000000000 +0400
+++ arith_yacc.c 2021-01-29 23:47:01.854997852 +0400
@@ -292,10 +292,17 @@
intmax_t arith(const char *s)
{
intmax_t result;
+ int l0;
arith_buf = arith_startbuf = s;
- result = assignment(yylex(), 0);
+ l0 = yylex();
+ if (l0 == 0) {
+ /* $(( )) */
+ yylval.val = 0;
+ l0 = ARITH_NUM;
+ }
+ result = assignment(l0, 0);
if (last_token)
yyerror("expecting EOF");
--w
vodz
^ permalink raw reply [flat|nested] 2+ messages in thread
* [PATCH]: allow recursive variable inderection in arith
2021-01-29 19:49 [PATCH]: allow $(()) Vladimir N. Oleynik
@ 2021-01-31 9:29 ` Vladimir N. Oleynik
0 siblings, 0 replies; 2+ messages in thread
From: Vladimir N. Oleynik @ 2021-01-31 9:29 UTC (permalink / raw)
To: dash; +Cc: Vladimir N. Oleynik
[-- Attachment #1: Type: text/plain, Size: 344 bytes --]
Hello.
My patch for allow recursive variable inderection in arith
and simplify allow $(( )). Originaly from my arith in busybox
Before patch:
$ a=b b=2; echo $((a))
dash: 1: Illegal number: b
After patch:
$ a=b b=2; echo $((a))
2
a=b b="a*2"; echo $((a))
./dash: 4: arithmetic expression: expression recursion loop detected: "a"
--w
vodz
[-- Attachment #2: arith_diff.txt --]
[-- Type: text/plain, Size: 4102 bytes --]
--- arith_yacc.c.orig 2020-12-23 11:58:12.000000000 +0400
+++ arith_yacc.c 2021-01-31 13:19:00.790119536 +0400
@@ -34,6 +34,7 @@
#include <inttypes.h>
#include <stdlib.h>
+#include <string.h>
#include "arith_yacc.h"
#include "expand.h"
#include "shell.h"
@@ -134,6 +135,50 @@
static intmax_t assignment(int var, int noeval);
+typedef struct CHK_VAR_RECURSIVE_LOOPED {
+ const char *name;
+ struct CHK_VAR_RECURSIVE_LOOPED *next;
+} chk_var_recursive_looped_t;
+
+static chk_var_recursive_looped_t *prev_chk_var_recursive;
+
+static intmax_t arith_lookup_val(const char *name)
+{
+ const char * p = lookupvar(name);
+
+ if(p) {
+ intmax_t ret;
+
+ /* recursive try as expression */
+ chk_var_recursive_looped_t *cur;
+ chk_var_recursive_looped_t cur_save;
+ const char *arith_buf_s;
+ int lt;
+
+ for(cur = prev_chk_var_recursive; cur; cur = cur->next) {
+ if(!strcmp(cur->name, name))
+ yyerror("expression recursion loop detected");
+ }
+ /* save current lookuped var name */
+ cur = prev_chk_var_recursive;
+ cur_save.name = name;
+ cur_save.next = cur;
+ prev_chk_var_recursive = &cur_save;
+
+ arith_buf_s = arith_buf;
+ lt = last_token;
+ ret = arith (p, 1);
+ /* restore previous after recursiving */
+ prev_chk_var_recursive = cur;
+ arith_buf = arith_buf_s;
+ last_token = lt;
+ return ret;
+ } else {
+ /* allow undefined var as 0 */
+ return 0;
+ }
+}
+
static intmax_t primary(int token, union yystype *val, int op, int noeval)
{
intmax_t result;
@@ -151,7 +196,7 @@
return val->val;
case ARITH_VAR:
last_token = op;
- return noeval ? val->val : lookupvarint(val->name);
+ return noeval ? val->val : arith_lookup_val(val->name);
case ARITH_ADD:
token = op;
*val = yylval;
@@ -286,16 +331,27 @@
return setvarint(val.name,
op == ARITH_ASS ? result :
- do_binop(op - 11, lookupvarint(val.name), result), 0);
+ do_binop(op - 11, arith_lookup_val(val.name), result), 0);
}
-intmax_t arith(const char *s)
+intmax_t arith(const char *s, int r)
{
intmax_t result;
+ int l0;
- arith_buf = arith_startbuf = s;
+ arith_buf = s;
+ last_token = 0;
- result = assignment(yylex(), 0);
+ if(!r) {
+ prev_chk_var_recursive = (chk_var_recursive_looped_t *)0;
+ arith_startbuf = s;
+ }
+ l0 = yylex();
+ if (l0 == 0) {
+ /* $(( )) */
+ return 0;
+ }
+ result = assignment(l0, 0);
if (last_token)
yyerror("expecting EOF");
--- expand.c.orig 2020-12-23 11:58:12.000000000 +0400
+++ expand.c 2021-01-31 12:39:07.083194412 +0400
@@ -460,7 +460,7 @@
rmescapes(start);
pushstackmark(&sm, endoff);
- result = arith(start);
+ result = arith(start, 0);
popstackmark(&sm);
len = cvtnum(result, flag);
--- expand.h.orig 2020-12-23 11:58:12.000000000 +0400
+++ expand.h 2021-01-31 12:39:09.435194338 +0400
@@ -73,7 +73,7 @@
void ifsfree(void);
/* From arith.y */
-intmax_t arith(const char *);
+intmax_t arith(const char *, int r);
int expcmd(int , char **);
#ifdef USE_LEX
void arith_lex_reset(void);
--- var.c.orig 2020-12-23 11:58:12.000000000 +0400
+++ var.c 2021-01-31 12:30:38.894210308 +0400
@@ -322,12 +322,6 @@
return NULL;
}
-intmax_t lookupvarint(const char *name)
-{
- return atomax(lookupvar(name) ?: nullstr, 0);
-}
-
-
/*
--- var.h.orig 2020-12-23 11:58:12.000000000 +0400
+++ var.h 2021-01-31 12:30:45.150210113 +0400
@@ -140,7 +140,6 @@
struct var *setvareq(char *s, int flags);
struct strlist;
char *lookupvar(const char *);
-intmax_t lookupvarint(const char *);
char **listvars(int, int, char ***);
#define environment() listvars(VEXPORT, VUNSET, 0)
int showvars(const char *, int, int);
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2021-01-31 9:33 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-29 19:49 [PATCH]: allow $(()) Vladimir N. Oleynik
2021-01-31 9:29 ` [PATCH]: allow recursive variable inderection in arith Vladimir N. Oleynik
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).