From 91ce988bec6307c97c83c53aee72fcd7ee25ac7a Mon Sep 17 00:00:00 2001 From: apb Date: Sun, 25 Mar 2007 06:29:26 +0000 Subject: [PATCH] Make /bin/sh use intmax_t (instead of int) for arithmetic in $((...)). --- bin/sh/arith.y | 31 +++++++++++++++++++++---------- bin/sh/arith_lex.l | 16 ++++++++-------- bin/sh/expand.c | 20 ++++++++++---------- bin/sh/expand.h | 6 ++++-- 4 files changed, 43 insertions(+), 30 deletions(-) diff --git a/bin/sh/arith.y b/bin/sh/arith.y index e702c1d43d84..e0365dac0b33 100644 --- a/bin/sh/arith.y +++ b/bin/sh/arith.y @@ -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 @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)arith.y 8.3 (Berkeley) 5/4/95"; #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 /* 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 "memalloc.h" +typedef intmax_t YYSTYPE; +#define YYSTYPE YYSTYPE + +intmax_t arith_result; const char *arith_buf, *arith_startbuf; void yyerror(const char *); @@ -74,7 +78,12 @@ int error(char *); %% 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 ; %% -int +intmax_t arith(s) const char *s; { - long result; + intmax_t result; arith_buf = arith_startbuf = s; INTOFF; - result = yyparse(); + (void) yyparse(); + result = arith_result; arith_lex_reset(); /* reprime lex */ INTON; @@ -141,7 +151,7 @@ expcmd(argc, argv) const char *p; char *concat; char **ap; - long i; + intmax_t i; if (argc > 1) { p = argv[1]; @@ -164,9 +174,10 @@ expcmd(argc, argv) } else p = ""; - i = arith(p); + (void)arith(p); + i = arith_result; - out1fmt("%ld\n", i); + out1fmt("%"PRIdMAX"\n", i); return (! i); } @@ -176,7 +187,7 @@ expcmd(argc, argv) main(argc, argv) char *argv[]; { - printf("%d\n", exp(argv[1])); + printf("%"PRIdMAX"\n", exp(argv[1])); } error(s) char *s; diff --git a/bin/sh/arith_lex.l b/bin/sh/arith_lex.l index e4815e948ce1..3472f7dcca97 100644 --- a/bin/sh/arith_lex.l +++ b/bin/sh/arith_lex.l @@ -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 @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)arith_lex.l 8.3 (Berkeley) 5/4/95"; #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 /* 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 "var.h" -extern int yylval; -extern char *arith_buf, *arith_startbuf; +extern intmax_t yylval; +extern const char *arith_buf, *arith_startbuf; #undef YY_INPUT #define YY_INPUT(buf,result,max) \ result = (*buf = *arith_buf++) ? 1 : YY_NULL; @@ -58,12 +58,12 @@ extern char *arith_buf, *arith_startbuf; %% [ \t\n] { ; } -0x[0-9a-fA-F]+ { yylval = strtol(yytext, 0, 0); return(ARITH_NUM); } -0[0-7]* { yylval = strtol(yytext, 0, 0); return(ARITH_NUM); } -[1-9][0-9]* { 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 = strtoimax(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); if (v) { - yylval = strtol(v, &v, 0); + yylval = strtoimax(v, &v, 0); if (*v == 0) return ARITH_NUM; } diff --git a/bin/sh/expand.c b/bin/sh/expand.c index a1b07ef20ca8..621120442d10 100644 --- a/bin/sh/expand.c +++ b/bin/sh/expand.c @@ -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 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)expand.c 8.5 (Berkeley) 5/15/95"; #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 /* not lint */ @@ -352,7 +352,8 @@ void expari(int flag) { char *p, *start; - int result; + intmax_t result; + int adjustment; int begoff; int quotes = flag & (EXP_FULL | EXP_CASE); int quoted; @@ -369,10 +370,9 @@ expari(int flag) * have to rescan starting from the beginning since CTLESC * characters have to be processed left to right. */ -#if INT_MAX / 1000000000 >= 10 || INT_MIN / 1000000000 <= -10 -#error "integers with more than 10 digits are not supported" -#endif - CHECKSTRSPACE(12 - 2, expdest); +/* SPACE_NEEDED is enough for all digits, plus possible "-", plus 2 (why?) */ +#define SPACE_NEEDED ((sizeof(intmax_t) * CHAR_BIT + 2) / 3 + 1 + 2) + CHECKSTRSPACE(SPACE_NEEDED - 2, expdest); USTPUTC('\0', expdest); start = stackblock(); p = expdest - 1; @@ -394,15 +394,15 @@ expari(int flag) if (quotes) rmescapes(p+2); result = arith(p+2); - fmtstr(p, 12, "%d", result); + fmtstr(p, SPACE_NEEDED, "%"PRIdMAX, result); while (*p++) ; if (quoted == 0) recordregion(begoff, p - 1 - start, 0); - result = expdest - p + 1; - STADJUST(-result, expdest); + adjustment = expdest - p + 1; + STADJUST(-adjustment, expdest); } diff --git a/bin/sh/expand.h b/bin/sh/expand.h index 1ea876d61034..048cb4cc1912 100644 --- a/bin/sh/expand.h +++ b/bin/sh/expand.h @@ -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 @@ -34,6 +34,8 @@ * @(#)expand.h 8.2 (Berkeley) 5/4/95 */ +#include + struct strlist { struct strlist *next; char *text; @@ -66,7 +68,7 @@ int casematch(union node *, char *); int wordexpcmd(int, char **); /* From arith.y */ -int arith(const char *); +intmax_t arith(const char *); int expcmd(int , char **); void arith_lex_reset(void); int yylex(void);