mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-22 10:12:10 +01:00
Add checks for alloca, defining G_NATIVE_ALLOCA if present.
Fri Jan 22 13:41:41 EST 1999 Jeff Garzik <jgarzik@pobox.com> * configure.in: Add checks for alloca, defining G_NATIVE_ALLOCA if present. * galloca.c: Import replacement alloca implementation from gettext 0.10.35. Begin to convert to using GLib types and functions. * glib.h: New macros g_alloca, g_alloca_gc, g_alloca_new, to perform stack-based memory allocations. * tests/Makefile.am, tests/queue-test.c, tests/alloca-test.c: New tests for g_alloca_*, GQueue ADT. * tests/stack-test.c: Fix pointer casts, include config.h, and call g_stack_free at end of run.
This commit is contained in:
parent
b5706b2604
commit
0d0f178c09
22
ChangeLog
22
ChangeLog
@ -1,7 +1,27 @@
|
|||||||
|
Fri Jan 22 13:41:41 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
|
||||||
|
* configure.in:
|
||||||
|
Add checks for alloca, defining G_NATIVE_ALLOCA if present.
|
||||||
|
|
||||||
|
* galloca.c:
|
||||||
|
Import replacement alloca implementation from gettext 0.10.35.
|
||||||
|
Begin to convert to using GLib types and functions.
|
||||||
|
|
||||||
|
* glib.h:
|
||||||
|
New macros g_alloca, g_alloca_gc, g_alloca_new, to perform
|
||||||
|
stack-based memory allocations.
|
||||||
|
|
||||||
|
* tests/Makefile.am, tests/queue-test.c, tests/alloca-test.c:
|
||||||
|
New tests for g_alloca_*, GQueue ADT.
|
||||||
|
|
||||||
|
* tests/stack-test.c:
|
||||||
|
Fix pointer casts, include config.h, and
|
||||||
|
call g_stack_free at end of run.
|
||||||
|
|
||||||
Fri Jan 22 11:58:13 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
Fri Jan 22 11:58:13 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
|
||||||
* Makefile.am:
|
* Makefile.am:
|
||||||
Add gqueue.c
|
Add gqueue.c.
|
||||||
|
|
||||||
* glib.h:
|
* glib.h:
|
||||||
Add GQueue struct and prototypes.
|
Add GQueue struct and prototypes.
|
||||||
|
@ -1,7 +1,27 @@
|
|||||||
|
Fri Jan 22 13:41:41 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
|
||||||
|
* configure.in:
|
||||||
|
Add checks for alloca, defining G_NATIVE_ALLOCA if present.
|
||||||
|
|
||||||
|
* galloca.c:
|
||||||
|
Import replacement alloca implementation from gettext 0.10.35.
|
||||||
|
Begin to convert to using GLib types and functions.
|
||||||
|
|
||||||
|
* glib.h:
|
||||||
|
New macros g_alloca, g_alloca_gc, g_alloca_new, to perform
|
||||||
|
stack-based memory allocations.
|
||||||
|
|
||||||
|
* tests/Makefile.am, tests/queue-test.c, tests/alloca-test.c:
|
||||||
|
New tests for g_alloca_*, GQueue ADT.
|
||||||
|
|
||||||
|
* tests/stack-test.c:
|
||||||
|
Fix pointer casts, include config.h, and
|
||||||
|
call g_stack_free at end of run.
|
||||||
|
|
||||||
Fri Jan 22 11:58:13 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
Fri Jan 22 11:58:13 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
|
||||||
* Makefile.am:
|
* Makefile.am:
|
||||||
Add gqueue.c
|
Add gqueue.c.
|
||||||
|
|
||||||
* glib.h:
|
* glib.h:
|
||||||
Add GQueue struct and prototypes.
|
Add GQueue struct and prototypes.
|
||||||
|
@ -1,7 +1,27 @@
|
|||||||
|
Fri Jan 22 13:41:41 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
|
||||||
|
* configure.in:
|
||||||
|
Add checks for alloca, defining G_NATIVE_ALLOCA if present.
|
||||||
|
|
||||||
|
* galloca.c:
|
||||||
|
Import replacement alloca implementation from gettext 0.10.35.
|
||||||
|
Begin to convert to using GLib types and functions.
|
||||||
|
|
||||||
|
* glib.h:
|
||||||
|
New macros g_alloca, g_alloca_gc, g_alloca_new, to perform
|
||||||
|
stack-based memory allocations.
|
||||||
|
|
||||||
|
* tests/Makefile.am, tests/queue-test.c, tests/alloca-test.c:
|
||||||
|
New tests for g_alloca_*, GQueue ADT.
|
||||||
|
|
||||||
|
* tests/stack-test.c:
|
||||||
|
Fix pointer casts, include config.h, and
|
||||||
|
call g_stack_free at end of run.
|
||||||
|
|
||||||
Fri Jan 22 11:58:13 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
Fri Jan 22 11:58:13 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
|
||||||
* Makefile.am:
|
* Makefile.am:
|
||||||
Add gqueue.c
|
Add gqueue.c.
|
||||||
|
|
||||||
* glib.h:
|
* glib.h:
|
||||||
Add GQueue struct and prototypes.
|
Add GQueue struct and prototypes.
|
||||||
|
@ -1,7 +1,27 @@
|
|||||||
|
Fri Jan 22 13:41:41 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
|
||||||
|
* configure.in:
|
||||||
|
Add checks for alloca, defining G_NATIVE_ALLOCA if present.
|
||||||
|
|
||||||
|
* galloca.c:
|
||||||
|
Import replacement alloca implementation from gettext 0.10.35.
|
||||||
|
Begin to convert to using GLib types and functions.
|
||||||
|
|
||||||
|
* glib.h:
|
||||||
|
New macros g_alloca, g_alloca_gc, g_alloca_new, to perform
|
||||||
|
stack-based memory allocations.
|
||||||
|
|
||||||
|
* tests/Makefile.am, tests/queue-test.c, tests/alloca-test.c:
|
||||||
|
New tests for g_alloca_*, GQueue ADT.
|
||||||
|
|
||||||
|
* tests/stack-test.c:
|
||||||
|
Fix pointer casts, include config.h, and
|
||||||
|
call g_stack_free at end of run.
|
||||||
|
|
||||||
Fri Jan 22 11:58:13 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
Fri Jan 22 11:58:13 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
|
||||||
* Makefile.am:
|
* Makefile.am:
|
||||||
Add gqueue.c
|
Add gqueue.c.
|
||||||
|
|
||||||
* glib.h:
|
* glib.h:
|
||||||
Add GQueue struct and prototypes.
|
Add GQueue struct and prototypes.
|
||||||
|
@ -1,7 +1,27 @@
|
|||||||
|
Fri Jan 22 13:41:41 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
|
||||||
|
* configure.in:
|
||||||
|
Add checks for alloca, defining G_NATIVE_ALLOCA if present.
|
||||||
|
|
||||||
|
* galloca.c:
|
||||||
|
Import replacement alloca implementation from gettext 0.10.35.
|
||||||
|
Begin to convert to using GLib types and functions.
|
||||||
|
|
||||||
|
* glib.h:
|
||||||
|
New macros g_alloca, g_alloca_gc, g_alloca_new, to perform
|
||||||
|
stack-based memory allocations.
|
||||||
|
|
||||||
|
* tests/Makefile.am, tests/queue-test.c, tests/alloca-test.c:
|
||||||
|
New tests for g_alloca_*, GQueue ADT.
|
||||||
|
|
||||||
|
* tests/stack-test.c:
|
||||||
|
Fix pointer casts, include config.h, and
|
||||||
|
call g_stack_free at end of run.
|
||||||
|
|
||||||
Fri Jan 22 11:58:13 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
Fri Jan 22 11:58:13 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
|
||||||
* Makefile.am:
|
* Makefile.am:
|
||||||
Add gqueue.c
|
Add gqueue.c.
|
||||||
|
|
||||||
* glib.h:
|
* glib.h:
|
||||||
Add GQueue struct and prototypes.
|
Add GQueue struct and prototypes.
|
||||||
|
@ -1,7 +1,27 @@
|
|||||||
|
Fri Jan 22 13:41:41 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
|
||||||
|
* configure.in:
|
||||||
|
Add checks for alloca, defining G_NATIVE_ALLOCA if present.
|
||||||
|
|
||||||
|
* galloca.c:
|
||||||
|
Import replacement alloca implementation from gettext 0.10.35.
|
||||||
|
Begin to convert to using GLib types and functions.
|
||||||
|
|
||||||
|
* glib.h:
|
||||||
|
New macros g_alloca, g_alloca_gc, g_alloca_new, to perform
|
||||||
|
stack-based memory allocations.
|
||||||
|
|
||||||
|
* tests/Makefile.am, tests/queue-test.c, tests/alloca-test.c:
|
||||||
|
New tests for g_alloca_*, GQueue ADT.
|
||||||
|
|
||||||
|
* tests/stack-test.c:
|
||||||
|
Fix pointer casts, include config.h, and
|
||||||
|
call g_stack_free at end of run.
|
||||||
|
|
||||||
Fri Jan 22 11:58:13 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
Fri Jan 22 11:58:13 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
|
||||||
* Makefile.am:
|
* Makefile.am:
|
||||||
Add gqueue.c
|
Add gqueue.c.
|
||||||
|
|
||||||
* glib.h:
|
* glib.h:
|
||||||
Add GQueue struct and prototypes.
|
Add GQueue struct and prototypes.
|
||||||
|
@ -1,7 +1,27 @@
|
|||||||
|
Fri Jan 22 13:41:41 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
|
||||||
|
* configure.in:
|
||||||
|
Add checks for alloca, defining G_NATIVE_ALLOCA if present.
|
||||||
|
|
||||||
|
* galloca.c:
|
||||||
|
Import replacement alloca implementation from gettext 0.10.35.
|
||||||
|
Begin to convert to using GLib types and functions.
|
||||||
|
|
||||||
|
* glib.h:
|
||||||
|
New macros g_alloca, g_alloca_gc, g_alloca_new, to perform
|
||||||
|
stack-based memory allocations.
|
||||||
|
|
||||||
|
* tests/Makefile.am, tests/queue-test.c, tests/alloca-test.c:
|
||||||
|
New tests for g_alloca_*, GQueue ADT.
|
||||||
|
|
||||||
|
* tests/stack-test.c:
|
||||||
|
Fix pointer casts, include config.h, and
|
||||||
|
call g_stack_free at end of run.
|
||||||
|
|
||||||
Fri Jan 22 11:58:13 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
Fri Jan 22 11:58:13 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
|
||||||
* Makefile.am:
|
* Makefile.am:
|
||||||
Add gqueue.c
|
Add gqueue.c.
|
||||||
|
|
||||||
* glib.h:
|
* glib.h:
|
||||||
Add GQueue struct and prototypes.
|
Add GQueue struct and prototypes.
|
||||||
|
@ -1,7 +1,27 @@
|
|||||||
|
Fri Jan 22 13:41:41 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
|
||||||
|
* configure.in:
|
||||||
|
Add checks for alloca, defining G_NATIVE_ALLOCA if present.
|
||||||
|
|
||||||
|
* galloca.c:
|
||||||
|
Import replacement alloca implementation from gettext 0.10.35.
|
||||||
|
Begin to convert to using GLib types and functions.
|
||||||
|
|
||||||
|
* glib.h:
|
||||||
|
New macros g_alloca, g_alloca_gc, g_alloca_new, to perform
|
||||||
|
stack-based memory allocations.
|
||||||
|
|
||||||
|
* tests/Makefile.am, tests/queue-test.c, tests/alloca-test.c:
|
||||||
|
New tests for g_alloca_*, GQueue ADT.
|
||||||
|
|
||||||
|
* tests/stack-test.c:
|
||||||
|
Fix pointer casts, include config.h, and
|
||||||
|
call g_stack_free at end of run.
|
||||||
|
|
||||||
Fri Jan 22 11:58:13 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
Fri Jan 22 11:58:13 EST 1999 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
|
||||||
* Makefile.am:
|
* Makefile.am:
|
||||||
Add gqueue.c
|
Add gqueue.c.
|
||||||
|
|
||||||
* glib.h:
|
* glib.h:
|
||||||
Add GQueue struct and prototypes.
|
Add GQueue struct and prototypes.
|
||||||
|
47
configure.in
47
configure.in
@ -171,6 +171,12 @@ AC_HEADER_STDC
|
|||||||
|
|
||||||
# Checks for library functions.
|
# Checks for library functions.
|
||||||
AC_FUNC_VPRINTF
|
AC_FUNC_VPRINTF
|
||||||
|
AC_FUNC_ALLOCA
|
||||||
|
if test "x$ac_cv_func_alloca_works" = xyes; then
|
||||||
|
glib_have_alloca=yes
|
||||||
|
else
|
||||||
|
glib_have_alloca=no
|
||||||
|
fi
|
||||||
|
|
||||||
AC_CHECK_FUNCS(atexit on_exit)
|
AC_CHECK_FUNCS(atexit on_exit)
|
||||||
|
|
||||||
@ -248,6 +254,7 @@ AC_CHECK_HEADERS(sys/time.h, AC_DEFINE(HAVE_SYS_TIME_H))
|
|||||||
AC_CHECK_HEADERS(sys/times.h, AC_DEFINE(HAVE_SYS_TIMES_H))
|
AC_CHECK_HEADERS(sys/times.h, AC_DEFINE(HAVE_SYS_TIMES_H))
|
||||||
AC_CHECK_HEADERS(unistd.h, AC_DEFINE(HAVE_UNISTD_H))
|
AC_CHECK_HEADERS(unistd.h, AC_DEFINE(HAVE_UNISTD_H))
|
||||||
AC_CHECK_HEADERS(values.h, AC_DEFINE(HAVE_VALUES_H))
|
AC_CHECK_HEADERS(values.h, AC_DEFINE(HAVE_VALUES_H))
|
||||||
|
AC_CHECK_HEADER(alloca.h, glib_have_alloca_h=yes, glib_have_alloca_h=no)
|
||||||
|
|
||||||
# Check for some functions
|
# Check for some functions
|
||||||
AC_CHECK_FUNCS(lstat strerror strsignal memmove vsnprintf strcasecmp strncasecmp poll)
|
AC_CHECK_FUNCS(lstat strerror strsignal memmove vsnprintf strcasecmp strncasecmp poll)
|
||||||
@ -904,6 +911,7 @@ _______EOF
|
|||||||
cat >>$outfile <<_______EOF
|
cat >>$outfile <<_______EOF
|
||||||
$glib_atexit
|
$glib_atexit
|
||||||
$glib_memmove
|
$glib_memmove
|
||||||
|
$glib_alloca
|
||||||
$glib_defines
|
$glib_defines
|
||||||
|
|
||||||
$glib_vacopy
|
$glib_vacopy
|
||||||
@ -1169,6 +1177,45 @@ if test x$glib_working_wctype = xno; then
|
|||||||
#define G_HAVE_BROKEN_WCTYPE 1"
|
#define G_HAVE_BROKEN_WCTYPE 1"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test x$glib_have_alloca = xyes; then
|
||||||
|
glib_alloca="
|
||||||
|
|
||||||
|
/* alloca support */"
|
||||||
|
|
||||||
|
if test x$glib_have_alloca_h = xyes; then
|
||||||
|
glib_alloca="\$glib_alloca
|
||||||
|
#define G_HAVE_ALLOCA_H 1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
glib_alloca="\$glib_alloca
|
||||||
|
#define G_NATIVE_ALLOCA 1
|
||||||
|
|
||||||
|
/* BEGIN autoconf 2.13 alloca incantation
|
||||||
|
NOTE: Do not un-indent the #pragma below. */
|
||||||
|
/* AIX requires this to be the first thing in the file. */
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# ifndef alloca
|
||||||
|
# define alloca __builtin_alloca
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# if G_HAVE_ALLOCA_H
|
||||||
|
# include <alloca.h>
|
||||||
|
# else
|
||||||
|
# ifdef _AIX
|
||||||
|
#pragma alloca
|
||||||
|
# else
|
||||||
|
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||||
|
char *alloca ();
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
/* END autoconf 2.13 alloca incantation */
|
||||||
|
|
||||||
|
|
||||||
|
"
|
||||||
|
fi
|
||||||
|
|
||||||
case x$enable_threads in
|
case x$enable_threads in
|
||||||
xyes) g_enable_threads_def="#define";;
|
xyes) g_enable_threads_def="#define";;
|
||||||
*) g_enable_threads_def="#undef ";;
|
*) g_enable_threads_def="#undef ";;
|
||||||
|
456
galloca.c
Normal file
456
galloca.c
Normal file
@ -0,0 +1,456 @@
|
|||||||
|
/* alloca.c -- allocate automatically reclaimed memory
|
||||||
|
(Mostly) portable public-domain implementation -- D A Gwyn
|
||||||
|
|
||||||
|
This implementation of the PWB library alloca function,
|
||||||
|
which is used to allocate space off the run-time stack so
|
||||||
|
that it is automatically reclaimed upon procedure exit,
|
||||||
|
was inspired by discussions with J. Q. Johnson of Cornell.
|
||||||
|
J.Otto Tennant <jot@cray.com> contributed the Cray support.
|
||||||
|
|
||||||
|
There are some preprocessor constants that can
|
||||||
|
be defined when compiling for your specific system, for
|
||||||
|
improved efficiency; however, the defaults should be okay.
|
||||||
|
|
||||||
|
The general concept of this implementation is to keep
|
||||||
|
track of all alloca-allocated blocks, and reclaim any
|
||||||
|
that are found to be deeper in the stack than the current
|
||||||
|
invocation. This heuristic does not reclaim storage as
|
||||||
|
soon as it becomes invalid, but it will do so eventually.
|
||||||
|
|
||||||
|
As a special case, alloca(0) reclaims storage without
|
||||||
|
allocating any. It is a good idea to use alloca(0) in
|
||||||
|
your main control loop, etc. to force garbage collection. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STDC_HEADERS
|
||||||
|
# include <string.h>
|
||||||
|
# include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef G_NATIVE_ALLOCA
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* If your stack is a linked list of frames, you have to
|
||||||
|
provide an "address metric" ADDRESS_FUNCTION macro. */
|
||||||
|
|
||||||
|
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||||
|
long i00afunc ();
|
||||||
|
#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
|
||||||
|
#else
|
||||||
|
#define ADDRESS_FUNCTION(arg) &(arg)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Define STACK_DIRECTION if you know the direction of stack
|
||||||
|
growth for your system; otherwise it will be automatically
|
||||||
|
deduced at run-time.
|
||||||
|
|
||||||
|
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||||
|
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||||
|
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||||
|
|
||||||
|
#ifndef STACK_DIRECTION
|
||||||
|
#define STACK_DIRECTION 0 /* Direction unknown. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STACK_DIRECTION != 0
|
||||||
|
|
||||||
|
#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
|
||||||
|
|
||||||
|
#else /* STACK_DIRECTION == 0; need run-time code. */
|
||||||
|
|
||||||
|
static int stack_dir; /* 1 or -1 once known. */
|
||||||
|
#define STACK_DIR stack_dir
|
||||||
|
|
||||||
|
static void
|
||||||
|
find_stack_direction ()
|
||||||
|
{
|
||||||
|
static char *addr = NULL; /* Address of first `dummy', once known. */
|
||||||
|
auto char dummy; /* To get stack address. */
|
||||||
|
|
||||||
|
if (addr == NULL)
|
||||||
|
{ /* Initial entry. */
|
||||||
|
addr = ADDRESS_FUNCTION (dummy);
|
||||||
|
|
||||||
|
find_stack_direction (); /* Recurse once. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Second entry. */
|
||||||
|
if (ADDRESS_FUNCTION (dummy) > addr)
|
||||||
|
stack_dir = 1; /* Stack grew upward. */
|
||||||
|
else
|
||||||
|
stack_dir = -1; /* Stack grew downward. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* STACK_DIRECTION == 0 */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* An "alloca header" is used to:
|
||||||
|
(a) chain together all alloca'ed blocks;
|
||||||
|
(b) keep track of stack depth.
|
||||||
|
|
||||||
|
It is very important that sizeof(header) agree with malloc
|
||||||
|
alignment chunk size. The following default should work okay. */
|
||||||
|
|
||||||
|
#ifndef ALIGN_SIZE
|
||||||
|
#define ALIGN_SIZE sizeof(double)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef union hdr
|
||||||
|
{
|
||||||
|
char align[ALIGN_SIZE]; /* To force sizeof(header). */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
union hdr *next; /* For chaining headers. */
|
||||||
|
char *deep; /* For stack depth measure. */
|
||||||
|
} h;
|
||||||
|
} header;
|
||||||
|
|
||||||
|
static header *last_alloca_header = NULL; /* -> last alloca header. */
|
||||||
|
|
||||||
|
/* Return a pointer to at least SIZE bytes of storage,
|
||||||
|
which will be automatically reclaimed upon exit from
|
||||||
|
the procedure that called alloca. Originally, this space
|
||||||
|
was supposed to be taken from the current stack frame of the
|
||||||
|
caller, but that method cannot be made to work for some
|
||||||
|
implementations of C, for example under Gould's UTX/32. */
|
||||||
|
|
||||||
|
gpointer
|
||||||
|
_g_alloca (guint size)
|
||||||
|
{
|
||||||
|
auto char probe; /* Probes stack depth: */
|
||||||
|
char *depth = ADDRESS_FUNCTION (probe);
|
||||||
|
|
||||||
|
#if STACK_DIRECTION == 0
|
||||||
|
if (STACK_DIR == 0) /* Unknown growth direction. */
|
||||||
|
find_stack_direction ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Reclaim garbage, defined as all alloca'd storage that
|
||||||
|
was allocated from deeper in the stack than currently. */
|
||||||
|
|
||||||
|
{
|
||||||
|
header *hp; /* Traverses linked list. */
|
||||||
|
|
||||||
|
for (hp = last_alloca_header; hp != NULL;)
|
||||||
|
if ((STACK_DIR > 0 && hp->h.deep > depth)
|
||||||
|
|| (STACK_DIR < 0 && hp->h.deep < depth))
|
||||||
|
{
|
||||||
|
header *np = hp->h.next;
|
||||||
|
|
||||||
|
g_free ((gpointer) hp); /* Collect garbage. */
|
||||||
|
|
||||||
|
hp = np; /* -> next header. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break; /* Rest are not deeper. */
|
||||||
|
|
||||||
|
last_alloca_header = hp; /* -> last valid storage. */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
return NULL; /* No allocation required. */
|
||||||
|
|
||||||
|
/* Allocate combined header + user data storage. */
|
||||||
|
|
||||||
|
{
|
||||||
|
/* GLib: use mem chunks here? */
|
||||||
|
gpointer new = g_malloc (sizeof (header) + size);
|
||||||
|
/* Address of header. */
|
||||||
|
|
||||||
|
if (new == 0)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
((header *) new)->h.next = last_alloca_header;
|
||||||
|
((header *) new)->h.deep = depth;
|
||||||
|
|
||||||
|
last_alloca_header = (header *) new;
|
||||||
|
|
||||||
|
/* User storage begins just after header. */
|
||||||
|
|
||||||
|
return (gpointer) ((char *) new + sizeof (header));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||||
|
|
||||||
|
#ifdef DEBUG_I00AFUNC
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRAY_STACK
|
||||||
|
#define CRAY_STACK
|
||||||
|
#ifndef CRAY2
|
||||||
|
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
|
||||||
|
struct stack_control_header
|
||||||
|
{
|
||||||
|
long shgrow:32; /* Number of times stack has grown. */
|
||||||
|
long shaseg:32; /* Size of increments to stack. */
|
||||||
|
long shhwm:32; /* High water mark of stack. */
|
||||||
|
long shsize:32; /* Current size of stack (all segments). */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The stack segment linkage control information occurs at
|
||||||
|
the high-address end of a stack segment. (The stack
|
||||||
|
grows from low addresses to high addresses.) The initial
|
||||||
|
part of the stack segment linkage control information is
|
||||||
|
0200 (octal) words. This provides for register storage
|
||||||
|
for the routine which overflows the stack. */
|
||||||
|
|
||||||
|
struct stack_segment_linkage
|
||||||
|
{
|
||||||
|
long ss[0200]; /* 0200 overflow words. */
|
||||||
|
long sssize:32; /* Number of words in this segment. */
|
||||||
|
long ssbase:32; /* Offset to stack base. */
|
||||||
|
long:32;
|
||||||
|
long sspseg:32; /* Offset to linkage control of previous
|
||||||
|
segment of stack. */
|
||||||
|
long:32;
|
||||||
|
long sstcpt:32; /* Pointer to task common address block. */
|
||||||
|
long sscsnm; /* Private control structure number for
|
||||||
|
microtasking. */
|
||||||
|
long ssusr1; /* Reserved for user. */
|
||||||
|
long ssusr2; /* Reserved for user. */
|
||||||
|
long sstpid; /* Process ID for pid based multi-tasking. */
|
||||||
|
long ssgvup; /* Pointer to multitasking thread giveup. */
|
||||||
|
long sscray[7]; /* Reserved for Cray Research. */
|
||||||
|
long ssa0;
|
||||||
|
long ssa1;
|
||||||
|
long ssa2;
|
||||||
|
long ssa3;
|
||||||
|
long ssa4;
|
||||||
|
long ssa5;
|
||||||
|
long ssa6;
|
||||||
|
long ssa7;
|
||||||
|
long sss0;
|
||||||
|
long sss1;
|
||||||
|
long sss2;
|
||||||
|
long sss3;
|
||||||
|
long sss4;
|
||||||
|
long sss5;
|
||||||
|
long sss6;
|
||||||
|
long sss7;
|
||||||
|
};
|
||||||
|
|
||||||
|
#else /* CRAY2 */
|
||||||
|
/* The following structure defines the vector of words
|
||||||
|
returned by the STKSTAT library routine. */
|
||||||
|
struct stk_stat
|
||||||
|
{
|
||||||
|
long now; /* Current total stack size. */
|
||||||
|
long maxc; /* Amount of contiguous space which would
|
||||||
|
be required to satisfy the maximum
|
||||||
|
stack demand to date. */
|
||||||
|
long high_water; /* Stack high-water mark. */
|
||||||
|
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
|
||||||
|
long hits; /* Number of internal buffer hits. */
|
||||||
|
long extends; /* Number of block extensions. */
|
||||||
|
long stko_mallocs; /* Block allocations by $STKOFEN. */
|
||||||
|
long underflows; /* Number of stack underflow calls ($STKRETN). */
|
||||||
|
long stko_free; /* Number of deallocations by $STKRETN. */
|
||||||
|
long stkm_free; /* Number of deallocations by $STKMRET. */
|
||||||
|
long segments; /* Current number of stack segments. */
|
||||||
|
long maxs; /* Maximum number of stack segments so far. */
|
||||||
|
long pad_size; /* Stack pad size. */
|
||||||
|
long current_address; /* Current stack segment address. */
|
||||||
|
long current_size; /* Current stack segment size. This
|
||||||
|
number is actually corrupted by STKSTAT to
|
||||||
|
include the fifteen word trailer area. */
|
||||||
|
long initial_address; /* Address of initial segment. */
|
||||||
|
long initial_size; /* Size of initial segment. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The following structure describes the data structure which trails
|
||||||
|
any stack segment. I think that the description in 'asdef' is
|
||||||
|
out of date. I only describe the parts that I am sure about. */
|
||||||
|
|
||||||
|
struct stk_trailer
|
||||||
|
{
|
||||||
|
long this_address; /* Address of this block. */
|
||||||
|
long this_size; /* Size of this block (does not include
|
||||||
|
this trailer). */
|
||||||
|
long unknown2;
|
||||||
|
long unknown3;
|
||||||
|
long link; /* Address of trailer block of previous
|
||||||
|
segment. */
|
||||||
|
long unknown5;
|
||||||
|
long unknown6;
|
||||||
|
long unknown7;
|
||||||
|
long unknown8;
|
||||||
|
long unknown9;
|
||||||
|
long unknown10;
|
||||||
|
long unknown11;
|
||||||
|
long unknown12;
|
||||||
|
long unknown13;
|
||||||
|
long unknown14;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* CRAY2 */
|
||||||
|
#endif /* not CRAY_STACK */
|
||||||
|
|
||||||
|
#ifdef CRAY2
|
||||||
|
/* Determine a "stack measure" for an arbitrary ADDRESS.
|
||||||
|
I doubt that "lint" will like this much. */
|
||||||
|
|
||||||
|
static long
|
||||||
|
i00afunc (long *address)
|
||||||
|
{
|
||||||
|
struct stk_stat status;
|
||||||
|
struct stk_trailer *trailer;
|
||||||
|
long *block, size;
|
||||||
|
long result = 0;
|
||||||
|
|
||||||
|
/* We want to iterate through all of the segments. The first
|
||||||
|
step is to get the stack status structure. We could do this
|
||||||
|
more quickly and more directly, perhaps, by referencing the
|
||||||
|
$LM00 common block, but I know that this works. */
|
||||||
|
|
||||||
|
STKSTAT (&status);
|
||||||
|
|
||||||
|
/* Set up the iteration. */
|
||||||
|
|
||||||
|
trailer = (struct stk_trailer *) (status.current_address
|
||||||
|
+ status.current_size
|
||||||
|
- 15);
|
||||||
|
|
||||||
|
/* There must be at least one stack segment. Therefore it is
|
||||||
|
a fatal error if "trailer" is null. */
|
||||||
|
|
||||||
|
if (trailer == 0)
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
/* Discard segments that do not contain our argument address. */
|
||||||
|
|
||||||
|
while (trailer != 0)
|
||||||
|
{
|
||||||
|
block = (long *) trailer->this_address;
|
||||||
|
size = trailer->this_size;
|
||||||
|
if (block == 0 || size == 0)
|
||||||
|
abort ();
|
||||||
|
trailer = (struct stk_trailer *) trailer->link;
|
||||||
|
if ((block <= address) && (address < (block + size)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the result to the offset in this segment and add the sizes
|
||||||
|
of all predecessor segments. */
|
||||||
|
|
||||||
|
result = address - block;
|
||||||
|
|
||||||
|
if (trailer == 0)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (trailer->this_size <= 0)
|
||||||
|
abort ();
|
||||||
|
result += trailer->this_size;
|
||||||
|
trailer = (struct stk_trailer *) trailer->link;
|
||||||
|
}
|
||||||
|
while (trailer != 0);
|
||||||
|
|
||||||
|
/* We are done. Note that if you present a bogus address (one
|
||||||
|
not in any segment), you will get a different number back, formed
|
||||||
|
from subtracting the address of the first block. This is probably
|
||||||
|
not what you want. */
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* not CRAY2 */
|
||||||
|
/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
|
||||||
|
Determine the number of the cell within the stack,
|
||||||
|
given the address of the cell. The purpose of this
|
||||||
|
routine is to linearize, in some sense, stack addresses
|
||||||
|
for alloca. */
|
||||||
|
|
||||||
|
static long
|
||||||
|
i00afunc (long address)
|
||||||
|
{
|
||||||
|
long stkl = 0;
|
||||||
|
|
||||||
|
long size, pseg, this_segment, stack;
|
||||||
|
long result = 0;
|
||||||
|
|
||||||
|
struct stack_segment_linkage *ssptr;
|
||||||
|
|
||||||
|
/* Register B67 contains the address of the end of the
|
||||||
|
current stack segment. If you (as a subprogram) store
|
||||||
|
your registers on the stack and find that you are past
|
||||||
|
the contents of B67, you have overflowed the segment.
|
||||||
|
|
||||||
|
B67 also points to the stack segment linkage control
|
||||||
|
area, which is what we are really interested in. */
|
||||||
|
|
||||||
|
stkl = CRAY_STACKSEG_END ();
|
||||||
|
ssptr = (struct stack_segment_linkage *) stkl;
|
||||||
|
|
||||||
|
/* If one subtracts 'size' from the end of the segment,
|
||||||
|
one has the address of the first word of the segment.
|
||||||
|
|
||||||
|
If this is not the first segment, 'pseg' will be
|
||||||
|
nonzero. */
|
||||||
|
|
||||||
|
pseg = ssptr->sspseg;
|
||||||
|
size = ssptr->sssize;
|
||||||
|
|
||||||
|
this_segment = stkl - size;
|
||||||
|
|
||||||
|
/* It is possible that calling this routine itself caused
|
||||||
|
a stack overflow. Discard stack segments which do not
|
||||||
|
contain the target address. */
|
||||||
|
|
||||||
|
while (!(this_segment <= address && address <= stkl))
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_I00AFUNC
|
||||||
|
fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
|
||||||
|
#endif
|
||||||
|
if (pseg == 0)
|
||||||
|
break;
|
||||||
|
stkl = stkl - pseg;
|
||||||
|
ssptr = (struct stack_segment_linkage *) stkl;
|
||||||
|
size = ssptr->sssize;
|
||||||
|
pseg = ssptr->sspseg;
|
||||||
|
this_segment = stkl - size;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = address - this_segment;
|
||||||
|
|
||||||
|
/* If you subtract pseg from the current end of the stack,
|
||||||
|
you get the address of the previous stack segment's end.
|
||||||
|
This seems a little convoluted to me, but I'll bet you save
|
||||||
|
a cycle somewhere. */
|
||||||
|
|
||||||
|
while (pseg != 0)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_I00AFUNC
|
||||||
|
fprintf (stderr, "%011o %011o\n", pseg, size);
|
||||||
|
#endif
|
||||||
|
stkl = stkl - pseg;
|
||||||
|
ssptr = (struct stack_segment_linkage *) stkl;
|
||||||
|
size = ssptr->sssize;
|
||||||
|
pseg = ssptr->sspseg;
|
||||||
|
result += size;
|
||||||
|
}
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* not CRAY2 */
|
||||||
|
#endif /* CRAY */
|
||||||
|
|
||||||
|
#endif /* !G_NATIVE_ALLOCA */
|
22
glib.h
22
glib.h
@ -318,6 +318,24 @@ extern "C" {
|
|||||||
} G_STMT_END
|
} G_STMT_END
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Stack-based temporary allocation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if G_NATIVE_ALLOCA
|
||||||
|
# define g_alloca alloca
|
||||||
|
# define g_alloca_gc() /* nothing to do for garbage collection */
|
||||||
|
#else /* !G_NATIVE_ALLOCA */
|
||||||
|
gpointer _g_alloca (gulong size);
|
||||||
|
# define g_alloca _g_alloca
|
||||||
|
# define g_alloca_gc() _g_alloca (0)
|
||||||
|
#endif /* !G_NATIVE_ALLOCA */
|
||||||
|
|
||||||
|
#define g_alloca_new(type, count) \
|
||||||
|
((type *) g_alloca ((unsigned) sizeof (type) * (count)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define g_string(x) #x
|
#define g_string(x) #x
|
||||||
|
|
||||||
|
|
||||||
@ -977,8 +995,8 @@ void g_queue_push_back (GQueue *q, gpointer data);
|
|||||||
gpointer g_queue_pop_front (GQueue *q);
|
gpointer g_queue_pop_front (GQueue *q);
|
||||||
gpointer g_queue_pop_back (GQueue *q);
|
gpointer g_queue_pop_back (GQueue *q);
|
||||||
|
|
||||||
#define q_queue_push q_queue_push_back
|
#define g_queue_push g_queue_push_back
|
||||||
#define q_queue_pop q_queue_pop_front
|
#define g_queue_pop g_queue_pop_front
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
22
glib/glib.h
22
glib/glib.h
@ -318,6 +318,24 @@ extern "C" {
|
|||||||
} G_STMT_END
|
} G_STMT_END
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Stack-based temporary allocation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if G_NATIVE_ALLOCA
|
||||||
|
# define g_alloca alloca
|
||||||
|
# define g_alloca_gc() /* nothing to do for garbage collection */
|
||||||
|
#else /* !G_NATIVE_ALLOCA */
|
||||||
|
gpointer _g_alloca (gulong size);
|
||||||
|
# define g_alloca _g_alloca
|
||||||
|
# define g_alloca_gc() _g_alloca (0)
|
||||||
|
#endif /* !G_NATIVE_ALLOCA */
|
||||||
|
|
||||||
|
#define g_alloca_new(type, count) \
|
||||||
|
((type *) g_alloca ((unsigned) sizeof (type) * (count)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define g_string(x) #x
|
#define g_string(x) #x
|
||||||
|
|
||||||
|
|
||||||
@ -977,8 +995,8 @@ void g_queue_push_back (GQueue *q, gpointer data);
|
|||||||
gpointer g_queue_pop_front (GQueue *q);
|
gpointer g_queue_pop_front (GQueue *q);
|
||||||
gpointer g_queue_pop_back (GQueue *q);
|
gpointer g_queue_pop_back (GQueue *q);
|
||||||
|
|
||||||
#define q_queue_push q_queue_push_back
|
#define g_queue_push g_queue_push_back
|
||||||
#define q_queue_pop q_queue_pop_front
|
#define g_queue_pop g_queue_pop_front
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,3 +34,5 @@ dirname-test
|
|||||||
type-test
|
type-test
|
||||||
strfunc-test
|
strfunc-test
|
||||||
stack-test
|
stack-test
|
||||||
|
queue-test
|
||||||
|
alloca-test
|
||||||
|
@ -2,11 +2,13 @@
|
|||||||
INCLUDES = -I$(top_srcdir)
|
INCLUDES = -I$(top_srcdir)
|
||||||
|
|
||||||
TESTS = \
|
TESTS = \
|
||||||
|
alloca-test \
|
||||||
array-test \
|
array-test \
|
||||||
dirname-test \
|
dirname-test \
|
||||||
hash-test \
|
hash-test \
|
||||||
list-test \
|
list-test \
|
||||||
node-test \
|
node-test \
|
||||||
|
queue-test \
|
||||||
relation-test \
|
relation-test \
|
||||||
slist-test \
|
slist-test \
|
||||||
stack-test \
|
stack-test \
|
||||||
@ -17,11 +19,13 @@ TESTS = \
|
|||||||
|
|
||||||
noinst_PROGRAMS = $(TESTS)
|
noinst_PROGRAMS = $(TESTS)
|
||||||
|
|
||||||
|
alloca_test_LDADD = $(top_builddir)/libglib.la
|
||||||
array_test_LDADD = $(top_builddir)/libglib.la
|
array_test_LDADD = $(top_builddir)/libglib.la
|
||||||
dirname_test_LDADD = $(top_builddir)/libglib.la
|
dirname_test_LDADD = $(top_builddir)/libglib.la
|
||||||
hash_test_LDADD = $(top_builddir)/libglib.la
|
hash_test_LDADD = $(top_builddir)/libglib.la
|
||||||
list_test_LDADD = $(top_builddir)/libglib.la
|
list_test_LDADD = $(top_builddir)/libglib.la
|
||||||
node_test_LDADD = $(top_builddir)/libglib.la
|
node_test_LDADD = $(top_builddir)/libglib.la
|
||||||
|
queue_test_LDADD = $(top_builddir)/libglib.la
|
||||||
relation_test_LDADD = $(top_builddir)/libglib.la
|
relation_test_LDADD = $(top_builddir)/libglib.la
|
||||||
slist_test_LDADD = $(top_builddir)/libglib.la
|
slist_test_LDADD = $(top_builddir)/libglib.la
|
||||||
stack_test_LDADD = $(top_builddir)/libglib.la
|
stack_test_LDADD = $(top_builddir)/libglib.la
|
||||||
|
44
tests/alloca-test.c
Normal file
44
tests/alloca-test.c
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STDC_HEADERS
|
||||||
|
# include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
struct test_t {
|
||||||
|
int age;
|
||||||
|
char name [19];
|
||||||
|
int stuph;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void test_alloca (void)
|
||||||
|
{
|
||||||
|
gpointer data;
|
||||||
|
struct test_t *t;
|
||||||
|
|
||||||
|
data = g_alloca (15);
|
||||||
|
strcpy ((char *) data, "blah blah blah");
|
||||||
|
g_assert (strcmp ((char *) data, "blah blah blah") == 0);
|
||||||
|
|
||||||
|
t = g_alloca_new (struct test_t, 1);
|
||||||
|
t->age = 142;
|
||||||
|
t->stuph = 0xBEDAC0ED;
|
||||||
|
strcpy (t->name, "nyognyou hoddypeak");
|
||||||
|
g_assert (t->stuph == 0xBEDAC0ED);
|
||||||
|
g_assert (strcmp (t->name, "nyognyou hoddypeak") == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test_alloca ();
|
||||||
|
|
||||||
|
g_alloca_gc ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
70
tests/queue-test.c
Normal file
70
tests/queue-test.c
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
GQueue *q;
|
||||||
|
|
||||||
|
q = g_queue_new ();
|
||||||
|
|
||||||
|
g_queue_push (q, GINT_TO_POINTER (1));
|
||||||
|
g_assert (g_list_length (q->list) == 1);
|
||||||
|
g_queue_push (q, GINT_TO_POINTER (2));
|
||||||
|
g_assert (g_list_length (q->list) == 2);
|
||||||
|
g_queue_push (q, GINT_TO_POINTER (3));
|
||||||
|
g_assert (g_list_length (q->list) == 3);
|
||||||
|
g_queue_push (q, GINT_TO_POINTER (4));
|
||||||
|
g_assert (g_list_length (q->list) == 4);
|
||||||
|
g_queue_push (q, GINT_TO_POINTER (5));
|
||||||
|
g_assert (g_list_length (q->list) == 5);
|
||||||
|
|
||||||
|
g_assert (g_queue_pop (q) == GINT_TO_POINTER (1));
|
||||||
|
g_assert (g_list_length (q->list) == 4);
|
||||||
|
g_assert (g_queue_pop (q) == GINT_TO_POINTER (2));
|
||||||
|
g_assert (g_list_length (q->list) == 3);
|
||||||
|
g_assert (g_queue_pop (q) == GINT_TO_POINTER (3));
|
||||||
|
g_assert (g_list_length (q->list) == 2);
|
||||||
|
g_assert (g_queue_pop (q) == GINT_TO_POINTER (4));
|
||||||
|
g_assert (g_list_length (q->list) == 1);
|
||||||
|
g_assert (g_queue_pop (q) == GINT_TO_POINTER (5));
|
||||||
|
g_assert (g_list_length (q->list) == 0);
|
||||||
|
g_assert (g_queue_pop (q) == NULL);
|
||||||
|
g_assert (g_list_length (q->list) == 0);
|
||||||
|
g_assert (g_queue_pop (q) == NULL);
|
||||||
|
g_assert (g_list_length (q->list) == 0);
|
||||||
|
|
||||||
|
/************************/
|
||||||
|
|
||||||
|
g_queue_push_front (q, GINT_TO_POINTER (1));
|
||||||
|
g_assert (g_list_length (q->list) == 1);
|
||||||
|
g_queue_push_front (q, GINT_TO_POINTER (2));
|
||||||
|
g_assert (g_list_length (q->list) == 2);
|
||||||
|
g_queue_push_front (q, GINT_TO_POINTER (3));
|
||||||
|
g_assert (g_list_length (q->list) == 3);
|
||||||
|
g_queue_push_front (q, GINT_TO_POINTER (4));
|
||||||
|
g_assert (g_list_length (q->list) == 4);
|
||||||
|
g_queue_push_front (q, GINT_TO_POINTER (5));
|
||||||
|
g_assert (g_list_length (q->list) == 5);
|
||||||
|
|
||||||
|
g_assert (g_queue_pop_front (q) == GINT_TO_POINTER (5));
|
||||||
|
g_assert (g_list_length (q->list) == 4);
|
||||||
|
g_assert (g_queue_pop_front (q) == GINT_TO_POINTER (4));
|
||||||
|
g_assert (g_list_length (q->list) == 3);
|
||||||
|
g_assert (g_queue_pop_front (q) == GINT_TO_POINTER (3));
|
||||||
|
g_assert (g_list_length (q->list) == 2);
|
||||||
|
g_assert (g_queue_pop_front (q) == GINT_TO_POINTER (2));
|
||||||
|
g_assert (g_list_length (q->list) == 1);
|
||||||
|
g_assert (g_queue_pop_front (q) == GINT_TO_POINTER (1));
|
||||||
|
g_assert (g_list_length (q->list) == 0);
|
||||||
|
g_assert (g_queue_pop_front (q) == NULL);
|
||||||
|
g_assert (g_list_length (q->list) == 0);
|
||||||
|
g_assert (g_queue_pop_front (q) == NULL);
|
||||||
|
g_assert (g_list_length (q->list) == 0);
|
||||||
|
|
||||||
|
g_queue_free (q);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,7 @@
|
|||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
@ -17,21 +21,23 @@ int main()
|
|||||||
g_stack_push (s, GINT_TO_POINTER (5));
|
g_stack_push (s, GINT_TO_POINTER (5));
|
||||||
g_assert (g_list_length (s->list) == 5);
|
g_assert (g_list_length (s->list) == 5);
|
||||||
|
|
||||||
g_assert (g_stack_pop (s) == GPOINTER_TO_INT (5));
|
g_assert (g_stack_pop (s) == GINT_TO_POINTER (5));
|
||||||
g_assert (g_list_length (s->list) == 4);
|
g_assert (g_list_length (s->list) == 4);
|
||||||
g_assert (g_stack_pop (s) == GPOINTER_TO_INT (4));
|
g_assert (g_stack_pop (s) == GINT_TO_POINTER (4));
|
||||||
g_assert (g_list_length (s->list) == 3);
|
g_assert (g_list_length (s->list) == 3);
|
||||||
g_assert (g_stack_pop (s) == GPOINTER_TO_INT (3));
|
g_assert (g_stack_pop (s) == GINT_TO_POINTER (3));
|
||||||
g_assert (g_list_length (s->list) == 2);
|
g_assert (g_list_length (s->list) == 2);
|
||||||
g_assert (g_stack_pop (s) == GPOINTER_TO_INT (2));
|
g_assert (g_stack_pop (s) == GINT_TO_POINTER (2));
|
||||||
g_assert (g_list_length (s->list) == 1);
|
g_assert (g_list_length (s->list) == 1);
|
||||||
g_assert (g_stack_pop (s) == GPOINTER_TO_INT (1));
|
g_assert (g_stack_pop (s) == GINT_TO_POINTER (1));
|
||||||
g_assert (g_list_length (s->list) == 0);
|
g_assert (g_list_length (s->list) == 0);
|
||||||
g_assert (g_stack_pop (s) == NULL);
|
g_assert (g_stack_pop (s) == NULL);
|
||||||
g_assert (g_list_length (s->list) == 0);
|
g_assert (g_list_length (s->list) == 0);
|
||||||
g_assert (g_stack_pop (s) == NULL);
|
g_assert (g_stack_pop (s) == NULL);
|
||||||
g_assert (g_list_length (s->list) == 0);
|
g_assert (g_list_length (s->list) == 0);
|
||||||
|
|
||||||
|
g_stack_free (s);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user