diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2016-12-15 12:18:28 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2016-12-15 12:19:45 -0800 |
commit | 5942af614133000a42b3b11f963a30c2b987272e (patch) | |
tree | 4ae569cc45e976bc4c6dca75088df6fadcf00d99 | |
parent | b80485f6810041a12c84953c59bb6cd956d358c6 (diff) | |
download | emacs-5942af614133000a42b3b11f963a30c2b987272e.tar.gz |
Merge from gnulib
This incorporates:
2016-12-14 xalloc-oversized: check for PTRDIFF_MAX too
2016-12-12 fpending: port to native Windows with MSVC
* .gitignore: Do not ignore lib/stdio-impl.h.
* lib/fpending.c, lib/xalloc-oversized.h, m4/fpending.m4:
Copy from gnulib.
* lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate.
* lib/stdio-impl.h:
New file, copied from gnulib.
* nt/gnulib.mk (EXTRA_DIST): Add stdio-impl.h.
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | lib/fpending.c | 32 | ||||
-rw-r--r-- | lib/gnulib.mk | 2 | ||||
-rw-r--r-- | lib/stdio-impl.h | 140 | ||||
-rw-r--r-- | lib/xalloc-oversized.h | 33 | ||||
-rw-r--r-- | m4/fpending.m4 | 67 | ||||
-rw-r--r-- | m4/gnulib-comp.m4 | 2 | ||||
-rw-r--r-- | nt/gnulib.mk | 2 |
8 files changed, 196 insertions, 83 deletions
diff --git a/.gitignore b/.gitignore index 15f9c5699cd..1de15a1c092 100644 --- a/.gitignore +++ b/.gitignore @@ -71,6 +71,7 @@ lib/limits.h lib/signal.h lib/std*.h !lib/std*.in.h +!lib/stdio-impl.h lib/string.h lib/sys/ lib/time.h diff --git a/lib/fpending.c b/lib/fpending.c index a503b9f53ae..ce93604e518 100644 --- a/lib/fpending.c +++ b/lib/fpending.c @@ -19,12 +19,42 @@ #include <config.h> +/* Specification. */ #include "fpending.h" +#include "stdio-impl.h" + /* Return the number of pending (aka buffered, unflushed) bytes on the stream, FP, that is open for writing. */ size_t __fpending (FILE *fp) { - return PENDING_OUTPUT_N_BYTES; + /* Most systems provide FILE as a struct and the necessary bitmask in + <stdio.h>, because they need it for implementing getc() and putc() as + fast macros. */ +#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + return fp->_IO_write_ptr - fp->_IO_write_base; +#elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ + /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Android */ + return fp->_p - fp->_bf._base; +#elif defined __EMX__ /* emx+gcc */ + return fp->_ptr - fp->_buffer; +#elif defined __minix /* Minix */ + return fp_->_ptr - fp_->_buf; +#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, MSVC, NonStop Kernel */ + return (fp_->_ptr ? fp_->_ptr - fp_->_base : 0); +#elif defined __UCLIBC__ /* uClibc */ + return (fp->__modeflags & __FLAG_WRITING ? fp->__bufpos - fp->__bufstart : 0); +#elif defined __QNX__ /* QNX */ + return (fp->_Mode & 0x2000 /*_MWRITE*/ ? fp->_Next - fp->_Buf : 0); +#elif defined __MINT__ /* Atari FreeMiNT */ + return fp->__bufp - fp->__buffer; +#elif defined EPLAN9 /* Plan9 */ + return fp->wp - fp->buf; +#elif defined __VMS /* VMS */ + return (*fp)->_ptr - (*fp)->_base; +#else +# error "Please port gnulib fpending.c to your platform!" + return 1; +#endif } diff --git a/lib/gnulib.mk b/lib/gnulib.mk index 56c210961a7..0399abc2104 100644 --- a/lib/gnulib.mk +++ b/lib/gnulib.mk @@ -459,7 +459,7 @@ EXTRA_DIST += flexmember.h ## begin gnulib module fpending -EXTRA_DIST += fpending.c fpending.h +EXTRA_DIST += fpending.c fpending.h stdio-impl.h EXTRA_libgnu_a_SOURCES += fpending.c diff --git a/lib/stdio-impl.h b/lib/stdio-impl.h new file mode 100644 index 00000000000..766d6936590 --- /dev/null +++ b/lib/stdio-impl.h @@ -0,0 +1,140 @@ +/* Implementation details of FILE streams. + Copyright (C) 2007-2008, 2010-2016 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* Many stdio implementations have the same logic and therefore can share + the same implementation of stdio extension API, except that some fields + have different naming conventions, or their access requires some casts. */ + + +/* BSD stdio derived implementations. */ + +#if defined __NetBSD__ /* NetBSD */ +/* Get __NetBSD_Version__. */ +# include <sys/param.h> +#endif + +#include <errno.h> /* For detecting Plan9. */ + +#if defined __sferror || defined __DragonFly__ || defined __ANDROID__ + /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Android */ + +# if defined __DragonFly__ /* DragonFly */ + /* See <http://www.dragonflybsd.org/cvsweb/src/lib/libc/stdio/priv_stdio.h?rev=HEAD&content-type=text/x-cvsweb-markup>. */ +# define fp_ ((struct { struct __FILE_public pub; \ + struct { unsigned char *_base; int _size; } _bf; \ + void *cookie; \ + void *_close; \ + void *_read; \ + void *_seek; \ + void *_write; \ + struct { unsigned char *_base; int _size; } _ub; \ + int _ur; \ + unsigned char _ubuf[3]; \ + unsigned char _nbuf[1]; \ + struct { unsigned char *_base; int _size; } _lb; \ + int _blksize; \ + fpos_t _offset; \ + /* More fields, not relevant here. */ \ + } *) fp) + /* See <http://www.dragonflybsd.org/cvsweb/src/include/stdio.h?rev=HEAD&content-type=text/x-cvsweb-markup>. */ +# define _p pub._p +# define _flags pub._flags +# define _r pub._r +# define _w pub._w +# else +# define fp_ fp +# endif + +# if (defined __NetBSD__ && __NetBSD_Version__ >= 105270000) || defined __OpenBSD__ || defined __ANDROID__ /* NetBSD >= 1.5ZA, OpenBSD, Android */ + /* See <http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> + and <http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> */ + struct __sfileext + { + struct __sbuf _ub; /* ungetc buffer */ + /* More fields, not relevant here. */ + }; +# define fp_ub ((struct __sfileext *) fp->_ext._base)->_ub +# else /* FreeBSD, NetBSD <= 1.5Z, DragonFly, Mac OS X, Cygwin, Android */ +# define fp_ub fp_->_ub +# endif + +# define HASUB(fp) (fp_ub._base != NULL) + +#endif + + +/* SystemV derived implementations. */ + +#ifdef __TANDEM /* NonStop Kernel */ +# ifndef _IOERR +/* These values were determined by the program 'stdioext-flags' at + <http://lists.gnu.org/archive/html/bug-gnulib/2010-12/msg00165.html>. */ +# define _IOERR 0x40 +# define _IOREAD 0x80 +# define _IOWRT 0x4 +# define _IORW 0x100 +# endif +#endif + +#if defined _IOERR + +# if defined __sun && defined _LP64 /* Solaris/{SPARC,AMD64} 64-bit */ +# define fp_ ((struct { unsigned char *_ptr; \ + unsigned char *_base; \ + unsigned char *_end; \ + long _cnt; \ + int _file; \ + unsigned int _flag; \ + } *) fp) +# else +# define fp_ fp +# endif + +# if defined _SCO_DS /* OpenServer */ +# define _cnt __cnt +# define _ptr __ptr +# define _base __base +# define _flag __flag +# endif + +#elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ /* newer Windows with MSVC */ + +/* <stdio.h> does not define the innards of FILE any more. */ +# define WINDOWS_OPAQUE_FILE + +struct _gl_real_FILE +{ + /* Note: Compared to older Windows and to mingw, it has the fields + _base and _cnt swapped. */ + unsigned char *_ptr; + unsigned char *_base; + int _cnt; + int _flag; + int _file; + int _charbuf; + int _bufsiz; +}; +# define fp_ ((struct _gl_real_FILE *) fp) + +/* These values were determined by a program similar to the one at + <http://lists.gnu.org/archive/html/bug-gnulib/2010-12/msg00165.html>. */ +# define _IOREAD 0x1 +# define _IOWRT 0x2 +# define _IORW 0x4 +# define _IOEOF 0x8 +# define _IOERR 0x10 + +#endif diff --git a/lib/xalloc-oversized.h b/lib/xalloc-oversized.h index 53e6556c610..503bb37801b 100644 --- a/lib/xalloc-oversized.h +++ b/lib/xalloc-oversized.h @@ -19,32 +19,36 @@ #define XALLOC_OVERSIZED_H_ #include <stddef.h> +#include <stdint.h> /* Default for (non-Clang) compilers that lack __has_builtin. */ #ifndef __has_builtin # define __has_builtin(x) 0 #endif -/* True if N * S would overflow in a size calculation. +/* True if N * S would overflow in a size_t calculation, + or would generate a value larger than PTRDIFF_MAX. This expands to a constant expression if N and S are both constants. By gnulib convention, SIZE_MAX represents overflow in size - calculations, so the conservative dividend to use here is - SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value. - However, malloc (SIZE_MAX) fails on all known hosts where - sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for - exactly-SIZE_MAX allocations on such hosts; this avoids a test and - branch when S is known to be 1. */ + calculations, so the conservative size_t-based dividend to use here + is SIZE_MAX - 1. */ #define __xalloc_oversized(n, s) \ - ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n)) + ((size_t) (PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : SIZE_MAX - 1) / (s) < (n)) +#if PTRDIFF_MAX < SIZE_MAX +typedef ptrdiff_t __xalloc_count_type; +#else +typedef size_t __xalloc_count_type; +#endif -/* Return 1 if an array of N objects, each of size S, cannot exist due - to size arithmetic overflow. S must be positive and N must be - nonnegative. This is a macro, not a function, so that it - works correctly even when SIZE_MAX < N. */ +/* Return 1 if an array of N objects, each of size S, cannot exist + reliably due to size or ptrdiff_t arithmetic overflow. S must be + positive and N must be nonnegative. This is a macro, not a + function, so that it works correctly even when SIZE_MAX < N. */ #if 7 <= __GNUC__ || __has_builtin (__builtin_add_overflow_p) -# define xalloc_oversized(n, s) __builtin_mul_overflow_p (n, s, (size_t) 1) +# define xalloc_oversized(n, s) \ + __builtin_mul_overflow_p (n, s, (__xalloc_count_type) 1) #elif ((5 <= __GNUC__ \ || (__has_builtin (__builtin_mul_overflow) \ && __has_builtin (__builtin_constant_p))) \ @@ -52,7 +56,8 @@ # define xalloc_oversized(n, s) \ (__builtin_constant_p (n) && __builtin_constant_p (s) \ ? __xalloc_oversized (n, s) \ - : ({ size_t __xalloc_size; __builtin_mul_overflow (n, s, &__xalloc_size); })) + : ({ __xalloc_count_type __xalloc_count; \ + __builtin_mul_overflow (n, s, &__xalloc_count); })) /* Other compilers use integer division; this may be slower but is more portable. */ diff --git a/m4/fpending.m4 b/m4/fpending.m4 index a446156df2f..f6776a83e69 100644 --- a/m4/fpending.m4 +++ b/m4/fpending.m4 @@ -1,4 +1,4 @@ -# serial 21 +# serial 22 # Copyright (C) 2000-2001, 2004-2016 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation @@ -11,7 +11,7 @@ dnl and Ulrich Drepper. dnl Find out how to determine the number of pending output bytes on a stream. dnl glibc (2.1.93 and newer) and Solaris provide __fpending. On other systems, -dnl we have to grub around in the FILE struct. +dnl we have to grub around in the (possibly opaque) FILE struct. AC_DEFUN([gl_FUNC_FPENDING], [ @@ -34,66 +34,3 @@ AC_DEFUN([gl_FUNC_FPENDING], AC_CHECK_DECLS([__fpending], [], [], [$fp_headers]) fi ]) - -AC_DEFUN([gl_PREREQ_FPENDING], -[ - AC_CACHE_CHECK( - [how to determine the number of pending output bytes on a stream], - ac_cv_sys_pending_output_n_bytes, - [ - for ac_expr in \ - \ - '# glibc2' \ - 'fp->_IO_write_ptr - fp->_IO_write_base' \ - \ - '# traditional Unix' \ - 'fp->_ptr - fp->_base' \ - \ - '# BSD' \ - 'fp->_p - fp->_bf._base' \ - \ - '# SCO, Unixware' \ - '(fp->__ptr ? fp->__ptr - fp->__base : 0)' \ - \ - '# QNX' \ - '(fp->_Mode & 0x2000 /*_MWRITE*/ ? fp->_Next - fp->_Buf : 0)' \ - \ - '# old glibc?' \ - 'fp->__bufp - fp->__buffer' \ - \ - '# old glibc iostream?' \ - 'fp->_pptr - fp->_pbase' \ - \ - '# emx+gcc' \ - 'fp->_ptr - fp->_buffer' \ - \ - '# Minix' \ - 'fp->_ptr - fp->_buf' \ - \ - '# Plan9' \ - 'fp->wp - fp->buf' \ - \ - '# VMS' \ - '(*fp)->_ptr - (*fp)->_base' \ - \ - '# e.g., DGUX R4.11; the info is not available' \ - 1 \ - ; do - - # Skip each embedded comment. - case "$ac_expr" in '#'*) continue;; esac - - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>]], - [[FILE *fp = stdin; (void) ($ac_expr);]])], - [fp_done=yes] - ) - test "$fp_done" = yes && break - done - - ac_cv_sys_pending_output_n_bytes=$ac_expr - ] - ) - AC_DEFINE_UNQUOTED([PENDING_OUTPUT_N_BYTES], - $ac_cv_sys_pending_output_n_bytes, - [the number of pending output bytes on stream 'fp']) -]) diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index 592543b88f5..171a3ef94e4 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -238,7 +238,6 @@ AC_DEFUN([gl_INIT], gl_FUNC_FPENDING if test $gl_cv_func___fpending = no; then AC_LIBOBJ([fpending]) - gl_PREREQ_FPENDING fi gl_FUNC_FSTATAT if test $HAVE_FSTATAT = 0 || test $REPLACE_FSTATAT = 1; then @@ -956,6 +955,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/stdalign.in.h lib/stddef.in.h lib/stdint.in.h + lib/stdio-impl.h lib/stdio.in.h lib/stdlib.in.h lib/stpcpy.c diff --git a/nt/gnulib.mk b/nt/gnulib.mk index 65b206e2fac..6d9fbcf0254 100644 --- a/nt/gnulib.mk +++ b/nt/gnulib.mk @@ -345,7 +345,7 @@ EXTRA_DIST += filevercmp.h ## begin gnulib module fpending -EXTRA_DIST += fpending.c fpending.h +EXTRA_DIST += fpending.c fpending.h stdio-impl.h EXTRA_libgnu_a_SOURCES += fpending.c |