aboutsummaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorStefan Farfeleder <stefanf@FreeBSD.org>2008-04-27 20:46:45 +0000
committerStefan Farfeleder <stefanf@FreeBSD.org>2008-04-27 20:46:45 +0000
commit39376f45e298ec9d397f9a7825d9cfb926eb3cae (patch)
treeb99023495b88b391643c34c0ad760ad9f638044b /bin
parent9d5a22b928c20d4f1d262a0f4df09952da7d6634 (diff)
downloadsrc-39376f45e298ec9d397f9a7825d9cfb926eb3cae.tar.gz
src-39376f45e298ec9d397f9a7825d9cfb926eb3cae.zip
- Fix bugs where the value of arithmetic expansion$((...)) was trucated
to type int. - Change the type used for arithmetic expansion to intmax_t (ie. 64 bit on all currently supported FreeBSD architectures). SUSv3 requires at least type long but allows for larger types. Other shells (eg. bash, zsh, NetBSD's sh) do that too. PR: 122659 Submitted by: Jaakko Heinonen (minor modifications by me)
Notes
Notes: svn path=/head/; revision=178625
Diffstat (limited to 'bin')
-rw-r--r--bin/sh/arith.h6
-rw-r--r--bin/sh/arith.y22
-rw-r--r--bin/sh/shell.h15
3 files changed, 29 insertions, 14 deletions
diff --git a/bin/sh/arith.h b/bin/sh/arith.h
index ed5773bdc399..41bc76fa2c7e 100644
--- a/bin/sh/arith.h
+++ b/bin/sh/arith.h
@@ -30,8 +30,12 @@
* $FreeBSD$
*/
+#include "shell.h"
+
+#define DIGITS(var) (3 + (2 + CHAR_BIT * sizeof((var))) / 3)
+
extern char *arith_buf, *arith_startbuf;
-int arith(char *);
+arith_t arith(char *);
void arith_lex_reset(void);
int expcmd(int, char **);
diff --git a/bin/sh/arith.y b/bin/sh/arith.y
index 391cc1618cc2..542fc445a8a7 100644
--- a/bin/sh/arith.y
+++ b/bin/sh/arith.y
@@ -75,7 +75,10 @@ __FBSDID("$FreeBSD$");
exp:
expr
- { return ($1); }
+ {
+ *YYPARSE_PARAM = $1;
+ return (0);
+ }
;
expr:
@@ -259,12 +262,13 @@ expr:
#include "output.h"
#include "memalloc.h"
-#define lstrlen(var) (3 + (2 + CHAR_BIT * sizeof((var))) / 3)
+#define YYPARSE_PARAM_TYPE arith_t *
+#define YYPARSE_PARAM result
char *arith_buf, *arith_startbuf;
int yylex(void);
-int yyparse(void);
+int yyparse(YYPARSE_PARAM_TYPE);
static int
arith_assign(char *name, arith_t value)
@@ -272,22 +276,22 @@ arith_assign(char *name, arith_t value)
char *str;
int ret;
- str = (char *)ckmalloc(lstrlen(value));
+ str = (char *)ckmalloc(DIGITS(value));
sprintf(str, ARITH_FORMAT_STR, value);
ret = setvarsafe(name, str, 0);
free(str);
return ret;
}
-int
+arith_t
arith(char *s)
{
- long result;
+ arith_t result;
arith_buf = arith_startbuf = s;
INTOFF;
- result = yyparse();
+ yyparse(&result);
arith_lex_reset(); /* Reprime lex. */
INTON;
@@ -313,7 +317,7 @@ expcmd(int argc, char **argv)
char *p;
char *concat;
char **ap;
- long i;
+ arith_t i;
if (argc > 1) {
p = argv[1];
@@ -338,7 +342,7 @@ expcmd(int argc, char **argv)
i = arith(p);
- out1fmt("%ld\n", i);
+ out1fmt(ARITH_FORMAT_STR "\n", i);
return !i;
}
diff --git a/bin/sh/shell.h b/bin/sh/shell.h
index 58a25feb53cf..81ad42473a19 100644
--- a/bin/sh/shell.h
+++ b/bin/sh/shell.h
@@ -33,6 +33,11 @@
* $FreeBSD$
*/
+#ifndef SHELL_H_
+#define SHELL_H_
+
+#include <inttypes.h>
+
/*
* The follow should be set to reflect the type of system you have:
* JOBS -> 1 if you have Berkeley job control, 0 otherwise.
@@ -50,10 +55,10 @@
/*
* Type of used arithmetics. SUSv3 requires us to have at least signed long.
*/
-typedef long arith_t;
-#define ARITH_FORMAT_STR "%ld"
-#define atoarith_t(arg) strtol(arg, NULL, 0)
-#define strtoarith_t(nptr, endptr, base) strtol(nptr, endptr, base)
+typedef intmax_t arith_t;
+#define ARITH_FORMAT_STR "%" PRIdMAX
+#define atoarith_t(arg) strtoimax(arg, NULL, 0)
+#define strtoarith_t(nptr, endptr, base) strtoimax(nptr, endptr, base)
typedef void *pointer;
#define STATIC static
@@ -68,3 +73,5 @@ extern char nullstr[1]; /* null string */
#else
#define TRACE(param)
#endif
+
+#endif /* !SHELL_H_ */