/[m4]/m4/m4/obstack.c
ViewVC logotype

Diff of /m4/m4/obstack.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.3 by gary, Wed Aug 27 17:10:12 2003 UTC revision 1.4 by gary, Fri Aug 29 18:33:38 2003 UTC
# Line 1  Line 1 
1  /* obstack.c - subroutines used implicitly by object stack macros  /* obstack.c - subroutines used implicitly by object stack macros
2     Copyright (C) 1988-1994,1996-2000 Free Software Foundation, Inc.     Copyright (C) 1988-1994, 1996-1999, 2000-2002 Free Software Foundation, Inc.
3       This program is free software; you can redistribute it and/or modify
4       it under the terms of the GNU General Public License as published by
5       the Free Software Foundation; either version 2, or (at your option)
6       any later version.
7    
8     This file is part of the GNU C Library.  Its master source is NOT part of     This program is distributed in the hope that it will be useful,
    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,  
9     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
10     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11     Library General Public License for more details.     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.  */  
12    
13  /* Modified for GNU m4 by Gary V. Vaughan <gary@gnu.org> */     You should have received a copy of the GNU General Public License along
14       with this program; if not, write to the Free Software Foundation,
15       Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
16    
17  #if HAVE_CONFIG_H  #ifdef HAVE_CONFIG_H
18  #include <config.h>  # include <config.h>
19  #endif  #endif
20    
21  #include <obstack.h>  #include "obstack.h"
22    
23  /* NOTE BEFORE MODIFYING THIS FILE: This version number must be  /* NOTE BEFORE MODIFYING THIS FILE: This version number must be
24     incremented whenever callers compiled using an old obstack.h can no     incremented whenever callers compiled using an old obstack.h can no
# Line 42  Line 35 
35     files, it is simpler to just do this in the source for each such file.  */     files, it is simpler to just do this in the source for each such file.  */
36    
37  #include <stdio.h>              /* Random thing to get __GNU_LIBRARY__.  */  #include <stdio.h>              /* Random thing to get __GNU_LIBRARY__.  */
38  #if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1  #if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
39  #include <gnu-versions.h>  # include <gnu-versions.h>
40  #if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION  # if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
41  #define ELIDE_CODE  #  define ELIDE_CODE
42  #endif  # endif
43  #endif  #endif
44    
45    #if defined _LIBC && defined USE_IN_LIBIO
46    # include <wchar.h>
47    #endif
48    
49  #ifndef ELIDE_CODE  #ifndef ELIDE_CODE
50    
51    
52  #if defined (__STDC__) && __STDC__  # if defined __STDC__ && __STDC__
53  #define POINTER void *  #  define POINTER void *
54  #else  # else
55  #define POINTER char *  #  define POINTER char *
56  #endif  # endif
57    
58  /* Determine default alignment.  */  /* Determine default alignment.  */
59  struct fooalign {char x; double d;};  struct fooalign {char x; double d;};
60  #define DEFAULT_ALIGNMENT  \  # define DEFAULT_ALIGNMENT  \
61    ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))    ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))
62  /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.  /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
63     But in fact it might be less smart and round addresses to as much as     But in fact it might be less smart and round addresses to as much as
64     DEFAULT_ROUNDING.  So we prepare for it to do that.  */     DEFAULT_ROUNDING.  So we prepare for it to do that.  */
65  union fooround {long x; double d;};  union fooround {long x; double d;};
66  #define DEFAULT_ROUNDING (sizeof (union fooround))  # define DEFAULT_ROUNDING (sizeof (union fooround))
67    
68  /* When we copy a long block of data, this is the unit to do it with.  /* When we copy a long block of data, this is the unit to do it with.
69     On some machines, copying successive ints does not work;     On some machines, copying successive ints does not work;
70     in such a case, redefine COPYING_UNIT to `long' (if that works)     in such a case, redefine COPYING_UNIT to `long' (if that works)
71     or `char' as a last resort.  */     or `char' as a last resort.  */
72  #ifndef COPYING_UNIT  # ifndef COPYING_UNIT
73  #define COPYING_UNIT int  #  define COPYING_UNIT int
74  #endif  # endif
75    
76    
77  /* The functions allocating more room by calling `obstack_chunk_alloc'  /* The functions allocating more room by calling `obstack_chunk_alloc'
# Line 84  union fooround {long x; double d;}; Line 80  union fooround {long x; double d;};
80     abort gracefully or use longjump - but shouldn't return.  This     abort gracefully or use longjump - but shouldn't return.  This
81     variable by default points to the internal function     variable by default points to the internal function
82     `print_and_abort'.  */     `print_and_abort'.  */
83  #if defined (__STDC__) && __STDC__  # if defined __STDC__ && __STDC__
84  static void print_and_abort (void);  static void print_and_abort (void);
85  void (*obstack_alloc_failed_handler) (void) = print_and_abort;  void (*obstack_alloc_failed_handler) (void) = print_and_abort;
86  #else  # else
87  static void print_and_abort ();  static void print_and_abort ();
88  void (*obstack_alloc_failed_handler) () = print_and_abort;  void (*obstack_alloc_failed_handler) () = print_and_abort;
89  #endif  # endif
90    
91  /* Exit value used when `print_and_abort' is used.  */  /* Exit value used when `print_and_abort' is used.  */
92  #if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H  # if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H
93  #include <stdlib.h>  #  include <stdlib.h>
94  #endif  # endif
95  #ifndef EXIT_FAILURE  # ifndef EXIT_FAILURE
96  #define EXIT_FAILURE 1  #  define EXIT_FAILURE 1
97  #endif  # endif
98  int obstack_exit_failure = EXIT_FAILURE;  int obstack_exit_failure = EXIT_FAILURE;
99    
100  /* The non-GNU-C macros copy the obstack into this global variable  /* The non-GNU-C macros copy the obstack into this global variable
# Line 112  struct obstack *_obstack; Line 108  struct obstack *_obstack;
108     For free, do not use ?:, since some compilers, like the MIPS compilers,     For free, do not use ?:, since some compilers, like the MIPS compilers,
109     do not allow (expr) ? void : void.  */     do not allow (expr) ? void : void.  */
110    
111  #if defined (__STDC__) && __STDC__  # if defined __STDC__ && __STDC__
112  #define CALL_CHUNKFUN(h, size) \  #  define CALL_CHUNKFUN(h, size) \
113    (((h) -> use_extra_arg) \    (((h) -> use_extra_arg) \
114     ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \     ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
115     : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))     : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
116    
117  #define CALL_FREEFUN(h, old_chunk) \  #  define CALL_FREEFUN(h, old_chunk) \
118    do { \    do { \
119      if ((h) -> use_extra_arg) \      if ((h) -> use_extra_arg) \
120        (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \        (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
121      else \      else \
122        (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \        (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
123    } while (0)    } while (0)
124  #else  # else
125  #define CALL_CHUNKFUN(h, size) \  #  define CALL_CHUNKFUN(h, size) \
126    (((h) -> use_extra_arg) \    (((h) -> use_extra_arg) \
127     ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \     ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
128     : (*(struct _obstack_chunk *(*) ()) (h)->chunkfun) ((size)))     : (*(struct _obstack_chunk *(*) ()) (h)->chunkfun) ((size)))
129    
130  #define CALL_FREEFUN(h, old_chunk) \  #  define CALL_FREEFUN(h, old_chunk) \
131    do { \    do { \
132      if ((h) -> use_extra_arg) \      if ((h) -> use_extra_arg) \
133        (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \        (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
134      else \      else \
135        (*(void (*) ()) (h)->freefun) ((old_chunk)); \        (*(void (*) ()) (h)->freefun) ((old_chunk)); \
136    } while (0)    } while (0)
137  #endif  # endif
138    
139    
140  /* Initialize an obstack H for use.  Specify chunk size SIZE (0 means default).  /* Initialize an obstack H for use.  Specify chunk size SIZE (0 means default).
# Line 154  _obstack_begin (h, size, alignment, chun Line 150  _obstack_begin (h, size, alignment, chun
150       struct obstack *h;       struct obstack *h;
151       int size;       int size;
152       int alignment;       int alignment;
153  #if defined (__STDC__) && __STDC__  # if defined __STDC__ && __STDC__
154       POINTER (*chunkfun) (long);       POINTER (*chunkfun) (long);
155       void (*freefun) (void *);       void (*freefun) (void *);
156  #else  # else
157       POINTER (*chunkfun) ();       POINTER (*chunkfun) ();
158       void (*freefun) ();       void (*freefun) ();
159  #endif  # endif
160  {  {
161    register struct _obstack_chunk *chunk; /* points to new chunk */    register struct _obstack_chunk *chunk; /* points to new chunk */
162    
# Line 183  _obstack_begin (h, size, alignment, chun Line 179  _obstack_begin (h, size, alignment, chun
179        size = 4096 - extra;        size = 4096 - extra;
180      }      }
181    
182  #if defined (__STDC__) && __STDC__  # if defined __STDC__ && __STDC__
183    h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;    h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
184    h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;    h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
185  #else  # else
186    h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;    h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
187    h->freefun = freefun;    h->freefun = freefun;
188  #endif  # endif
189    h->chunk_size = size;    h->chunk_size = size;
190    h->alignment_mask = alignment - 1;    h->alignment_mask = alignment - 1;
191    h->use_extra_arg = 0;    h->use_extra_arg = 0;
# Line 212  _obstack_begin_1 (h, size, alignment, ch Line 208  _obstack_begin_1 (h, size, alignment, ch
208       struct obstack *h;       struct obstack *h;
209       int size;       int size;
210       int alignment;       int alignment;
211  #if defined (__STDC__) && __STDC__  # if defined __STDC__ && __STDC__
212       POINTER (*chunkfun) (POINTER, long);       POINTER (*chunkfun) (POINTER, long);
213       void (*freefun) (POINTER, POINTER);       void (*freefun) (POINTER, POINTER);
214  #else  # else
215       POINTER (*chunkfun) ();       POINTER (*chunkfun) ();
216       void (*freefun) ();       void (*freefun) ();
217  #endif  # endif
218       POINTER arg;       POINTER arg;
219  {  {
220    register struct _obstack_chunk *chunk; /* points to new chunk */    register struct _obstack_chunk *chunk; /* points to new chunk */
# Line 242  _obstack_begin_1 (h, size, alignment, ch Line 238  _obstack_begin_1 (h, size, alignment, ch
238        size = 4096 - extra;        size = 4096 - extra;
239      }      }
240    
241  #if defined(__STDC__) && __STDC__  # if defined __STDC__ && __STDC__
242    h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;    h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
243    h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;    h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
244  #else  # else
245    h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;    h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
246    h->freefun = freefun;    h->freefun = freefun;
247  #endif  # endif
248    h->chunk_size = size;    h->chunk_size = size;
249    h->alignment_mask = alignment - 1;    h->alignment_mask = alignment - 1;
250    h->extra_arg = arg;    h->extra_arg = arg;
# Line 284  _obstack_newchunk (h, length) Line 280  _obstack_newchunk (h, length)
280    register long obj_size = h->next_free - h->object_base;    register long obj_size = h->next_free - h->object_base;
281    register long i;    register long i;
282    long already;    long already;
283      char *object_base;
284    
285    /* Compute size for new chunk.  */    /* Compute size for new chunk.  */
286    new_size = (obj_size + length) + (obj_size >> 3) + 100;    new_size = (obj_size + length) + (obj_size >> 3) + h->alignment_mask + 100;
287    if (new_size < h->chunk_size)    if (new_size < h->chunk_size)
288      new_size = h->chunk_size;      new_size = h->chunk_size;
289    
# Line 298  _obstack_newchunk (h, length) Line 295  _obstack_newchunk (h, length)
295    new_chunk->prev = old_chunk;    new_chunk->prev = old_chunk;
296    new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;    new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
297    
298      /* Compute an aligned object_base in the new chunk */
299      object_base =
300        __INT_TO_PTR ((__PTR_TO_INT (new_chunk->contents) + h->alignment_mask)
301                      & ~ (h->alignment_mask));
302    
303    /* Move the existing object to the new chunk.    /* Move the existing object to the new chunk.
304       Word at a time is fast and is safe if the object       Word at a time is fast and is safe if the object
305       is sufficiently aligned.  */       is sufficiently aligned.  */
# Line 305  _obstack_newchunk (h, length) Line 307  _obstack_newchunk (h, length)
307      {      {
308        for (i = obj_size / sizeof (COPYING_UNIT) - 1;        for (i = obj_size / sizeof (COPYING_UNIT) - 1;
309             i >= 0; i--)             i >= 0; i--)
310          ((COPYING_UNIT *)new_chunk->contents)[i]          ((COPYING_UNIT *)object_base)[i]
311            = ((COPYING_UNIT *)h->object_base)[i];            = ((COPYING_UNIT *)h->object_base)[i];
312        /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,        /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
313           but that can cross a page boundary on a machine           but that can cross a page boundary on a machine
# Line 316  _obstack_newchunk (h, length) Line 318  _obstack_newchunk (h, length)
318      already = 0;      already = 0;
319    /* Copy remaining bytes one by one.  */    /* Copy remaining bytes one by one.  */
320    for (i = already; i < obj_size; i++)    for (i = already; i < obj_size; i++)
321      new_chunk->contents[i] = h->object_base[i];      object_base[i] = h->object_base[i];
322    
323    /* If the object just copied was the only data in OLD_CHUNK,    /* If the object just copied was the only data in OLD_CHUNK,
324       free that chunk and remove it from the chain.       free that chunk and remove it from the chain.
# Line 327  _obstack_newchunk (h, length) Line 329  _obstack_newchunk (h, length)
329        CALL_FREEFUN (h, old_chunk);        CALL_FREEFUN (h, old_chunk);
330      }      }
331    
332    h->object_base = new_chunk->contents;    h->object_base = object_base;
333    h->next_free = h->object_base + obj_size;    h->next_free = h->object_base + obj_size;
334    /* The new chunk certainly contains no empty object yet.  */    /* The new chunk certainly contains no empty object yet.  */
335    h->maybe_empty_object = 0;    h->maybe_empty_object = 0;
# Line 337  _obstack_newchunk (h, length) Line 339  _obstack_newchunk (h, length)
339     This is here for debugging.     This is here for debugging.
340     If you use it in a program, you are probably losing.  */     If you use it in a program, you are probably losing.  */
341    
342  #if defined (__STDC__) && __STDC__  # if defined __STDC__ && __STDC__
343  /* Suppress -Wmissing-prototypes warning.  We don't want to declare this in  /* Suppress -Wmissing-prototypes warning.  We don't want to declare this in
344     obstack.h because it is just for debugging.  */     obstack.h because it is just for debugging.  */
345  int _obstack_allocated_p (struct obstack *h, POINTER obj);  int _obstack_allocated_p (struct obstack *h, POINTER obj);
346  #endif  # endif
347    
348  int  int
349  _obstack_allocated_p (h, obj)  _obstack_allocated_p (h, obj)
# Line 366  _obstack_allocated_p (h, obj) Line 368  _obstack_allocated_p (h, obj)
368  /* Free objects in obstack H, including OBJ and everything allocate  /* Free objects in obstack H, including OBJ and everything allocate
369     more recently than OBJ.  If OBJ is zero, free everything in H.  */     more recently than OBJ.  If OBJ is zero, free everything in H.  */
370    
371  #undef obstack_free  # undef obstack_free
372    
373  /* This function has two names with identical definitions.  /* This function has two names with identical definitions.
374     This is the first one, called from non-ANSI code.  */     This is the first one, called from non-ANSI code.  */
# Line 452  _obstack_memory_used (h) Line 454  _obstack_memory_used (h)
454  }  }
455    
456  /* Define the error handler.  */  /* Define the error handler.  */
457  #ifndef _  # ifdef _LIBC
 # ifdef HAVE_LIBINTL_H  
458  #  include <libintl.h>  #  include <libintl.h>
 #  ifndef _  
 #   define _(Str) gettext (Str)  
 #  endif  
459  # else  # else
460  #  define _(Str) (Str)  #  include "gettext.h"
461    # endif
462    # define _(msgid) gettext (msgid)
463    
464    # if defined _LIBC && defined USE_IN_LIBIO
465    #  include <libio/iolibio.h>
466    #  define fputs(s, f) _IO_fputs (s, f)
467    # endif
468    
469    # ifndef __attribute__
470    /* This feature is available in gcc versions 2.5 and later.  */
471    #  if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
472    #   define __attribute__(Spec) /* empty */
473    #  endif
474  # endif  # endif
 #endif  
 #if defined _LIBC && defined USE_IN_LIBIO  
 # include <libio/iolibio.h>  
 # define fputs(s, f) _IO_fputs (s, f)  
 #endif  
475    
476  static void  static void
477    __attribute__ ((noreturn))
478  print_and_abort ()  print_and_abort ()
479  {  {
480    fputs (_("memory exhausted"), stderr);    /* Don't change any of these strings.  Yes, it would be possible to add
481    fputc ('\n', stderr);       the newline to the string and use fputs or so.  But this must not
482         happen because the "memory exhausted" message appears in other places
483         like this and the translation should be reused instead of creating
484         a very similar string which requires a separate translation.  */
485    # if defined _LIBC && defined USE_IN_LIBIO
486      if (_IO_fwide (stderr, 0) > 0)
487        __fwprintf (stderr, L"%s\n", _("memory exhausted"));
488      else
489    # endif
490        fprintf (stderr, "%s\n", _("memory exhausted"));
491    exit (obstack_exit_failure);    exit (obstack_exit_failure);
492  }  }
493    
494  #if 0  # if 0
495  /* These are now turned off because the applications do not use it  /* These are now turned off because the applications do not use it
496     and it uses bcopy via obstack_grow, which causes trouble on sysV.  */     and it uses bcopy via obstack_grow, which causes trouble on sysV.  */
497    
498  /* Now define the functional versions of the obstack macros.  /* Now define the functional versions of the obstack macros.
499     Define them to simply use the corresponding macros to do the job.  */     Define them to simply use the corresponding macros to do the job.  */
500    
501  #if defined (__STDC__) && __STDC__  #  if defined __STDC__ && __STDC__
502  /* These function definitions do not work with non-ANSI preprocessors;  /* These function definitions do not work with non-ANSI preprocessors;
503     they won't pass through the macro names in parentheses.  */     they won't pass through the macro names in parentheses.  */
504    
# Line 520  int (obstack_make_room) (obstack, length Line 536  int (obstack_make_room) (obstack, length
536    return obstack_make_room (obstack, length);    return obstack_make_room (obstack, length);
537  }  }
538    
539  void (obstack_grow) (obstack, pointer, length)  void (obstack_grow) (obstack, data, length)
540       struct obstack *obstack;       struct obstack *obstack;
541       POINTER pointer;       const POINTER data;
542       int length;       int length;
543  {  {
544    obstack_grow (obstack, pointer, length);    obstack_grow (obstack, data, length);
545  }  }
546    
547  void (obstack_grow0) (obstack, pointer, length)  void (obstack_grow0) (obstack, data, length)
548       struct obstack *obstack;       struct obstack *obstack;
549       POINTER pointer;       const POINTER data;
550       int length;       int length;
551  {  {
552    obstack_grow0 (obstack, pointer, length);    obstack_grow0 (obstack, data, length);
553  }  }
554    
555  void (obstack_1grow) (obstack, character)  void (obstack_1grow) (obstack, character)
# Line 577  POINTER (obstack_alloc) (obstack, length Line 593  POINTER (obstack_alloc) (obstack, length
593    return obstack_alloc (obstack, length);    return obstack_alloc (obstack, length);
594  }  }
595    
596  POINTER (obstack_copy) (obstack, pointer, length)  POINTER (obstack_copy) (obstack, address, length)
597       struct obstack *obstack;       struct obstack *obstack;
598       POINTER pointer;       const POINTER address;
599       int length;       int length;
600  {  {
601    return obstack_copy (obstack, pointer, length);    return obstack_copy (obstack, address, length);
602  }  }
603    
604  POINTER (obstack_copy0) (obstack, pointer, length)  POINTER (obstack_copy0) (obstack, address, length)
605       struct obstack *obstack;       struct obstack *obstack;
606       POINTER pointer;       const POINTER address;
607       int length;       int length;
608  {  {
609    return obstack_copy0 (obstack, pointer, length);    return obstack_copy0 (obstack, address, length);
610  }  }
611    
612  #endif /* __STDC__ */  #  endif /* __STDC__ */
613    
614  #endif /* 0 */  # endif /* 0 */
615    
616  #endif  /* !ELIDE_CODE */  #endif  /* !ELIDE_CODE */

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26