[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 1/5] obstack tidy
From: |
Alan Modra |
Subject: |
[PATCH 1/5] obstack tidy |
Date: |
Sat, 26 Jul 2014 15:27:08 +0930 |
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 <temp>): 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 <stddef.h>
-
#ifndef ELIDE_CODE
# include <stdint.h>
+# include <stdlib.h>
/* 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 <stdlib.h>
-# 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);
/* If the object just copied was the only data in OLD_CHUNK,
free that chunk and remove it from the chain.
@@ -342,7 +286,7 @@ _obstack_allocated_p (struct obstack *h, void *obj)
# undef obstack_free
void
-__obstack_free (struct obstack *h, void *obj)
+_obstack_free (struct obstack *h, void *obj)
{
struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
struct _obstack_chunk *plp; /* point to previous chunk if any */
@@ -370,11 +314,9 @@ __obstack_free (struct obstack *h, void *obj)
/* obj is not in any of the chunks! */
abort ();
}
-
# ifdef _LIBC
-/* Older versions of libc used a function _obstack_free intended to be
- called by non-GCC compilers. */
-strong_alias (obstack_free, _obstack_free)
+/* Older versions of libc defined both _obstack_free and obstack_free. */
+strong_alias (_obstack_free, obstack_free)
# endif
int
@@ -391,6 +333,15 @@ _obstack_memory_used (struct obstack *h)
}
/* Define the error handler. */
+
+/* Exit value used when 'print_and_abort' is used. */
+# ifdef _LIBC
+int obstack_exit_failure = EXIT_FAILURE;
+# else
+# include "exitfail.h"
+# define obstack_exit_failure exit_failure
+# endif
+
# ifdef _LIBC
# include <libintl.h>
# else
@@ -420,4 +371,22 @@ print_and_abort (void)
exit (obstack_exit_failure);
}
+/* 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'. */
+void (*obstack_alloc_failed_handler) (void) = print_and_abort;
+
+# 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
+
#endif /* !ELIDE_CODE */
diff --git a/lib/obstack.h b/lib/obstack.h
index f92492f..413c7a3 100644
--- a/lib/obstack.h
+++ b/lib/obstack.h
@@ -104,17 +104,7 @@
#ifndef _OBSTACK_H
#define _OBSTACK_H 1
-/* We need the type of a pointer subtraction. If __PTRDIFF_TYPE__ is
- defined, as with GNU C, use that; that way we don't pollute the
- namespace with <stddef.h>'s symbols. Otherwise, include <stddef.h>
- and use ptrdiff_t. */
-
-#ifdef __PTRDIFF_TYPE__
-# define PTR_INT_TYPE __PTRDIFF_TYPE__
-#else
-# include <stddef.h>
-# define PTR_INT_TYPE ptrdiff_t
-#endif
+#include <stddef.h>
/* 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
@@ -122,15 +112,15 @@
#define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A)))
-/* Similar to _BPTR_ALIGN (B, P, A), except optimize the common case
+/* Similar to __BPTR_ALIGN (B, P, A), except optimize the common case
where pointers can be converted to integers, aligned as integers,
- and converted back again. If PTR_INT_TYPE is narrower than a
+ and converted back again. If ptrdiff_t is narrower than a
pointer (e.g., the AS/400), play it safe and compute the alignment
relative to B. Otherwise, use the faster strategy of computing the
alignment relative to 0. */
#define __PTR_ALIGN(B, P, A) \
- __BPTR_ALIGN (sizeof (PTR_INT_TYPE) < sizeof (void *) ? (B) : (char *) 0, \
+ __BPTR_ALIGN (sizeof (ptrdiff_t) < sizeof (void *) ? (B) : (char *) 0, \
P, A)
#include <string.h>
@@ -159,8 +149,8 @@ struct obstack /* control current object in
current chunk */
char *chunk_limit; /* address of char after current chunk */
union
{
- PTR_INT_TYPE tempint;
- void *tempptr;
+ ptrdiff_t i;
+ void *p;
} temp; /* Temporary for some macros. */
int alignment_mask; /* Mask of alignment for each object. */
/* These prototypes vary based on 'use_extra_arg', and we use
@@ -182,6 +172,7 @@ struct obstack /* control current object in
current chunk */
/* Declare the external functions we use; they are in obstack.c. */
extern void _obstack_newchunk (struct obstack *, int);
+extern void _obstack_free (struct obstack *, void *);
extern int _obstack_begin (struct obstack *, int, int,
void *(*)(long), void (*)(void *));
extern int _obstack_begin_1 (struct obstack *, int, int,
@@ -189,13 +180,6 @@ extern int _obstack_begin_1 (struct obstack *, int, int,
void (*)(void *, void *), void *);
extern int _obstack_memory_used (struct obstack *) __attribute_pure__;
-/* The default name of the function for freeing a chunk is 'obstack_free',
- but gnulib users can override this by defining '__obstack_free'. */
-#ifndef __obstack_free
-# define __obstack_free obstack_free
-#endif
-extern void __obstack_free (struct obstack *, void *);
-
/* Error handler called when 'obstack_chunk_alloc' failed to allocate
more memory. This can be set to a user defined function which
@@ -258,7 +242,7 @@ extern int obstack_exit_failure;
#define obstack_memory_used(h) _obstack_memory_used (h)
#if defined __GNUC__
-# if ! (2 < __GNUC__ + (8 <= __GNUC_MINOR__))
+# if !defined __GNUC_MINOR__ || __GNUC__ * 1000 + __GNUC_MINOR__ < 2008
# define __extension__
# endif
@@ -406,15 +390,16 @@ extern int obstack_exit_failure;
void *__obj = (OBJ); \
if (__obj > (void *) __o->chunk && __obj < (void *) __o->chunk_limit) \
__o->next_free = __o->object_base = (char *) __obj; \
- else (__obstack_free) (__o, __obj); })
+ else \
+ _obstack_free (__o, __obj); })
#else /* not __GNUC__ */
-# define obstack_object_size(h) \
- (unsigned) ((h)->next_free - (h)->object_base)
+# define obstack_object_size(h)
\
+ ((unsigned) ((h)->next_free - (h)->object_base))
# define obstack_room(h) \
- (unsigned) ((h)->chunk_limit - (h)->next_free)
+ ((unsigned) ((h)->chunk_limit - (h)->next_free))
# define obstack_empty_p(h) \
((h)->chunk->prev == 0 \
@@ -429,23 +414,23 @@ extern int obstack_exit_failure;
but some compilers won't accept it. */
# define obstack_make_room(h, length) \
- ((h)->temp.tempint = (length), \
- (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
- ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0))
+ ((h)->temp.i = (length), \
+ (((h)->next_free + (h)->temp.i > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0))
# define obstack_grow(h, where, length)
\
- ((h)->temp.tempint = (length), \
- (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
- ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
- memcpy ((h)->next_free, where, (h)->temp.tempint), \
- (h)->next_free += (h)->temp.tempint)
+ ((h)->temp.i = (length), \
+ (((h)->next_free + (h)->temp.i > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0), \
+ memcpy ((h)->next_free, where, (h)->temp.i),
\
+ (h)->next_free += (h)->temp.i)
# define obstack_grow0(h, where, length) \
- ((h)->temp.tempint = (length), \
- (((h)->next_free + (h)->temp.tempint + 1 > (h)->chunk_limit)
\
- ? (_obstack_newchunk ((h), (h)->temp.tempint + 1), 0) : 0), \
- memcpy ((h)->next_free, where, (h)->temp.tempint), \
- (h)->next_free += (h)->temp.tempint,
\
+ ((h)->temp.i = (length), \
+ (((h)->next_free + (h)->temp.i + 1 > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), (h)->temp.i + 1), 0) : 0), \
+ memcpy ((h)->next_free, where, (h)->temp.i),
\
+ (h)->next_free += (h)->temp.i, \
*((h)->next_free)++ = 0)
# define obstack_1grow(h, datum) \
@@ -470,10 +455,10 @@ extern int obstack_exit_failure;
(((int *) ((h)->next_free += sizeof (int)))[-1] = (aint))
# define obstack_blank(h, length) \
- ((h)->temp.tempint = (length), \
- (((h)->chunk_limit - (h)->next_free < (h)->temp.tempint) \
- ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
- obstack_blank_fast (h, (h)->temp.tempint))
+ ((h)->temp.i = (length), \
+ (((h)->chunk_limit - (h)->next_free < (h)->temp.i) \
+ ? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0), \
+ obstack_blank_fast (h, (h)->temp.i))
# define obstack_alloc(h, length) \
(obstack_blank ((h), (length)), obstack_finish ((h)))
@@ -488,7 +473,7 @@ extern int obstack_exit_failure;
(((h)->next_free == (h)->object_base \
? (((h)->maybe_empty_object = 1), 0) \
: 0), \
- (h)->temp.tempptr = (h)->object_base, \
+ (h)->temp.p = (h)->object_base, \
(h)->next_free \
= __PTR_ALIGN ((h)->object_base, (h)->next_free, \
(h)->alignment_mask), \
@@ -496,15 +481,15 @@ extern int obstack_exit_failure;
> (h)->chunk_limit - (char *) (h)->chunk) \
? ((h)->next_free = (h)->chunk_limit) : 0), \
(h)->object_base = (h)->next_free, \
- (h)->temp.tempptr)
+ (h)->temp.p)
# define obstack_free(h, obj) \
- ((h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \
- ((((h)->temp.tempint > 0 \
- && (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \
+ ((h)->temp.i = (char *) (obj) - (char *) (h)->chunk, \
+ ((((h)->temp.i > 0 \
+ && (h)->temp.i < (h)->chunk_limit - (char *) (h)->chunk))
\
? (void) ((h)->next_free = (h)->object_base
\
- = (h)->temp.tempint + (char *) (h)->chunk) \
- : (__obstack_free) (h, (h)->temp.tempint + (char *) (h)->chunk)))
+ = (h)->temp.i + (char *) (h)->chunk) \
+ : _obstack_free (h, (h)->temp.i + (char *) (h)->chunk)))
#endif /* not __GNUC__ */
@@ -512,4 +497,4 @@ extern int obstack_exit_failure;
} /* C++ */
#endif
-#endif /* obstack.h */
+#endif /* _OBSTACK_H */
Re: [PATCH 5/5] obstack usability, Paul Eggert, 2014/07/26