[PATCH] Do not use inline in argp.h on FreeBSD

2014-07-25 Thread Andrey Borzenkov
This fixes this error:

In file included from util/grub-mkimage.c:54:0:
./grub-core/gnulib/argp.h:627:49: error: '__sbistype' is static but
used in inline function '_option_is_short' which is not static
[-Werror] cc1: all warnings being treated as errors gmake[2]: ***
[util/grub_mkimage-grub-mkimage.o] Error 1

Treat FreeBSD similar to Apple and do not try inlines. It currently
does it for GCC only, as this is what had been tested.

Reported-By: Beeblebrox 
Tested-By: Beeblebrox 
Signed-off-by: Andrey Borzenkov 

---
 m4/extern-inline.m4 | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/m4/extern-inline.m4 b/m4/extern-inline.m4
index 240150e..009b928 100644
--- a/m4/extern-inline.m4
+++ b/m4/extern-inline.m4
@@ -24,7 +24,10 @@ AC_DEFUN([gl_EXTERN_INLINE],
.
OS X 10.9 has a macro __header_inline indicating the bug is fixed for C and
for clang but remains for g++; see .
-   Perhaps Apple will fix this some day.  */
+   Perhaps Apple will fix this some day.
+
+   Suppress use of inlines on FreeBSD with GCC similar to Apple. It fails to
+   compile arpg.h due to static inlines in ctype.h  */
 #if (defined __APPLE__ \
  && (defined __header_inline \
  ? (defined __cplusplus && defined __GNUC_STDC_INLINE__ \
@@ -36,7 +39,8 @@ AC_DEFUN([gl_EXTERN_INLINE],
 # define _GL_EXTERN_INLINE_APPLE_BUG
 #endif
 #if ((__GNUC__ \
-  ? defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ \
+  ? (defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__) \
+ && !defined __FreeBSD__ \
   : (199901L <= __STDC_VERSION__ \
  && !defined __HP_cc \
  && !(defined __SUNPRO_C && __STDC__))) \
@@ -45,7 +49,7 @@ AC_DEFUN([gl_EXTERN_INLINE],
 # define _GL_EXTERN_INLINE extern inline
 # define _GL_EXTERN_INLINE_IN_USE
 #elif (2 < __GNUC__ + (7 <= __GNUC_MINOR__) && !defined __STRICT_ANSI__ \
-   && !defined _GL_EXTERN_INLINE_APPLE_BUG)
+   && !defined _GL_EXTERN_INLINE_APPLE_BUG && !defined __FreeBSD__)
 # if defined __GNUC_GNU_INLINE__ && __GNUC_GNU_INLINE__
/* __gnu_inline__ suppresses a GCC 4.2 diagnostic.  */
 #  define _GL_INLINE extern inline __attribute__ ((__gnu_inline__))
-- 
tg: (5acee27..) FreeBSD-ctype.h (depends on: master)



[PATCH 1/5] obstack tidy

2014-07-25 Thread Alan Modra
a) Delete nonsense about "not polluting the namespace with stddef.h
symbols" since string.h includes stddef.h a little later anyway.
b) Don't roll our own slow memcpy in _obstack_newchunk.
c) Rename obstack_free to _obstack_free.  This makes the naming consistent
   with other obstack functions and obviates the need for __obstack_free.
   Ancient obstack.c defined both obstack_free and _obstack_free.  We
   continue to do that for _LIBC via an alias.
d) Miscellaneous macro fixes.  The expression used to test for gcc-2.8 is
   clever, but will give a warning nowadays if simulating an old gcc with
   -U__GNUC__ -U__GNUC_MINOR__ -D__GNUC__=1.
e) Move error handling code, to avoid a forward declaration and to
   simplify later patches in this series.

* lib/obstack.h: Include stddef.h unconditionally and stdlib.h earlier.
(PTR_INT_TYPE): Delete, replace with ptrdiff_t.
(struct obstack ): Rename fields of union and update all uses.
(__obstack_free): Delete, update refs.
(_obstack_free): Rename from obstack_free.
(__extension__): Avoid undefined macro warning for __GNUC_MINOR__.
(obstack_object_size, obstack_room): Parenthesise !__GNUC__ versions.
* lib/obstack.c: Don't include stddef.h.
(COPYING_UNIT): Delete.
(_obstack_newchunk): Use memcpy to move existing object to new chunk.
(_obstack_free): Rename from __obstack_free, update alias.
(obstack_exit_failure, obstack_alloc_failed_handler, _obstack_compat):
Move later in file.
---
 lib/obstack.c |   97 -
 lib/obstack.h |   91 ++---
 2 files changed, 71 insertions(+), 117 deletions(-)

diff --git a/lib/obstack.c b/lib/obstack.c
index 598f6aa..f7cd4e5 100644
--- a/lib/obstack.c
+++ b/lib/obstack.c
@@ -47,12 +47,11 @@
 # endif
 #endif
 
-#include 
-
 #ifndef ELIDE_CODE
 
 
 # include 
+# include 
 
 /* Determine default alignment.  */
 union fooround
@@ -75,42 +74,6 @@ enum
   DEFAULT_ROUNDING = sizeof (union fooround)
 };
 
-/* When we copy a long block of data, this is the unit to do it with.
-   On some machines, copying successive ints does not work;
-   in such a case, redefine COPYING_UNIT to 'long' (if that works)
-   or 'char' as a last resort.  */
-# ifndef COPYING_UNIT
-#  define COPYING_UNIT int
-# endif
-
-
-/* The functions allocating more room by calling 'obstack_chunk_alloc'
-   jump to the handler pointed to by 'obstack_alloc_failed_handler'.
-   This can be set to a user defined function which should either
-   abort gracefully or use longjump - but shouldn't return.  This
-   variable by default points to the internal function
-   'print_and_abort'.  */
-static _Noreturn void print_and_abort (void);
-void (*obstack_alloc_failed_handler) (void) = print_and_abort;
-
-/* Exit value used when 'print_and_abort' is used.  */
-# include 
-# ifdef _LIBC
-int obstack_exit_failure = EXIT_FAILURE;
-# else
-#  include "exitfail.h"
-#  define obstack_exit_failure exit_failure
-# endif
-
-# ifdef _LIBC
-#  if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
-/* A looong time ago (before 1994, anyway; we're not sure) this global variable
-   was used by non-GNU-C macros to avoid multiple evaluation.  The GNU C
-   library still exports it because somebody might use it.  */
-struct obstack *_obstack_compat = 0;
-compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0);
-#  endif
-# endif
 
 /* Define a macro that either calls functions with the traditional malloc/free
calling interface, or calls functions with the mmalloc/mfree interface
@@ -248,8 +211,6 @@ _obstack_newchunk (struct obstack *h, int length)
   struct _obstack_chunk *new_chunk;
   long new_size;
   long obj_size = h->next_free - h->object_base;
-  long i;
-  long already;
   char *object_base;
 
   /* Compute size for new chunk.  */
@@ -269,25 +230,8 @@ _obstack_newchunk (struct obstack *h, int length)
   object_base =
 __PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask);
 
-  /* Move the existing object to the new chunk.
- Word at a time is fast and is safe if the object
- is sufficiently aligned.  */
-  if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
-{
-  for (i = obj_size / sizeof (COPYING_UNIT) - 1;
-   i >= 0; i--)
-((COPYING_UNIT *) object_base)[i]
-  = ((COPYING_UNIT *) h->object_base)[i];
-  /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
- but that can cross a page boundary on a machine
- which does not do strict alignment for COPYING_UNITS.  */
-  already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
-}
-  else
-already = 0;
-  /* Copy remaining bytes one by one.  */
-  for (i = already; i < obj_size; i++)
-object_base[i] = h->object_base[i];
+  /* Move the existing object to the new chunk.  */
+  memcpy (object_base, h->object_base, obj_size);

[PATCH 0/5] obstacks

2014-07-25 Thread Alan Modra
This patch series gives obstacks some much needed TLC.  The first patch
is mostly just a tidy, with one perhaps controversial change, renaming
the function obstack_free to _obstack_free.  This will be visible to
users who compile some code using a new obstack.h and try to link
against an old (but not ancient!) relocatable obstack.o.  They will
need to recompile their obstack.o.  Users linking against glibc won't
see a problem since glibc exports both _obstack_free and obstack_free.
I figure the number of people affected by this rename is small, and
note that gnulib made a change that would similarly affect linking
against relocatable object files when _obstack_free was removed..

The second and third patch get us to the point where 4G obstacks are
supported without significantly changing the ABI.  At this point some
code will need fixes, due to people wrongly using obstack internals.
For instance, gcc needs some changes like the following (which is
backward compatible with current libiberty obstacks):

Index: gcc/coretypes.h
===
--- gcc/coretypes.h (revision 212477)
+++ gcc/coretypes.h (working copy)
@@ -158,13 +158,13 @@ struct basic_block_def;
 typedef struct basic_block_def *basic_block;
 typedef const struct basic_block_def *const_basic_block;
 
-#define obstack_chunk_alloc((void *(*) (long)) xmalloc)
-#define obstack_chunk_free ((void (*) (void *)) free)
+#define obstack_chunk_allocxmalloc
+#define obstack_chunk_free free
 #define OBSTACK_CHUNK_SIZE 0
-#define gcc_obstack_init(OBSTACK)  \
-  _obstack_begin ((OBSTACK), OBSTACK_CHUNK_SIZE, 0,\
- obstack_chunk_alloc,  \
- obstack_chunk_free)
+#define gcc_obstack_init(OBSTACK)  \
+  obstack_specify_allocation ((OBSTACK), OBSTACK_CHUNK_SIZE, 0,\
+ obstack_chunk_alloc,  \
+ obstack_chunk_free)
 
 /* enum reg_class is target specific, so it should not appear in
target-independent code or interfaces, like the target hook declarations

gcc needs other fixes for existing upstream obstack changes,
obstack_base() now returns a void* where it previously returned a char*.

The fourth patch switches obstacks to use size_t for sizes, and
contains the necessary machinery for glibc to compile obstacks twice,
once for version 1 compatibiliy, and once for version 2.

The fifth patch avoids the necessity to install other gnulib headers
in libiberty, and importantly, avoids the need for a whole lot of
gnulib configury.  Running configure already takes signigicant time in
libiberty.  I don't want to double that time.

Alan Modra (5):
  obstack tidy
  64-bit obstack support, part 1
  64-bit obstack support, part 2
  64-bit obstack support, part 3
  obstack usability

 lib/obstack.c   |  275 ---
 lib/obstack.h   |  244 ++--
 modules/obstack |1 +
 3 files changed, 273 insertions(+), 247 deletions(-)




[PATCH] glibc 64-bit obstack support

2014-07-25 Thread Alan Modra
And >2G on 32-bit.

* include/gnu-versions.h (_GNU_OBSTACK_INTERFACE_VERSION): Bump.
* include/obstack.h: Add _obstack2_newchunk hidden proto.
* malloc/obstack.h: Import from gnulib.
* malloc/obstack.c: Likewise.
* malloc/obstackv1.c: New file.
* malloc/Makefile (routines): Add obstackv1.
(CFLAGS-obstackv1.c): Define.
(malloc/Versions): Add _obstack2 functions.
* config.h.in (SIZEOF_INT, SIZEOF_SIZE_T): Add.
* configure.in: AC_CHECK_SIZEOF int and size_t.
* configure: Regenerate.

diff --git a/config.h.in b/config.h.in
index 2dcd135..0996130 100644
--- a/config.h.in
+++ b/config.h.in
@@ -200,6 +200,12 @@
 /* Define if the linker defines __ehdr_start.  */
 #undef HAVE_EHDR_START
 
+/* The size of "int", as computed by sizeof.  */
+#undef SIZEOF_INT
+
+/* The size of "size_t", as computed by sizeof.  */
+#undef SIZEOF_SIZE_T
+
 /*
  */
 
diff --git a/configure.ac b/configure.ac
index 566ecb2..53ee319 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1824,6 +1824,10 @@ AC_CHECK_SIZEOF(long double, 0)
 sizeof_long_double=$ac_cv_sizeof_long_double
 AC_SUBST(sizeof_long_double)
 
+dnl Determine the size of int and size_t for obstack.h.
+AC_CHECK_SIZEOF([int])
+AC_CHECK_SIZEOF([size_t],,[#include ])
+
 CPPUNDEFS=
 dnl Check for silly hacked compilers predefining _FORTIFY_SOURCE.
 dnl Since we are building the implementations of the fortified functions here,
diff --git a/include/gnu-versions.h b/include/gnu-versions.h
index 6ffbd47..99caf5b 100644
--- a/include/gnu-versions.h
+++ b/include/gnu-versions.h
@@ -43,7 +43,7 @@
remember, if any of these versions change, the libc.so major version
number must change too (so avoid it)!  */
 
-#define _GNU_OBSTACK_INTERFACE_VERSION 1 /* vs malloc/obstack.c */
+#define _GNU_OBSTACK_INTERFACE_VERSION 2 /* vs malloc/obstack.c */
 #define _GNU_REGEX_INTERFACE_VERSION   1 /* vs posix/regex.c */
 #define _GNU_GLOB_INTERFACE_VERSION1 /* vs posix/glob.c */
 #define _GNU_GETOPT_INTERFACE_VERSION  2 /* vs posix/getopt.c and
diff --git a/include/obstack.h b/include/obstack.h
index 349d59b..655a853 100644
--- a/include/obstack.h
+++ b/include/obstack.h
@@ -1,3 +1,6 @@
 #include 
 
 libc_hidden_proto (_obstack_newchunk)
+#ifdef __OBSTACK_ALIAS_VER2
+libc_hidden_proto (_obstack2_newchunk)
+#endif
diff --git a/malloc/Makefile b/malloc/Makefile
index 9e93523..accc584 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -30,7 +30,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc 
tst-obstack \
 tst-pvalloc tst-memalign tst-mallopt
 test-srcs = tst-mtrace
 
-routines = malloc morecore mcheck mtrace obstack
+routines = malloc morecore mcheck mtrace obstack obstackv1
 
 install-lib := libmcheck.a
 non-lib.a := libmcheck.a
@@ -104,6 +104,7 @@ include ../Rules
 
 CFLAGS-mcheck-init.c = $(PIC-ccflag)
 CFLAGS-obstack.c = $(uses-callbacks)
+CFLAGS-obstackv1.c = $(uses-callbacks)
 
 $(objpfx)libmcheck.a: $(objpfx)mcheck-init.o
-rm -f $@
diff --git a/malloc/Versions b/malloc/Versions
index 7ca9bdf..09fb9dd 100644
--- a/malloc/Versions
+++ b/malloc/Versions
@@ -61,6 +61,10 @@ libc {
   GLIBC_2.16 {
 aligned_alloc;
   }
+  GLIBC_2.20 {
+_obstack2_allocated_p; _obstack2_begin; _obstack2_begin_1;
+_obstack2_free; _obstack2_memory_used; _obstack2_newchunk;
+  }
   GLIBC_PRIVATE {
 # Internal startup hook for libpthread.
 __libc_malloc_pthread_startup;
diff --git a/malloc/obstackv1.c b/malloc/obstackv1.c
new file mode 100644
index 000..65e82b5
--- /dev/null
+++ b/malloc/obstackv1.c
@@ -0,0 +1,2 @@
+#define __OBSTACK_INTERFACE_VERSION 1
+#include "obstack.c"



[PATCH 2/5] 64-bit obstack support, part 1

2014-07-25 Thread Alan Modra
a) Correct calls to alloc function, to use a size_t arg.  "long" is
   just wrong on targets like x86_64-mingw64 where "long" is 32 bits
   and "size_t" 64 bits.
b) Consolidate _obstack_begin and _obstack_begin1 code.

* lib/obstack.h (struct obstack ): Correct prototype to
use "size_t" rather than "long".
(_obstack_begin, _obstack_begin1): Likewise.
(obstack_init, obstack_begin, obstack_specify_allocation_with_arg,
obstack_chunkfun): Update alloc function casts.
* lib/obstack.c (CALL_CHUNKFUN): Update chunkfun cast.
(chunkfun_type, freefun_type): New typdefs.
(_obstack_begin_worker): Split out from ..
(_obstack_begin, _obstack_begin_1): ..here.  Correct chunkfun
prototype.
---
 lib/obstack.c |   77 +
 lib/obstack.h |   16 ++--
 2 files changed, 36 insertions(+), 57 deletions(-)

diff --git a/lib/obstack.c b/lib/obstack.c
index f7cd4e5..37cf5ae 100644
--- a/lib/obstack.c
+++ b/lib/obstack.c
@@ -84,7 +84,7 @@ enum
 # define CALL_CHUNKFUN(h, size) \
   (((h)->use_extra_arg)
  \
? (*(h)->chunkfun)((h)->extra_arg, (size))\
-   : (*(struct _obstack_chunk *(*)(long))(h)->chunkfun)((size)))
+   : (*(struct _obstack_chunk *(*)(size_t))(h)->chunkfun)((size)))
 
 # define CALL_FREEFUN(h, old_chunk) \
   do { \
@@ -103,11 +103,13 @@ enum
Return nonzero if successful, calls obstack_alloc_failed_handler if
allocation fails.  */
 
-int
-_obstack_begin (struct obstack *h,
-int size, int alignment,
-void *(*chunkfun) (long),
-void (*freefun) (void *))
+typedef struct _obstack_chunk * (*chunkfun_type) (void *, size_t);
+typedef void (*freefun_type) (void *, struct _obstack_chunk *);
+
+static int
+_obstack_begin_worker (struct obstack *h,
+   int size, int alignment,
+   chunkfun_type chunkfun, freefun_type freefun)
 {
   struct _obstack_chunk *chunk; /* points to new chunk */
 
@@ -130,11 +132,10 @@ _obstack_begin (struct obstack *h,
   size = 4096 - extra;
 }
 
-  h->chunkfun = (struct _obstack_chunk * (*) (void *, long)) chunkfun;
-  h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
+  h->chunkfun = chunkfun;
+  h->freefun = freefun;
   h->chunk_size = size;
   h->alignment_mask = alignment - 1;
-  h->use_extra_arg = 0;
 
   chunk = h->chunk = CALL_CHUNKFUN (h, h->chunk_size);
   if (!chunk)
@@ -151,51 +152,29 @@ _obstack_begin (struct obstack *h,
 }
 
 int
-_obstack_begin_1 (struct obstack *h, int size, int alignment,
-  void *(*chunkfun) (void *, long),
+_obstack_begin (struct obstack *h,
+int size, int alignment,
+void *(*chunkfun) (size_t),
+void (*freefun) (void *))
+{
+  h->use_extra_arg = 0;
+  return _obstack_begin_worker (h, size, alignment,
+(chunkfun_type) chunkfun,
+(freefun_type) freefun);
+}
+
+int
+_obstack_begin_1 (struct obstack *h,
+  int size, int alignment,
+  void *(*chunkfun) (void *, size_t),
   void (*freefun) (void *, void *),
   void *arg)
 {
-  struct _obstack_chunk *chunk; /* points to new chunk */
-
-  if (alignment == 0)
-alignment = DEFAULT_ALIGNMENT;
-  if (size == 0)
-/* Default size is what GNU malloc can fit in a 4096-byte block.  */
-{
-  /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
- Use the values for range checking, because if range checking is off,
- the extra bytes won't be missed terribly, but if range checking is on
- and we used a larger request, a whole extra 4096 bytes would be
- allocated.
-
- These number are irrelevant to the new GNU malloc.  I suspect it is
- less sensitive to the size of the request.  */
-  int extra = 12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
-+ 4 + DEFAULT_ROUNDING - 1)
-   & ~(DEFAULT_ROUNDING - 1));
-  size = 4096 - extra;
-}
-
-  h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
-  h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
-  h->chunk_size = size;
-  h->alignment_mask = alignment - 1;
   h->extra_arg = arg;
   h->use_extra_arg = 1;
-
-  chunk = h->chunk = CALL_CHUNKFUN (h, h->chunk_size);
-  if (!chunk)
-(*obstack_alloc_failed_handler) ();
-  h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
-   alignment - 1);
-  h->chunk_limit = chunk->limit
- = (char *) chunk + h->chunk_size;
-  chunk->prev = 0;
-  /* The initial chunk now contains no empty object.  */
-  h->maybe_empty_object = 0;
-  h->alloc_failed = 0;
-  return 1;
+  return _ob

[PATCH 4/5] 64-bit obstack support, part 3

2014-07-25 Thread Alan Modra
This finally enables full 64-bit obstack support.  Renaming the
_obstack_* functions to _obstack2_* is necessary to prevent a shared
library using version 1 obstack functions from having these functions
overridden by version 2 functions in the main executable.  Not all
shared libraries are created with as much care as glibc in this
regard.  Moving __OBSTACK_INTERFACE_VERSION to obstack.h allows glibc
to compile obstack.c twice, once to provide version 1 compat
functions, and once for 64-bit obstack support.  For 32-bit targets
where version 1 and version 2 code is ABI compatible, I've put
machinery in place so that we only get one copy of the obstack.c
functions.

* lib/obstack.h (__OBSTACK_INTERFACE_VERSION): Define.
(__OBSTACK_ELIDE_CODE): Define.
(__OBSTACK_ALIAS_VER2): Define.
(__OBSTACK_SIZE_T, __CHUNK_SIZE_T): Define as size_t for version 2.
(_obstack_allocated_p, _obstack_begin, _obstack_begin_1,
_obstack_free, _obstack_memory_used, _obstack_newchunk): Define
for version 2.
(_obstack2_begin, _obstack2_begin_1, _obstack2_free,
_obstack2_memory_used, _obstack2_newchunk): Declare function aliases.
* lib/obstack.c (__OBSTACK_INTERFACE_VERSION): Delete.
(ELIDE_CODE): Delete, test __OBSTACK_ELIDE_CODE instead.
(_obstack2_begin, _obstack2_begin_1, _obstack2_free,
_obstack2_memory_used, _obstack2_newchunk): Emit aliases for glibc.
(obstack_alloc_failed_handler, print_and_abort, _obstack_compat):
Arrange for libc to emit definitions only for one obstack version.
* module/obstack: Add obstack.o to libgnu.a.
---
 lib/obstack.c   |   88 ++-
 lib/obstack.h   |   74 --
 modules/obstack |1 +
 3 files changed, 115 insertions(+), 48 deletions(-)

diff --git a/lib/obstack.c b/lib/obstack.c
index 98b955e..1ac0e5d 100644
--- a/lib/obstack.c
+++ b/lib/obstack.c
@@ -25,30 +25,11 @@
 # include "obstack.h"
 #endif
 
-/* NOTE BEFORE MODIFYING THIS FILE: This version number must be
-   incremented whenever callers compiled using an old obstack.h can no
-   longer properly call the functions in this obstack.c.  */
-#define OBSTACK_INTERFACE_VERSION 1
-
-/* Comment out all this code if we are using the GNU C Library, and are not
-   actually compiling the library itself, and the installed library
-   supports the same library interface we do.  This code is part of the GNU
-   C Library, but also included in many other GNU distributions.  Compiling
-   and linking in this code is a waste when using the GNU C library
-   (especially if it is a shared library).  Rather than having every GNU
-   program understand 'configure --with-gnu-libc' and omit the object
-   files, it is simpler to just do this in the source for each such file.  */
-
-#include   /* Random thing to get __GNU_LIBRARY__.  */
-#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
-# include 
-# if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
-#  define ELIDE_CODE
-# endif
-#endif
-
-#ifndef ELIDE_CODE
+/* NOTE BEFORE MODIFYING THIS FILE: __OBSTACK_INTERFACE_VERSION in
+   obstack.h must be incremented whenever callers compiled using an old
+   obstack.h can no longer properly call the functions in this file.  */
 
+#ifndef __OBSTACK_ELIDE_CODE
 
 # include 
 # include 
@@ -293,7 +274,7 @@ _obstack_free (struct obstack *h, void *obj)
 /* obj is not in any of the chunks! */
 abort ();
 }
-# ifdef _LIBC
+# if defined _LIBC && __OBSTACK_INTERFACE_VERSION == 1
 /* Older versions of libc defined both _obstack_free and obstack_free.  */
 strong_alias (_obstack_free, obstack_free)
 # endif
@@ -311,28 +292,42 @@ _obstack_memory_used (struct obstack *h)
   return nbytes;
 }
 
+# ifdef __OBSTACK_ALIAS_VER2
+/* If sizeof(int) == sizeof(size_t) then version 2 obstack code is ABI
+   compatible with version 1.  */
+strong_alias (_obstack_allocated_p, _obstack2_allocated_p)
+strong_alias (_obstack_begin,   _obstack2_begin)
+strong_alias (_obstack_begin_1, _obstack2_begin_1)
+strong_alias (_obstack_free,_obstack2_free)
+strong_alias (_obstack_memory_used, _obstack2_memory_used)
+strong_alias (_obstack_newchunk,_obstack2_newchunk)
+libc_hidden_def (_obstack2_newchunk)
+# endif
+
+
 /* Define the error handler.  */
+# if !defined _LIBC || __OBSTACK_INTERFACE_VERSION == 1
 
 /* Exit value used when 'print_and_abort' is used.  */
-# ifdef _LIBC
+#  ifdef _LIBC
 int obstack_exit_failure = EXIT_FAILURE;
-# else
-#  include "exitfail.h"
-#  define obstack_exit_failure exit_failure
-# endif
+#  else
+#   include "exitfail.h"
+#   define obstack_exit_failure exit_failure
+#  endif
 
-# ifdef _LIBC
-#  include 
-# else
-#  include "gettext.h"
-# endif
-# ifndef _
-#  define _(msgid) gettext (msgid)
-# endif
+#  ifdef _LIBC
+#   include 
+#  else
+#   include "gettext.h"

[PATCH 3/5] 64-bit obstack support, part 2

2014-07-25 Thread Alan Modra
This gets us 4G obstack support, without changing ABI compatibility.

a) Replace "int" size parameters, return values, and macro local vars
   with __OBSTACK_SIZE_T, an "unsigned int" for now.
b) Make obstack.chunk_size a __CHUNK_SIZE_T, an "unsigned long" for now.
c) Make all obstack macros checking available room use obstack_room.
   "next_free + desired > chunk_limit" may wrap the lhs for chunks
   allocated near the top of memory.
d) Use unsigned comparisons, and macro locals to support >2G on 32-bit.

* lib/obstack.h (__OBSTACK_SIZE_T): Define.  Use throughout
in place of "int" size parameters, return values and local vars.
(__CHUNK_SIZE_T): Define.
(struct obstack): Make chunk_size a __CHUNK_SIZE_T.  Make temp
union use an __OBSTACK_SIZE_T integer type.
For __GNUC__ versions of the following macros...
(obstack_room): Rename local var.
(obstack_make_room): Use obstack_room.
(obstack_grow, obstack_grow0, obstack_1grow, obstack_ptr_grow,
obstack_int_grow, obstack_blank): Likewise.
(obstack_finish): Use unsigned comparison when comparing aligned
next_free against chunk_limit.
(obstack_free): Cast OBJ to remove possible const qualifier.
For !__GNUC__ versions of the following macros...
(obstack_make_room): Use obstack_room.
(obstack_grow, obstack_grow0, obstack_1grow, obstack_ptr_grow,
obstack_int_grow, obstack_blank): Likewise.
(obstack_finish): Use unsigned comparision when comparing aligned
next_free against chunk_limit.
(obstack_free): Use temp.p and same comparisons as __GNUC__ version.
* lib/obstack.c (_obstack_begin_worker): Make "size" parameter
__OBSTACK_SIZE_T.
(_obstack_begin, _obstack_begin_1): Likewise.
(_obstack_newchunk): Likewise for length parameter.  Use size_t locals.
(_obstack_memory_used): Return and use __OBSTACK_SIZE_T local.
---
 lib/obstack.c |   16 +-
 lib/obstack.h |   91 ++---
 2 files changed, 56 insertions(+), 51 deletions(-)

diff --git a/lib/obstack.c b/lib/obstack.c
index 37cf5ae..98b955e 100644
--- a/lib/obstack.c
+++ b/lib/obstack.c
@@ -108,7 +108,7 @@ typedef void (*freefun_type) (void *, struct _obstack_chunk 
*);
 
 static int
 _obstack_begin_worker (struct obstack *h,
-   int size, int alignment,
+   __OBSTACK_SIZE_T size, int alignment,
chunkfun_type chunkfun, freefun_type freefun)
 {
   struct _obstack_chunk *chunk; /* points to new chunk */
@@ -153,7 +153,7 @@ _obstack_begin_worker (struct obstack *h,
 
 int
 _obstack_begin (struct obstack *h,
-int size, int alignment,
+__OBSTACK_SIZE_T size, int alignment,
 void *(*chunkfun) (size_t),
 void (*freefun) (void *))
 {
@@ -165,7 +165,7 @@ _obstack_begin (struct obstack *h,
 
 int
 _obstack_begin_1 (struct obstack *h,
-  int size, int alignment,
+  __OBSTACK_SIZE_T size, int alignment,
   void *(*chunkfun) (void *, size_t),
   void (*freefun) (void *, void *),
   void *arg)
@@ -184,12 +184,12 @@ _obstack_begin_1 (struct obstack *h,
to the beginning of the new one.  */
 
 void
-_obstack_newchunk (struct obstack *h, int length)
+_obstack_newchunk (struct obstack *h, __OBSTACK_SIZE_T length)
 {
   struct _obstack_chunk *old_chunk = h->chunk;
   struct _obstack_chunk *new_chunk;
-  long new_size;
-  long obj_size = h->next_free - h->object_base;
+  size_t new_size;
+  size_t obj_size = h->next_free - h->object_base;
   char *object_base;
 
   /* Compute size for new chunk.  */
@@ -298,11 +298,11 @@ _obstack_free (struct obstack *h, void *obj)
 strong_alias (_obstack_free, obstack_free)
 # endif
 
-int
+__OBSTACK_SIZE_T
 _obstack_memory_used (struct obstack *h)
 {
   struct _obstack_chunk *lp;
-  int nbytes = 0;
+  __OBSTACK_SIZE_T nbytes = 0;
 
   for (lp = h->chunk; lp != 0; lp = lp->prev)
 {
diff --git a/lib/obstack.h b/lib/obstack.h
index d70408e..daf28bd 100644
--- a/lib/obstack.h
+++ b/lib/obstack.h
@@ -106,6 +106,9 @@
 
 #include 
 
+#define __OBSTACK_SIZE_T unsigned int
+#define __CHUNK_SIZE_T unsigned long
+
 /* If B is the base of an object addressed by P, return the result of
aligning P to the next multiple of A + 1.  B and P must be of type
char *.  A + 1 must be a power of 2.  */
@@ -142,14 +145,14 @@ struct _obstack_chunk   /* Lives at front of each 
chunk. */
 
 struct obstack  /* control current object in current chunk */
 {
-  long chunk_size;  /* preferred size to allocate chunks in */
+  __CHUNK_SIZE_T chunk_size;/* preferred size to allocate chunks in */
   struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
   char *object_base;/* address of object we are buildi

[PATCH 5/5] obstack usability

2014-07-25 Thread Alan Modra
When using obstack.h/c in other projects it isn't very nice that gnulib
headers like exitfail.h and gettext.h need to be present.  Far worse
is a dependency on gnulib's version of stdlib.h for __attribute_pure__
and _Noreturn.  This only works if a project is willing to import
rather a lot of gnulib configury magic, because gnulib's stdlib.h must
be modified at configure time.

* lib/obstack.h (__attribute_pure__): Don't use _GL_ATTRIBUTE_PURE.
* lib/obstack.c (obstack_exit_failure): Don't include exitfail.h.
(_): Include libintl.h when HAVE_LIBINTL_H and ENABLE_NLS.  Don't
include gettext.h.
(_Noreturn): Define.
---
 lib/obstack.c |   29 +++--
 lib/obstack.h |6 +-
 2 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/lib/obstack.c b/lib/obstack.c
index 1ac0e5d..4101581 100644
--- a/lib/obstack.c
+++ b/lib/obstack.c
@@ -312,17 +312,34 @@ libc_hidden_def (_obstack2_newchunk)
 #  ifdef _LIBC
 int obstack_exit_failure = EXIT_FAILURE;
 #  else
-#   include "exitfail.h"
-#   define obstack_exit_failure exit_failure
+#   ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#   endif
+#   define obstack_exit_failure EXIT_FAILURE
 #  endif
 
-#  ifdef _LIBC
+#  if defined _LIBC || (HAVE_LIBINTL_H && ENABLE_NLS)
 #   include 
+#   ifndef _
+#define _(msgid) gettext (msgid)
+#   endif
 #  else
-#   include "gettext.h"
+#   ifndef _
+#define _(msgid) (msgid)
+#   endif
 #  endif
-#  ifndef _
-#   define _(msgid) gettext (msgid)
+
+#  if !(defined _Noreturn\
+|| (defined __STDC_VERSION__ && 201112 <= __STDC_VERSION__))
+#   if ((defined __GNUC__\
+&& (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__)))\
+   || (defined __SUNPRO_C && 0x5110 <= __SUNPRO_C))
+#define _Noreturn __attribute__ ((__noreturn__))
+#   elif defined _MSC_VER && 1200 <= _MSC_VER
+#define _Noreturn __declspec (noreturn)
+#   else
+#define _Noreturn
+#   endif
 #  endif
 
 #  ifdef _LIBC
diff --git a/lib/obstack.h b/lib/obstack.h
index 19a8eb2..b79d4cb 100644
--- a/lib/obstack.h
+++ b/lib/obstack.h
@@ -188,7 +188,11 @@
 #include 
 
 #ifndef __attribute_pure__
-# define __attribute_pure__ _GL_ATTRIBUTE_PURE
+# if defined __GNUC_MINOR__ && __GNUC__ * 1000 + __GNUC_MINOR__ >= 2096
+#  define __attribute_pure__ __attribute__ ((__pure__))
+# else
+#  define __attribute_pure__
+# endif
 #endif
 
 #ifdef __cplusplus