Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/bin/sh Add support for ++ and -- (pre & post) and ', ' to ari...
details: https://anonhg.NetBSD.org/src/rev/5c3de6073e5d
branches: trunk
changeset: 355298:5c3de6073e5d
user: kre <kre%NetBSD.org@localhost>
date: Mon Jul 24 13:21:14 2017 +0000
description:
Add support for ++ and -- (pre & post) and ',' to arithmetic.
diffstat:
bin/sh/arith_token.c | 21 ++++++++++++++-----
bin/sh/arith_tokens.h | 5 +++-
bin/sh/arithmetic.c | 52 ++++++++++++++++++++++++++++++++++++++++++++------
bin/sh/sh.1 | 27 ++++++++++++++++++-------
4 files changed, 83 insertions(+), 22 deletions(-)
diffs (224 lines):
diff -r 18a2ec27c7a0 -r 5c3de6073e5d bin/sh/arith_token.c
--- a/bin/sh/arith_token.c Mon Jul 24 12:36:02 2017 +0000
+++ b/bin/sh/arith_token.c Mon Jul 24 13:21:14 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: arith_token.c,v 1.5 2017/06/07 05:08:32 kre Exp $ */
+/* $NetBSD: arith_token.c,v 1.6 2017/07/24 13:21:14 kre Exp $ */
/*-
* Copyright (c) 2002
@@ -39,7 +39,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: arith_token.c,v 1.5 2017/06/07 05:08:32 kre Exp $");
+__RCSID("$NetBSD: arith_token.c,v 1.6 2017/07/24 13:21:14 kre Exp $");
#endif /* not lint */
#include <inttypes.h>
@@ -212,13 +212,19 @@
goto checkeq;
case '+':
- if (buf[1] == '+')
- error("arithmetic: ++ operator unsupported");
+ if (buf[1] == '+') {
+ buf++;
+ token = ARITH_INCR;
+ break;
+ }
token = ARITH_ADD;
goto checkeq;
case '-':
- if (buf[1] == '-')
- error("arithmetic: -- operator unsupported");
+ if (buf[1] == '-') {
+ buf++;
+ token = ARITH_DECR;
+ break;
+ }
token = ARITH_SUB;
goto checkeq;
case '~':
@@ -234,6 +240,9 @@
case ':':
token = ARITH_COLON;
break;
+ case ',':
+ token = ARITH_COMMA;
+ break;
}
break;
}
diff -r 18a2ec27c7a0 -r 5c3de6073e5d bin/sh/arith_tokens.h
--- a/bin/sh/arith_tokens.h Mon Jul 24 12:36:02 2017 +0000
+++ b/bin/sh/arith_tokens.h Mon Jul 24 13:21:14 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: arith_tokens.h,v 1.2 2017/06/07 05:08:32 kre Exp $ */
+/* $NetBSD: arith_tokens.h,v 1.3 2017/07/24 13:21:14 kre Exp $ */
/*-
* Copyright (c) 1993
@@ -98,6 +98,9 @@
#define ARITH_BNOT 36
#define ARITH_QMARK 37
#define ARITH_COLON 38
+#define ARITH_INCR 39
+#define ARITH_DECR 40
+#define ARITH_COMMA 41
/*
* Globals shared between arith parser, and lexer
diff -r 18a2ec27c7a0 -r 5c3de6073e5d bin/sh/arithmetic.c
--- a/bin/sh/arithmetic.c Mon Jul 24 12:36:02 2017 +0000
+++ b/bin/sh/arithmetic.c Mon Jul 24 13:21:14 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: arithmetic.c,v 1.3 2017/06/07 05:08:32 kre Exp $ */
+/* $NetBSD: arithmetic.c,v 1.4 2017/07/24 13:21:14 kre Exp $ */
/*-
* Copyright (c) 1993
@@ -39,7 +39,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: arithmetic.c,v 1.3 2017/06/07 05:08:32 kre Exp $");
+__RCSID("$NetBSD: arithmetic.c,v 1.4 2017/07/24 13:21:14 kre Exp $");
#endif /* not lint */
#include <limits.h>
@@ -192,19 +192,21 @@
}
}
-static intmax_t assignment(int var, int noeval);
+static intmax_t assignment(int, int);
+static intmax_t comma_list(int, int);
static intmax_t
primary(int token, union a_token_val *val, int op, int noeval)
{
intmax_t result;
+ char sresult[DIGITS(result) + 1];
VTRACE(DBG_ARITH, ("Arith primary: token %d op %d%s\n",
token, op, noeval ? " noeval" : ""));
switch (token) {
case ARITH_LPAREN:
- result = assignment(op, noeval);
+ result = comma_list(op, noeval);
if (last_token != ARITH_RPAREN)
arith_err("expecting ')'");
last_token = arith_token();
@@ -213,8 +215,18 @@
last_token = op;
return val->val;
case ARITH_VAR:
- last_token = op;
- return noeval ? val->val : arith_lookupvarint(val->name);
+ result = noeval ? val->val : arith_lookupvarint(val->name);
+ if (op == ARITH_INCR || op == ARITH_DECR) {
+ last_token = arith_token();
+ if (noeval)
+ return val->val;
+
+ snprintf(sresult, sizeof(sresult), ARITH_FORMAT_STR,
+ result + (op == ARITH_INCR ? 1 : -1));
+ setvar(val->name, sresult, 0);
+ } else
+ last_token = op;
+ return result;
case ARITH_ADD:
*val = a_t_val;
return primary(op, val, arith_token(), noeval);
@@ -227,6 +239,18 @@
case ARITH_BNOT:
*val = a_t_val;
return ~primary(op, val, arith_token(), noeval);
+ case ARITH_INCR:
+ case ARITH_DECR:
+ if (op != ARITH_VAR)
+ arith_err("incr/decr require var name");
+ last_token = arith_token();
+ if (noeval)
+ return val->val;
+ result = arith_lookupvarint(a_t_val.name);
+ snprintf(sresult, sizeof(sresult), ARITH_FORMAT_STR,
+ result += (token == ARITH_INCR ? 1 : -1));
+ setvar(a_t_val.name, sresult, 0);
+ return result;
default:
arith_err("expecting primary");
}
@@ -374,6 +398,20 @@
return result;
}
+static intmax_t
+comma_list(int token, int noeval)
+{
+ intmax_t result = assignment(token, noeval);
+
+ while (last_token == ARITH_COMMA) {
+ VTRACE(DBG_ARITH, ("Arith: comma discarding %jd%s\n", result,
+ noeval ? " noeval" : ""));
+ result = assignment(arith_token(), noeval);
+ }
+
+ return result;
+}
+
intmax_t
arith(const char *s, int lno)
{
@@ -405,7 +443,7 @@
arith_buf = arith_startbuf = s;
- result = assignment(arith_token(), 0);
+ result = comma_list(arith_token(), 0);
if (last_token)
arith_err("expecting end of expression");
diff -r 18a2ec27c7a0 -r 5c3de6073e5d bin/sh/sh.1
--- a/bin/sh/sh.1 Mon Jul 24 12:36:02 2017 +0000
+++ b/bin/sh/sh.1 Mon Jul 24 13:21:14 2017 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: sh.1,v 1.160 2017/07/24 12:36:02 kre Exp $
+.\" $NetBSD: sh.1,v 1.161 2017/07/24 13:21:14 kre Exp $
.\" Copyright (c) 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
@@ -1528,13 +1528,24 @@
Referencing the value of a variable which is not numeric is an error.
.Pp
All of the C expression operators applicable to integers are supported,
-and operate as they would in a C expression, except the unary
-.Dq ++
-and
-.Dq --
-operators (in both prefix and postfix forms) and the
-.Dq \&,
-(comma) operator, which are currently not supported.
+and operate as they would in a C expression.
+Use white space, or parentheses, to disambiguate confusing syntax,
+otherwise, as in C, the longest sequence of consecutive characters
+which make a valid token (operator, variable name, or number) is taken
+to be that token, even if the token designated cannot be used
+and a different interpretation could produce a successful parse.
+This means, as an example, that
+.Dq a+++++b
+is parsed as the gibberish sequence
+.Dq "a ++ ++ + b" ,
+rather than as the valid alternative
+.Dq "a ++ + ++ b" .
+Similarly, separate the
+.Sq \&,
+operator from numbers with white space to avoid the possibility
+of confusion with the decimal indicator in some locales (though
+fractional, or floating-point, numbers are not supported in this
+implementation.)
.Pp
It should not be necessary to state that the C operators which
operate on, or produce, pointer types, are not supported.
Home |
Main Index |
Thread Index |
Old Index