aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xadmin/merge-gnulib2
-rw-r--r--lib/gnulib.mk.in27
-rw-r--r--lib/strtoul.c19
-rw-r--r--lib/strtoull.c26
-rw-r--r--lib/strtoumax.c2
-rw-r--r--m4/gnulib-comp.m430
-rw-r--r--m4/strtoull.m424
-rw-r--r--m4/strtoumax.m428
-rw-r--r--src/editfns.c43
-rw-r--r--src/lread.c59
10 files changed, 58 insertions, 202 deletions
diff --git a/admin/merge-gnulib b/admin/merge-gnulib
index 45e4a788a35..e5fb0f59fb3 100755
--- a/admin/merge-gnulib
+++ b/admin/merge-gnulib
@@ -38,7 +38,7 @@ GNULIB_MODULES='
38 manywarnings memrchr mkostemp mktime 38 manywarnings memrchr mkostemp mktime
39 pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat 39 pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat
40 sig2str socklen stat-time std-gnu11 stdalign stddef stdio 40 sig2str socklen stat-time std-gnu11 stdalign stddef stdio
41 stpcpy strftime strtoimax strtoumax symlink sys_stat 41 stpcpy strftime strtoimax symlink sys_stat
42 sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub 42 sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub
43 update-copyright utimens 43 update-copyright utimens
44 vla warnings 44 vla warnings
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index d23c2a57ec3..73d304307d4 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -21,7 +21,7 @@
21# the same distribution terms as the rest of that program. 21# the same distribution terms as the rest of that program.
22# 22#
23# Generated by gnulib-tool. 23# Generated by gnulib-tool.
24# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=setenv --avoid=sigprocmask --avoid=stat --avoid=stdarg --avoid=stdbool --avoid=threadlib --avoid=tzset --avoid=unsetenv --avoid=utime --avoid=utime-h --gnu-make --makefile-name=gnulib.mk.in --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt binary-io byteswap c-ctype c-strcase careadlinkat close-stream count-leading-zeros count-one-bits count-trailing-zeros crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode filevercmp flexmember fstatat fsync getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog ignore-value intprops largefile lstat manywarnings memrchr mkostemp mktime pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat sig2str socklen stat-time std-gnu11 stdalign stddef stdio stpcpy strftime strtoimax strtoumax symlink sys_stat sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub update-copyright utimens vla warnings 24# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=setenv --avoid=sigprocmask --avoid=stat --avoid=stdarg --avoid=stdbool --avoid=threadlib --avoid=tzset --avoid=unsetenv --avoid=utime --avoid=utime-h --gnu-make --makefile-name=gnulib.mk.in --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt binary-io byteswap c-ctype c-strcase careadlinkat close-stream count-leading-zeros count-one-bits count-trailing-zeros crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode filevercmp flexmember fstatat fsync getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog ignore-value intprops largefile lstat manywarnings memrchr mkostemp mktime pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat sig2str socklen stat-time std-gnu11 stdalign stddef stdio stpcpy strftime strtoimax symlink sys_stat sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub update-copyright utimens vla warnings
25 25
26 26
27MOSTLYCLEANFILES += core *.stackdump 27MOSTLYCLEANFILES += core *.stackdump
@@ -905,7 +905,6 @@ gl_GNULIB_ENABLED_getdtablesize = @gl_GNULIB_ENABLED_getdtablesize@
905gl_GNULIB_ENABLED_getgroups = @gl_GNULIB_ENABLED_getgroups@ 905gl_GNULIB_ENABLED_getgroups = @gl_GNULIB_ENABLED_getgroups@
906gl_GNULIB_ENABLED_secure_getenv = @gl_GNULIB_ENABLED_secure_getenv@ 906gl_GNULIB_ENABLED_secure_getenv = @gl_GNULIB_ENABLED_secure_getenv@
907gl_GNULIB_ENABLED_strtoll = @gl_GNULIB_ENABLED_strtoll@ 907gl_GNULIB_ENABLED_strtoll = @gl_GNULIB_ENABLED_strtoll@
908gl_GNULIB_ENABLED_strtoull = @gl_GNULIB_ENABLED_strtoull@
909gl_GNULIB_ENABLED_tempname = @gl_GNULIB_ENABLED_tempname@ 908gl_GNULIB_ENABLED_tempname = @gl_GNULIB_ENABLED_tempname@
910gl_LIBOBJS = @gl_LIBOBJS@ 909gl_LIBOBJS = @gl_LIBOBJS@
911gl_LTLIBOBJS = @gl_LTLIBOBJS@ 910gl_LTLIBOBJS = @gl_LTLIBOBJS@
@@ -2507,30 +2506,6 @@ EXTRA_libgnu_a_SOURCES += strtol.c strtoll.c
2507endif 2506endif
2508## end gnulib module strtoll 2507## end gnulib module strtoll
2509 2508
2510## begin gnulib module strtoull
2511ifeq (,$(OMIT_GNULIB_MODULE_strtoull))
2512
2513ifneq (,$(gl_GNULIB_ENABLED_strtoull))
2514
2515endif
2516EXTRA_DIST += strtol.c strtoul.c strtoull.c
2517
2518EXTRA_libgnu_a_SOURCES += strtol.c strtoul.c strtoull.c
2519
2520endif
2521## end gnulib module strtoull
2522
2523## begin gnulib module strtoumax
2524ifeq (,$(OMIT_GNULIB_MODULE_strtoumax))
2525
2526
2527EXTRA_DIST += strtoimax.c strtoumax.c
2528
2529EXTRA_libgnu_a_SOURCES += strtoimax.c strtoumax.c
2530
2531endif
2532## end gnulib module strtoumax
2533
2534## begin gnulib module symlink 2509## begin gnulib module symlink
2535ifeq (,$(OMIT_GNULIB_MODULE_symlink)) 2510ifeq (,$(OMIT_GNULIB_MODULE_symlink))
2536 2511
diff --git a/lib/strtoul.c b/lib/strtoul.c
deleted file mode 100644
index c4974e069e5..00000000000
--- a/lib/strtoul.c
+++ /dev/null
@@ -1,19 +0,0 @@
1/* Copyright (C) 1991, 1997, 2009-2017 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
16
17#define UNSIGNED 1
18
19#include "strtol.c"
diff --git a/lib/strtoull.c b/lib/strtoull.c
deleted file mode 100644
index 51ae3acb03c..00000000000
--- a/lib/strtoull.c
+++ /dev/null
@@ -1,26 +0,0 @@
1/* Function to parse an 'unsigned long long int' from text.
2 Copyright (C) 1995-1997, 1999, 2009-2017 Free Software Foundation, Inc.
3 NOTE: The canonical source of this file is maintained with the GNU C
4 Library. Bugs can be reported to bug-glibc@gnu.org.
5
6 This program is free software: you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3 of the License, or any
9 later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18
19#define QUAD 1
20
21#include "strtoul.c"
22
23#ifdef _LIBC
24strong_alias (__strtoull_internal, __strtouq_internal)
25weak_alias (strtoull, strtouq)
26#endif
diff --git a/lib/strtoumax.c b/lib/strtoumax.c
deleted file mode 100644
index dc395d626ab..00000000000
--- a/lib/strtoumax.c
+++ /dev/null
@@ -1,2 +0,0 @@
1#define UNSIGNED 1
2#include "strtoimax.c"
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index 3f196d4f1de..8f53a990e34 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -140,8 +140,6 @@ AC_DEFUN([gl_EARLY],
140 # Code from module string: 140 # Code from module string:
141 # Code from module strtoimax: 141 # Code from module strtoimax:
142 # Code from module strtoll: 142 # Code from module strtoll:
143 # Code from module strtoull:
144 # Code from module strtoumax:
145 # Code from module symlink: 143 # Code from module symlink:
146 # Code from module sys_select: 144 # Code from module sys_select:
147 # Code from module sys_stat: 145 # Code from module sys_stat:
@@ -364,12 +362,6 @@ AC_DEFUN([gl_INIT],
364 gl_PREREQ_STRTOIMAX 362 gl_PREREQ_STRTOIMAX
365 fi 363 fi
366 gl_INTTYPES_MODULE_INDICATOR([strtoimax]) 364 gl_INTTYPES_MODULE_INDICATOR([strtoimax])
367 gl_FUNC_STRTOUMAX
368 if test $HAVE_DECL_STRTOUMAX = 0 || test $REPLACE_STRTOUMAX = 1; then
369 AC_LIBOBJ([strtoumax])
370 gl_PREREQ_STRTOUMAX
371 fi
372 gl_INTTYPES_MODULE_INDICATOR([strtoumax])
373 gl_FUNC_SYMLINK 365 gl_FUNC_SYMLINK
374 if test $HAVE_SYMLINK = 0 || test $REPLACE_SYMLINK = 1; then 366 if test $HAVE_SYMLINK = 0 || test $REPLACE_SYMLINK = 1; then
375 AC_LIBOBJ([symlink]) 367 AC_LIBOBJ([symlink])
@@ -420,7 +412,6 @@ AC_DEFUN([gl_INIT],
420 gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c=false 412 gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c=false
421 gl_gnulib_enabled_secure_getenv=false 413 gl_gnulib_enabled_secure_getenv=false
422 gl_gnulib_enabled_strtoll=false 414 gl_gnulib_enabled_strtoll=false
423 gl_gnulib_enabled_strtoull=false
424 gl_gnulib_enabled_tempname=false 415 gl_gnulib_enabled_tempname=false
425 gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec=false 416 gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec=false
426 func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b () 417 func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b ()
@@ -569,18 +560,6 @@ AC_DEFUN([gl_INIT],
569 gl_gnulib_enabled_strtoll=true 560 gl_gnulib_enabled_strtoll=true
570 fi 561 fi
571 } 562 }
572 func_gl_gnulib_m4code_strtoull ()
573 {
574 if ! $gl_gnulib_enabled_strtoull; then
575 gl_FUNC_STRTOULL
576 if test $HAVE_STRTOULL = 0; then
577 AC_LIBOBJ([strtoull])
578 gl_PREREQ_STRTOULL
579 fi
580 gl_STDLIB_MODULE_INDICATOR([strtoull])
581 gl_gnulib_enabled_strtoull=true
582 fi
583 }
584 func_gl_gnulib_m4code_tempname () 563 func_gl_gnulib_m4code_tempname ()
585 { 564 {
586 if ! $gl_gnulib_enabled_tempname; then 565 if ! $gl_gnulib_enabled_tempname; then
@@ -649,9 +628,6 @@ AC_DEFUN([gl_INIT],
649 if { test $HAVE_DECL_STRTOIMAX = 0 || test $REPLACE_STRTOIMAX = 1; } && test $ac_cv_type_long_long_int = yes; then 628 if { test $HAVE_DECL_STRTOIMAX = 0 || test $REPLACE_STRTOIMAX = 1; } && test $ac_cv_type_long_long_int = yes; then
650 func_gl_gnulib_m4code_strtoll 629 func_gl_gnulib_m4code_strtoll
651 fi 630 fi
652 if { test $HAVE_DECL_STRTOUMAX = 0 || test $REPLACE_STRTOUMAX = 1; } && test $ac_cv_type_unsigned_long_long_int = yes; then
653 func_gl_gnulib_m4code_strtoull
654 fi
655 if test $HAVE_TIMEGM = 0 || test $REPLACE_TIMEGM = 1; then 631 if test $HAVE_TIMEGM = 0 || test $REPLACE_TIMEGM = 1; then
656 func_gl_gnulib_m4code_5264294aa0a5557541b53c8c741f7f31 632 func_gl_gnulib_m4code_5264294aa0a5557541b53c8c741f7f31
657 fi 633 fi
@@ -670,7 +646,6 @@ AC_DEFUN([gl_INIT],
670 AM_CONDITIONAL([gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c], [$gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c]) 646 AM_CONDITIONAL([gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c], [$gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c])
671 AM_CONDITIONAL([gl_GNULIB_ENABLED_secure_getenv], [$gl_gnulib_enabled_secure_getenv]) 647 AM_CONDITIONAL([gl_GNULIB_ENABLED_secure_getenv], [$gl_gnulib_enabled_secure_getenv])
672 AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoll], [$gl_gnulib_enabled_strtoll]) 648 AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoll], [$gl_gnulib_enabled_strtoll])
673 AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoull], [$gl_gnulib_enabled_strtoull])
674 AM_CONDITIONAL([gl_GNULIB_ENABLED_tempname], [$gl_gnulib_enabled_tempname]) 649 AM_CONDITIONAL([gl_GNULIB_ENABLED_tempname], [$gl_gnulib_enabled_tempname])
675 AM_CONDITIONAL([gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec], [$gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec]) 650 AM_CONDITIONAL([gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec], [$gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec])
676 # End of code from modules 651 # End of code from modules
@@ -940,9 +915,6 @@ AC_DEFUN([gl_FILE_LIST], [
940 lib/strtoimax.c 915 lib/strtoimax.c
941 lib/strtol.c 916 lib/strtol.c
942 lib/strtoll.c 917 lib/strtoll.c
943 lib/strtoul.c
944 lib/strtoull.c
945 lib/strtoumax.c
946 lib/symlink.c 918 lib/symlink.c
947 lib/sys_select.in.h 919 lib/sys_select.in.h
948 lib/sys_stat.in.h 920 lib/sys_stat.in.h
@@ -1051,8 +1023,6 @@ AC_DEFUN([gl_FILE_LIST], [
1051 m4/string_h.m4 1023 m4/string_h.m4
1052 m4/strtoimax.m4 1024 m4/strtoimax.m4
1053 m4/strtoll.m4 1025 m4/strtoll.m4
1054 m4/strtoull.m4
1055 m4/strtoumax.m4
1056 m4/symlink.m4 1026 m4/symlink.m4
1057 m4/sys_select_h.m4 1027 m4/sys_select_h.m4
1058 m4/sys_socket_h.m4 1028 m4/sys_socket_h.m4
diff --git a/m4/strtoull.m4 b/m4/strtoull.m4
deleted file mode 100644
index c6b215072b6..00000000000
--- a/m4/strtoull.m4
+++ /dev/null
@@ -1,24 +0,0 @@
1# strtoull.m4 serial 7
2dnl Copyright (C) 2002, 2004, 2006, 2008-2017 Free Software Foundation, Inc.
3dnl This file is free software; the Free Software Foundation
4dnl gives unlimited permission to copy and/or distribute it,
5dnl with or without modifications, as long as this notice is preserved.
6
7AC_DEFUN([gl_FUNC_STRTOULL],
8[
9 AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
10 dnl We don't need (and can't compile) the replacement strtoull
11 dnl unless the type 'unsigned long long int' exists.
12 AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT])
13 if test "$ac_cv_type_unsigned_long_long_int" = yes; then
14 AC_CHECK_FUNCS([strtoull])
15 if test $ac_cv_func_strtoull = no; then
16 HAVE_STRTOULL=0
17 fi
18 fi
19])
20
21# Prerequisites of lib/strtoull.c.
22AC_DEFUN([gl_PREREQ_STRTOULL], [
23 :
24])
diff --git a/m4/strtoumax.m4 b/m4/strtoumax.m4
deleted file mode 100644
index 43ef5b5abbf..00000000000
--- a/m4/strtoumax.m4
+++ /dev/null
@@ -1,28 +0,0 @@
1# strtoumax.m4 serial 12
2dnl Copyright (C) 2002-2004, 2006, 2009-2017 Free Software Foundation, Inc.
3dnl This file is free software; the Free Software Foundation
4dnl gives unlimited permission to copy and/or distribute it,
5dnl with or without modifications, as long as this notice is preserved.
6
7AC_DEFUN([gl_FUNC_STRTOUMAX],
8[
9 AC_REQUIRE([gl_INTTYPES_H_DEFAULTS])
10
11 dnl On OSF/1 5.1 with cc, this function is declared but not defined.
12 AC_CHECK_FUNCS_ONCE([strtoumax])
13 AC_CHECK_DECLS_ONCE([strtoumax])
14 if test "$ac_cv_have_decl_strtoumax" = yes; then
15 if test "$ac_cv_func_strtoumax" != yes; then
16 # HP-UX 11.11 has "#define strtoimax(...) ..." but no function.
17 REPLACE_STRTOUMAX=1
18 fi
19 else
20 HAVE_DECL_STRTOUMAX=0
21 fi
22])
23
24# Prerequisites of lib/strtoumax.c.
25AC_DEFUN([gl_PREREQ_STRTOUMAX], [
26 AC_CHECK_DECLS([strtoull])
27 AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT])
28])
diff --git a/src/editfns.c b/src/editfns.c
index 98187df5d97..1dbae8f5d4b 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -3851,6 +3851,23 @@ usage: (propertize STRING &rest PROPERTIES) */)
3851 return string; 3851 return string;
3852} 3852}
3853 3853
3854/* Convert the prefix of STR from ASCII decimal digits to a number.
3855 Set *STR_END to the address of the first non-digit. Return the
3856 number, or PTRDIFF_MAX on overflow. Return 0 if there is no number.
3857 This is like strtol for ptrdiff_t and base 10 and C locale,
3858 except without negative numbers or errno. */
3859
3860static ptrdiff_t
3861str2num (char *str, char **str_end)
3862{
3863 ptrdiff_t n = 0;
3864 for (; c_isdigit (*str); str++)
3865 if (INT_MULTIPLY_WRAPV (n, 10, &n) || INT_ADD_WRAPV (n, *str - '0', &n))
3866 n = PTRDIFF_MAX;
3867 *str_end = str;
3868 return n;
3869}
3870
3854DEFUN ("format", Fformat, Sformat, 1, MANY, 0, 3871DEFUN ("format", Fformat, Sformat, 1, MANY, 0,
3855 doc: /* Format a string out of a format-string and arguments. 3872 doc: /* Format a string out of a format-string and arguments.
3856The first argument is a format control string. 3873The first argument is a format control string.
@@ -4057,17 +4074,16 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
4057 digits to print after the '.' for floats, or the max. 4074 digits to print after the '.' for floats, or the max.
4058 number of chars to print from a string. */ 4075 number of chars to print from a string. */
4059 4076
4060 uintmax_t num; 4077 ptrdiff_t num;
4061 char *num_end; 4078 char *num_end;
4062 if (c_isdigit (*format)) 4079 if (c_isdigit (*format))
4063 { 4080 {
4064 num = strtoumax (format, &num_end, 10); 4081 num = str2num (format, &num_end);
4065 if (*num_end == '$') 4082 if (*num_end == '$')
4066 { 4083 {
4067 if (num == 0) 4084 if (num == 0)
4068 error ("Invalid format field number 0"); 4085 error ("Invalid format field number 0");
4069 n = min (num, PTRDIFF_MAX); 4086 n = num - 1;
4070 n--;
4071 format = num_end + 1; 4087 format = num_end + 1;
4072 } 4088 }
4073 } 4089 }
@@ -4095,15 +4111,15 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
4095 space_flag &= ! plus_flag; 4111 space_flag &= ! plus_flag;
4096 zero_flag &= ! minus_flag; 4112 zero_flag &= ! minus_flag;
4097 4113
4098 num = strtoumax (format, &num_end, 10); 4114 num = str2num (format, &num_end);
4099 if (max_bufsize <= num) 4115 if (max_bufsize <= num)
4100 string_overflow (); 4116 string_overflow ();
4101 ptrdiff_t field_width = num; 4117 ptrdiff_t field_width = num;
4102 4118
4103 bool precision_given = *num_end == '.'; 4119 bool precision_given = *num_end == '.';
4104 uintmax_t precision = (precision_given 4120 ptrdiff_t precision = (precision_given
4105 ? strtoumax (num_end + 1, &num_end, 10) 4121 ? str2num (num_end + 1, &num_end)
4106 : UINTMAX_MAX); 4122 : PTRDIFF_MAX);
4107 format = num_end; 4123 format = num_end;
4108 4124
4109 if (format == end) 4125 if (format == end)
@@ -4176,7 +4192,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
4176 /* handle case (precision[n] >= 0) */ 4192 /* handle case (precision[n] >= 0) */
4177 4193
4178 ptrdiff_t prec = -1; 4194 ptrdiff_t prec = -1;
4179 if (precision_given && precision <= TYPE_MAXIMUM (ptrdiff_t)) 4195 if (precision_given)
4180 prec = precision; 4196 prec = precision;
4181 4197
4182 /* lisp_string_width ignores a precision of 0, but GNU 4198 /* lisp_string_width ignores a precision of 0, but GNU
@@ -4424,8 +4440,9 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
4424 padding and excess precision. Deal with excess precision 4440 padding and excess precision. Deal with excess precision
4425 first. This happens only when the format specifies 4441 first. This happens only when the format specifies
4426 ridiculously large precision. */ 4442 ridiculously large precision. */
4427 uintmax_t excess_precision = precision - prec; 4443 ptrdiff_t excess_precision
4428 uintmax_t leading_zeros = 0, trailing_zeros = 0; 4444 = precision_given ? precision - prec : 0;
4445 ptrdiff_t leading_zeros = 0, trailing_zeros = 0;
4429 if (excess_precision) 4446 if (excess_precision)
4430 { 4447 {
4431 if (float_conversion) 4448 if (float_conversion)
@@ -4451,7 +4468,9 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
4451 4468
4452 /* Compute the total bytes needed for this item, including 4469 /* Compute the total bytes needed for this item, including
4453 excess precision and padding. */ 4470 excess precision and padding. */
4454 uintmax_t numwidth = sprintf_bytes + excess_precision; 4471 ptrdiff_t numwidth;
4472 if (INT_ADD_WRAPV (sprintf_bytes, excess_precision, &numwidth))
4473 numwidth = PTRDIFF_MAX;
4455 ptrdiff_t padding 4474 ptrdiff_t padding
4456 = numwidth < field_width ? field_width - numwidth : 0; 4475 = numwidth < field_width ? field_width - numwidth : 0;
4457 if (max_bufsize - sprintf_bytes <= excess_precision 4476 if (max_bufsize - sprintf_bytes <= excess_precision
diff --git a/src/lread.c b/src/lread.c
index 368b86e8189..f8493982c67 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -3495,25 +3495,18 @@ substitute_in_interval (INTERVAL interval, Lisp_Object arg)
3495} 3495}
3496 3496
3497 3497
3498#define LEAD_INT 1 3498/* Convert STRING to a number, assuming base BASE. Return a fixnum if
3499#define DOT_CHAR 2 3499 STRING has integer syntax and fits in a fixnum, else return the
3500#define TRAIL_INT 4 3500 nearest float if STRING has either floating point or integer syntax
3501#define E_EXP 16 3501 and BASE is 10, else return nil. If IGNORE_TRAILING, consider just
3502 3502 the longest prefix of STRING that has valid floating point syntax.
3503 3503 Signal an overflow if BASE is not 10 and the number has integer
3504/* Convert STRING to a number, assuming base BASE. Return a fixnum if CP has 3504 syntax but does not fit. */
3505 integer syntax and fits in a fixnum, else return the nearest float if CP has
3506 either floating point or integer syntax and BASE is 10, else return nil. If
3507 IGNORE_TRAILING, consider just the longest prefix of CP that has
3508 valid floating point syntax. Signal an overflow if BASE is not 10 and the
3509 number has integer syntax but does not fit. */
3510 3505
3511Lisp_Object 3506Lisp_Object
3512string_to_number (char const *string, int base, bool ignore_trailing) 3507string_to_number (char const *string, int base, bool ignore_trailing)
3513{ 3508{
3514 int state;
3515 char const *cp = string; 3509 char const *cp = string;
3516 int leading_digit;
3517 bool float_syntax = 0; 3510 bool float_syntax = 0;
3518 double value = 0; 3511 double value = 0;
3519 3512
@@ -3525,15 +3518,23 @@ string_to_number (char const *string, int base, bool ignore_trailing)
3525 bool signedp = negative || *cp == '+'; 3518 bool signedp = negative || *cp == '+';
3526 cp += signedp; 3519 cp += signedp;
3527 3520
3528 state = 0; 3521 enum { INTOVERFLOW = 1, LEAD_INT = 2, DOT_CHAR = 4, TRAIL_INT = 8,
3529 3522 E_EXP = 16 };
3530 leading_digit = digit_to_number (*cp, base); 3523 int state = 0;
3524 int leading_digit = digit_to_number (*cp, base);
3525 uintmax_t n = leading_digit;
3531 if (leading_digit >= 0) 3526 if (leading_digit >= 0)
3532 { 3527 {
3533 state |= LEAD_INT; 3528 state |= LEAD_INT;
3534 do 3529 for (int digit; 0 <= (digit = digit_to_number (*++cp, base)); )
3535 ++cp; 3530 {
3536 while (digit_to_number (*cp, base) >= 0); 3531 if (INT_MULTIPLY_OVERFLOW (n, base))
3532 state |= INTOVERFLOW;
3533 n *= base;
3534 if (INT_ADD_OVERFLOW (n, digit))
3535 state |= INTOVERFLOW;
3536 n += digit;
3537 }
3537 } 3538 }
3538 if (*cp == '.') 3539 if (*cp == '.')
3539 { 3540 {
@@ -3583,32 +3584,22 @@ string_to_number (char const *string, int base, bool ignore_trailing)
3583 } 3584 }
3584 3585
3585 float_syntax = ((state & (DOT_CHAR|TRAIL_INT)) == (DOT_CHAR|TRAIL_INT) 3586 float_syntax = ((state & (DOT_CHAR|TRAIL_INT)) == (DOT_CHAR|TRAIL_INT)
3586 || state == (LEAD_INT|E_EXP)); 3587 || (state & ~INTOVERFLOW) == (LEAD_INT|E_EXP));
3587 } 3588 }
3588 3589
3589 /* Return nil if the number uses invalid syntax. If IGNORE_TRAILING, accept 3590 /* Return nil if the number uses invalid syntax. If IGNORE_TRAILING, accept
3590 any prefix that matches. Otherwise, the entire string must match. */ 3591 any prefix that matches. Otherwise, the entire string must match. */
3591 if (! (ignore_trailing 3592 if (! (ignore_trailing
3592 ? ((state & LEAD_INT) != 0 || float_syntax) 3593 ? ((state & LEAD_INT) != 0 || float_syntax)
3593 : (!*cp && ((state & ~DOT_CHAR) == LEAD_INT || float_syntax)))) 3594 : (!*cp && ((state & ~(INTOVERFLOW | DOT_CHAR)) == LEAD_INT
3595 || float_syntax))))
3594 return Qnil; 3596 return Qnil;
3595 3597
3596 /* If the number uses integer and not float syntax, and is in C-language 3598 /* If the number uses integer and not float syntax, and is in C-language
3597 range, use its value, preferably as a fixnum. */ 3599 range, use its value, preferably as a fixnum. */
3598 if (leading_digit >= 0 && ! float_syntax) 3600 if (leading_digit >= 0 && ! float_syntax)
3599 { 3601 {
3600 uintmax_t n; 3602 if (state & INTOVERFLOW)
3601
3602 /* Fast special case for single-digit integers. This also avoids a
3603 glitch when BASE is 16 and IGNORE_TRAILING, because in that
3604 case some versions of strtoumax accept numbers like "0x1" that Emacs
3605 does not allow. */
3606 if (digit_to_number (string[signedp + 1], base) < 0)
3607 return make_number (negative ? -leading_digit : leading_digit);
3608
3609 errno = 0;
3610 n = strtoumax (string + signedp, NULL, base);
3611 if (errno == ERANGE)
3612 { 3603 {
3613 /* Unfortunately there's no simple and accurate way to convert 3604 /* Unfortunately there's no simple and accurate way to convert
3614 non-base-10 numbers that are out of C-language range. */ 3605 non-base-10 numbers that are out of C-language range. */