Make /bin/sh use intmax_t (instead of int) for arithmetic in $((...)).

This commit is contained in:
apb 2007-03-25 06:29:26 +00:00
parent aeee45c69c
commit 91ce988bec
4 changed files with 43 additions and 30 deletions

View File

@ -1,5 +1,5 @@
%{ %{
/* $NetBSD: arith.y,v 1.17 2003/09/17 17:33:36 jmmv Exp $ */ /* $NetBSD: arith.y,v 1.18 2007/03/25 06:29:26 apb Exp $ */
/*- /*-
* Copyright (c) 1993 * Copyright (c) 1993
@ -38,7 +38,7 @@
#if 0 #if 0
static char sccsid[] = "@(#)arith.y 8.3 (Berkeley) 5/4/95"; static char sccsid[] = "@(#)arith.y 8.3 (Berkeley) 5/4/95";
#else #else
__RCSID("$NetBSD: arith.y,v 1.17 2003/09/17 17:33:36 jmmv Exp $"); __RCSID("$NetBSD: arith.y,v 1.18 2007/03/25 06:29:26 apb Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -49,6 +49,10 @@ __RCSID("$NetBSD: arith.y,v 1.17 2003/09/17 17:33:36 jmmv Exp $");
#include "output.h" #include "output.h"
#include "memalloc.h" #include "memalloc.h"
typedef intmax_t YYSTYPE;
#define YYSTYPE YYSTYPE
intmax_t arith_result;
const char *arith_buf, *arith_startbuf; const char *arith_buf, *arith_startbuf;
void yyerror(const char *); void yyerror(const char *);
@ -74,7 +78,12 @@ int error(char *);
%% %%
exp: expr { exp: expr {
return ($1); /*
* yyparse() returns int, so we have to save
* the desired result elsewhere.
*/
arith_result = $1;
return 0;
} }
; ;
@ -113,16 +122,17 @@ expr: ARITH_LPAREN expr ARITH_RPAREN { $$ = $2; }
| ARITH_NUM | ARITH_NUM
; ;
%% %%
int intmax_t
arith(s) arith(s)
const char *s; const char *s;
{ {
long result; intmax_t result;
arith_buf = arith_startbuf = s; arith_buf = arith_startbuf = s;
INTOFF; INTOFF;
result = yyparse(); (void) yyparse();
result = arith_result;
arith_lex_reset(); /* reprime lex */ arith_lex_reset(); /* reprime lex */
INTON; INTON;
@ -141,7 +151,7 @@ expcmd(argc, argv)
const char *p; const char *p;
char *concat; char *concat;
char **ap; char **ap;
long i; intmax_t i;
if (argc > 1) { if (argc > 1) {
p = argv[1]; p = argv[1];
@ -164,9 +174,10 @@ expcmd(argc, argv)
} else } else
p = ""; p = "";
i = arith(p); (void)arith(p);
i = arith_result;
out1fmt("%ld\n", i); out1fmt("%"PRIdMAX"\n", i);
return (! i); return (! i);
} }
@ -176,7 +187,7 @@ expcmd(argc, argv)
main(argc, argv) main(argc, argv)
char *argv[]; char *argv[];
{ {
printf("%d\n", exp(argv[1])); printf("%"PRIdMAX"\n", exp(argv[1]));
} }
error(s) error(s)
char *s; char *s;

View File

@ -1,5 +1,5 @@
%{ %{
/* $NetBSD: arith_lex.l,v 1.13 2005/03/21 22:37:09 dsl Exp $ */ /* $NetBSD: arith_lex.l,v 1.14 2007/03/25 06:29:26 apb Exp $ */
/*- /*-
* Copyright (c) 1993 * Copyright (c) 1993
@ -38,7 +38,7 @@
#if 0 #if 0
static char sccsid[] = "@(#)arith_lex.l 8.3 (Berkeley) 5/4/95"; static char sccsid[] = "@(#)arith_lex.l 8.3 (Berkeley) 5/4/95";
#else #else
__RCSID("$NetBSD: arith_lex.l,v 1.13 2005/03/21 22:37:09 dsl Exp $"); __RCSID("$NetBSD: arith_lex.l,v 1.14 2007/03/25 06:29:26 apb Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -48,8 +48,8 @@ __RCSID("$NetBSD: arith_lex.l,v 1.13 2005/03/21 22:37:09 dsl Exp $");
#include "expand.h" #include "expand.h"
#include "var.h" #include "var.h"
extern int yylval; extern intmax_t yylval;
extern char *arith_buf, *arith_startbuf; extern const char *arith_buf, *arith_startbuf;
#undef YY_INPUT #undef YY_INPUT
#define YY_INPUT(buf,result,max) \ #define YY_INPUT(buf,result,max) \
result = (*buf = *arith_buf++) ? 1 : YY_NULL; result = (*buf = *arith_buf++) ? 1 : YY_NULL;
@ -58,12 +58,12 @@ extern char *arith_buf, *arith_startbuf;
%% %%
[ \t\n] { ; } [ \t\n] { ; }
0x[0-9a-fA-F]+ { yylval = strtol(yytext, 0, 0); return(ARITH_NUM); } 0x[0-9a-fA-F]+ { yylval = strtoimax(yytext, 0, 0); return(ARITH_NUM); }
0[0-7]* { yylval = strtol(yytext, 0, 0); return(ARITH_NUM); } 0[0-7]* { yylval = strtoimax(yytext, 0, 0); return(ARITH_NUM); }
[1-9][0-9]* { yylval = strtol(yytext, 0, 0); return(ARITH_NUM); } [1-9][0-9]* { yylval = strtoimax(yytext, 0, 0); return(ARITH_NUM); }
[A-Za-z_][A-Za-z_0-9]* { char *v = lookupvar(yytext); [A-Za-z_][A-Za-z_0-9]* { char *v = lookupvar(yytext);
if (v) { if (v) {
yylval = strtol(v, &v, 0); yylval = strtoimax(v, &v, 0);
if (*v == 0) if (*v == 0)
return ARITH_NUM; return ARITH_NUM;
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: expand.c,v 1.77 2006/11/24 22:54:47 wiz Exp $ */ /* $NetBSD: expand.c,v 1.78 2007/03/25 06:29:26 apb Exp $ */
/*- /*-
* Copyright (c) 1991, 1993 * Copyright (c) 1991, 1993
@ -37,7 +37,7 @@
#if 0 #if 0
static char sccsid[] = "@(#)expand.c 8.5 (Berkeley) 5/15/95"; static char sccsid[] = "@(#)expand.c 8.5 (Berkeley) 5/15/95";
#else #else
__RCSID("$NetBSD: expand.c,v 1.77 2006/11/24 22:54:47 wiz Exp $"); __RCSID("$NetBSD: expand.c,v 1.78 2007/03/25 06:29:26 apb Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -352,7 +352,8 @@ void
expari(int flag) expari(int flag)
{ {
char *p, *start; char *p, *start;
int result; intmax_t result;
int adjustment;
int begoff; int begoff;
int quotes = flag & (EXP_FULL | EXP_CASE); int quotes = flag & (EXP_FULL | EXP_CASE);
int quoted; int quoted;
@ -369,10 +370,9 @@ expari(int flag)
* have to rescan starting from the beginning since CTLESC * have to rescan starting from the beginning since CTLESC
* characters have to be processed left to right. * characters have to be processed left to right.
*/ */
#if INT_MAX / 1000000000 >= 10 || INT_MIN / 1000000000 <= -10 /* SPACE_NEEDED is enough for all digits, plus possible "-", plus 2 (why?) */
#error "integers with more than 10 digits are not supported" #define SPACE_NEEDED ((sizeof(intmax_t) * CHAR_BIT + 2) / 3 + 1 + 2)
#endif CHECKSTRSPACE(SPACE_NEEDED - 2, expdest);
CHECKSTRSPACE(12 - 2, expdest);
USTPUTC('\0', expdest); USTPUTC('\0', expdest);
start = stackblock(); start = stackblock();
p = expdest - 1; p = expdest - 1;
@ -394,15 +394,15 @@ expari(int flag)
if (quotes) if (quotes)
rmescapes(p+2); rmescapes(p+2);
result = arith(p+2); result = arith(p+2);
fmtstr(p, 12, "%d", result); fmtstr(p, SPACE_NEEDED, "%"PRIdMAX, result);
while (*p++) while (*p++)
; ;
if (quoted == 0) if (quoted == 0)
recordregion(begoff, p - 1 - start, 0); recordregion(begoff, p - 1 - start, 0);
result = expdest - p + 1; adjustment = expdest - p + 1;
STADJUST(-result, expdest); STADJUST(-adjustment, expdest);
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: expand.h,v 1.16 2004/07/13 15:05:59 seb Exp $ */ /* $NetBSD: expand.h,v 1.17 2007/03/25 06:29:27 apb Exp $ */
/*- /*-
* Copyright (c) 1991, 1993 * Copyright (c) 1991, 1993
@ -34,6 +34,8 @@
* @(#)expand.h 8.2 (Berkeley) 5/4/95 * @(#)expand.h 8.2 (Berkeley) 5/4/95
*/ */
#include <inttypes.h>
struct strlist { struct strlist {
struct strlist *next; struct strlist *next;
char *text; char *text;
@ -66,7 +68,7 @@ int casematch(union node *, char *);
int wordexpcmd(int, char **); int wordexpcmd(int, char **);
/* From arith.y */ /* From arith.y */
int arith(const char *); intmax_t arith(const char *);
int expcmd(int , char **); int expcmd(int , char **);
void arith_lex_reset(void); void arith_lex_reset(void);
int yylex(void); int yylex(void);