Merge branch 'stable-2.0'
[bpt/guile.git] / test-suite / standalone / test-smob-mark.c
1 /* Copyright (C) 2013 Free Software Foundation, Inc.
2 *
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public License
5 * as published by the Free Software Foundation; either version 3 of
6 * the License, or (at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 * 02110-1301 USA
17 */
18
19 #if HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include <assert.h>
24 #include <libguile.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27
28 #define SMOBS_COUNT (10000)
29
30 struct x_tag
31 {
32 SCM scm_value;
33 int c_value;
34 };
35
36 typedef struct x_tag x_t;
37
38 unsigned int mark_call_count = 0;
39
40 static scm_t_bits x_tag;
41 static SCM make_x (void);
42 static SCM mark_x (SCM x);
43 static int print_x (SCM x, SCM port, scm_print_state * pstate);
44 static size_t free_x (SCM x);
45 static void init_smob_type (void);
46 static void test_scm_smob_mark (void);
47
48 static SCM
49 make_x ()
50 {
51 static int i = 0;
52 SCM s_x;
53 x_t *c_x;
54
55 i++;
56 c_x = (x_t *) scm_gc_malloc (sizeof (x_t), "x");
57 c_x->scm_value = scm_from_int (i);
58 c_x->c_value = i;
59 SCM_NEWSMOB (s_x, x_tag, c_x);
60 return s_x;
61 }
62
63 static SCM
64 mark_x (SCM x)
65 {
66 x_t *c_x;
67 c_x = (x_t *) SCM_SMOB_DATA (x);
68 scm_gc_mark (c_x->scm_value);
69 mark_call_count++;
70 return SCM_BOOL_F;
71 }
72
73 static size_t
74 free_x (SCM x)
75 {
76 x_t *c_x;
77 c_x = (x_t *) SCM_SMOB_DATA (x);
78 scm_gc_free (c_x, sizeof (x_t), "x");
79 c_x = NULL;
80 return 0;
81 }
82
83 static int
84 print_x (SCM x, SCM port, scm_print_state * pstate SCM_UNUSED)
85 {
86 x_t *c_x = (x_t *) SCM_SMOB_DATA (x);
87 scm_puts ("#<x ", port);
88 if (c_x == (x_t *) NULL)
89 scm_puts ("(freed)", port);
90 else
91 scm_write (c_x->scm_value, port);
92 scm_puts (">", port);
93
94 return 1;
95 }
96
97 static void
98 test_scm_smob_mark ()
99 {
100 int i;
101 mark_call_count = 0;
102 for (i = 0; i < SMOBS_COUNT; i++)
103 make_x ();
104 scm_gc ();
105 if (mark_call_count < SMOBS_COUNT)
106 {
107 fprintf (stderr, "FAIL: SMOB mark function called for each SMOB\n");
108 exit (EXIT_FAILURE);
109 }
110 }
111
112 static void
113 init_smob_type ()
114 {
115 x_tag = scm_make_smob_type ("x", sizeof (x_t));
116 scm_set_smob_free (x_tag, free_x);
117 scm_set_smob_print (x_tag, print_x);
118 scm_set_smob_mark (x_tag, mark_x);
119 }
120
121 static void
122 tests (void *data, int argc, char **argv)
123 {
124 init_smob_type ();
125 test_scm_smob_mark ();
126 }
127
128 int
129 main (int argc, char *argv[])
130 {
131 scm_boot_guile (argc, argv, tests, NULL);
132 return 0;
133 }