argp facility from glibc-20030610.
[gnulib.git] / lib / obstack.c
index 639a6b0..17eb986 100644 (file)
@@ -1,23 +1,18 @@
 /* obstack.c - subroutines used implicitly by object stack macros
-   Copyright (C) 1988-1994,96,97,98,1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1988-1994, 1996-1999, 2000-2002 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 2, or (at your option)
+   any later version.
 
-   This file is part of the GNU C Library.  Its master source is NOT part of
-   the C library, however.  The master source lives in /gd/gnu/lib.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
+   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
-   Library General Public License for more details.
+   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 Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU General Public License along
+   with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
    files, it is simpler to just do this in the source for each such file.  */
 
 #include <stdio.h>             /* Random thing to get __GNU_LIBRARY__.  */
-#if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
+#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
 # include <gnu-versions.h>
 # if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
 #  define ELIDE_CODE
 # endif
 #endif
 
+#if defined _LIBC && defined USE_IN_LIBIO
+# include <wchar.h>
+#endif
 
 #ifndef ELIDE_CODE
 
 
-# if defined (__STDC__) && __STDC__
+# if defined __STDC__ && __STDC__
 #  define POINTER void *
 # else
 #  define POINTER char *
@@ -82,7 +80,7 @@ union fooround {long x; double d;};
    abort gracefully or use longjump - but shouldn't return.  This
    variable by default points to the internal function
    `print_and_abort'.  */
-# if defined (__STDC__) && __STDC__
+# if defined __STDC__ && __STDC__
 static void print_and_abort (void);
 void (*obstack_alloc_failed_handler) (void) = print_and_abort;
 # else
@@ -110,7 +108,7 @@ struct obstack *_obstack;
    For free, do not use ?:, since some compilers, like the MIPS compilers,
    do not allow (expr) ? void : void.  */
 
-# if defined (__STDC__) && __STDC__
+# if defined __STDC__ && __STDC__
 #  define CALL_CHUNKFUN(h, size) \
   (((h) -> use_extra_arg) \
    ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
@@ -152,7 +150,7 @@ _obstack_begin (h, size, alignment, chunkfun, freefun)
      struct obstack *h;
      int size;
      int alignment;
-# if defined (__STDC__) && __STDC__
+# if defined __STDC__ && __STDC__
      POINTER (*chunkfun) (long);
      void (*freefun) (void *);
 # else
@@ -181,7 +179,7 @@ _obstack_begin (h, size, alignment, chunkfun, freefun)
       size = 4096 - extra;
     }
 
-# if defined (__STDC__) && __STDC__
+# if defined __STDC__ && __STDC__
   h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
   h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
 # else
@@ -210,7 +208,7 @@ _obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg)
      struct obstack *h;
      int size;
      int alignment;
-# if defined (__STDC__) && __STDC__
+# if defined __STDC__ && __STDC__
      POINTER (*chunkfun) (POINTER, long);
      void (*freefun) (POINTER, POINTER);
 # else
@@ -240,7 +238,7 @@ _obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg)
       size = 4096 - extra;
     }
 
-# if defined(__STDC__) && __STDC__
+# if defined __STDC__ && __STDC__
   h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
   h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
 # else
@@ -282,9 +280,10 @@ _obstack_newchunk (h, length)
   register long obj_size = h->next_free - h->object_base;
   register long i;
   long already;
+  char *object_base;
 
   /* Compute size for new chunk.  */
-  new_size = (obj_size + length) + (obj_size >> 3) + 100;
+  new_size = (obj_size + length) + (obj_size >> 3) + h->alignment_mask + 100;
   if (new_size < h->chunk_size)
     new_size = h->chunk_size;
 
@@ -296,6 +295,11 @@ _obstack_newchunk (h, length)
   new_chunk->prev = old_chunk;
   new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
 
+  /* Compute an aligned object_base in the new chunk */
+  object_base =
+    __INT_TO_PTR ((__PTR_TO_INT (new_chunk->contents) + h->alignment_mask)
+                 & ~ (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.  */
@@ -303,7 +307,7 @@ _obstack_newchunk (h, length)
     {
       for (i = obj_size / sizeof (COPYING_UNIT) - 1;
           i >= 0; i--)
-       ((COPYING_UNIT *)new_chunk->contents)[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
@@ -314,7 +318,7 @@ _obstack_newchunk (h, length)
     already = 0;
   /* Copy remaining bytes one by one.  */
   for (i = already; i < obj_size; i++)
-    new_chunk->contents[i] = h->object_base[i];
+    object_base[i] = h->object_base[i];
 
   /* If the object just copied was the only data in OLD_CHUNK,
      free that chunk and remove it from the chain.
@@ -325,7 +329,7 @@ _obstack_newchunk (h, length)
       CALL_FREEFUN (h, old_chunk);
     }
 
-  h->object_base = new_chunk->contents;
+  h->object_base = object_base;
   h->next_free = h->object_base + obj_size;
   /* The new chunk certainly contains no empty object yet.  */
   h->maybe_empty_object = 0;
@@ -335,7 +339,7 @@ _obstack_newchunk (h, length)
    This is here for debugging.
    If you use it in a program, you are probably losing.  */
 
-# if defined (__STDC__) && __STDC__
+# if defined __STDC__ && __STDC__
 /* Suppress -Wmissing-prototypes warning.  We don't want to declare this in
    obstack.h because it is just for debugging.  */
 int _obstack_allocated_p (struct obstack *h, POINTER obj);
@@ -450,26 +454,40 @@ _obstack_memory_used (h)
 }
 \f
 /* Define the error handler.  */
-# ifndef _
-#  ifdef HAVE_LIBINTL_H
-#   include <libintl.h>
-#   ifndef _
-#    define _(Str) gettext (Str)
-#   endif
-#  else
-#   define _(Str) (Str)
-#  endif
+# ifdef _LIBC
+#  include <libintl.h>
+# else
+#  include "gettext.h"
 # endif
+# define _(msgid) gettext (msgid)
+
 # if defined _LIBC && defined USE_IN_LIBIO
 #  include <libio/iolibio.h>
 #  define fputs(s, f) _IO_fputs (s, f)
 # endif
 
+# ifndef __attribute__
+/* This feature is available in gcc versions 2.5 and later.  */
+#  if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
+#   define __attribute__(Spec) /* empty */
+#  endif
+# endif
+
 static void
+__attribute__ ((noreturn))
 print_and_abort ()
 {
-  fputs (_("memory exhausted"), stderr);
-  fputc ('\n', stderr);
+  /* Don't change any of these strings.  Yes, it would be possible to add
+     the newline to the string and use fputs or so.  But this must not
+     happen because the "memory exhausted" message appears in other places
+     like this and the translation should be reused instead of creating
+     a very similar string which requires a separate translation.  */
+# if defined _LIBC && defined USE_IN_LIBIO
+  if (_IO_fwide (stderr, 0) > 0)
+    __fwprintf (stderr, L"%s\n", _("memory exhausted"));
+  else
+# endif
+    fprintf (stderr, "%s\n", _("memory exhausted"));
   exit (obstack_exit_failure);
 }
 \f
@@ -480,7 +498,7 @@ print_and_abort ()
 /* Now define the functional versions of the obstack macros.
    Define them to simply use the corresponding macros to do the job.  */
 
-#  if defined (__STDC__) && __STDC__
+#  if defined __STDC__ && __STDC__
 /* These function definitions do not work with non-ANSI preprocessors;
    they won't pass through the macro names in parentheses.  */
 
@@ -518,20 +536,20 @@ int (obstack_make_room) (obstack, length)
   return obstack_make_room (obstack, length);
 }
 
-void (obstack_grow) (obstack, pointer, length)
+void (obstack_grow) (obstack, data, length)
      struct obstack *obstack;
-     POINTER pointer;
+     const POINTER data;
      int length;
 {
-  obstack_grow (obstack, pointer, length);
+  obstack_grow (obstack, data, length);
 }
 
-void (obstack_grow0) (obstack, pointer, length)
+void (obstack_grow0) (obstack, data, length)
      struct obstack *obstack;
-     POINTER pointer;
+     const POINTER data;
      int length;
 {
-  obstack_grow0 (obstack, pointer, length);
+  obstack_grow0 (obstack, data, length);
 }
 
 void (obstack_1grow) (obstack, character)
@@ -575,20 +593,20 @@ POINTER (obstack_alloc) (obstack, length)
   return obstack_alloc (obstack, length);
 }
 
-POINTER (obstack_copy) (obstack, pointer, length)
+POINTER (obstack_copy) (obstack, address, length)
      struct obstack *obstack;
-     POINTER pointer;
+     const POINTER address;
      int length;
 {
-  return obstack_copy (obstack, pointer, length);
+  return obstack_copy (obstack, address, length);
 }
 
-POINTER (obstack_copy0) (obstack, pointer, length)
+POINTER (obstack_copy0) (obstack, address, length)
      struct obstack *obstack;
-     POINTER pointer;
+     const POINTER address;
      int length;
 {
-  return obstack_copy0 (obstack, pointer, length);
+  return obstack_copy0 (obstack, address, length);
 }
 
 #  endif /* __STDC__ */