Simplify GOOPS effective method cache format
[bpt/guile.git] / test-suite / standalone / test-foreign-object-c.c
1 /* test-foreign-object-c.c - exercise C foreign object interface */
2
3 /* Copyright (C) 2014 Free Software Foundation, Inc.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License
7 * as published by the Free Software Foundation; either version 3 of
8 * the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 */
20
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24
25 #include <libguile.h>
26
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30
31 enum
32 {
33 CSTR_SLOT_ADDR,
34 CSTR_SLOT_LEN,
35 CSTR_SLOT_COUNT
36 };
37
38 static void
39 finalizer (SCM obj)
40 {
41 free (scm_foreign_object_ref (obj, CSTR_SLOT_ADDR));
42 }
43
44 static SCM
45 make_cstr_from_static (SCM type, const char *str)
46 {
47 char *ours = strdup (str);
48
49 if (!ours)
50 abort ();
51
52 return scm_make_foreign_object_2 (type, ours, (void *) strlen (ours));
53 }
54
55 static int
56 cstr_equals_static_p (SCM cstr, const char *str)
57 {
58 const char *addr;
59 size_t len;
60
61 addr = scm_foreign_object_ref (cstr, CSTR_SLOT_ADDR);
62 len = scm_foreign_object_unsigned_ref (cstr, CSTR_SLOT_LEN);
63
64 if (strlen (str) != len)
65 return 0;
66
67 return strncmp (addr, str, len) == 0;
68 }
69
70 static void
71 test_scm_foreign_object (void)
72 {
73 SCM type_name, slot_names, type, cstr;
74
75 type_name = scm_from_utf8_symbol ("<cstr>");
76 slot_names = scm_list_2 (scm_from_utf8_symbol ("addr"),
77 scm_from_utf8_symbol ("len"));
78 type = scm_make_foreign_object_type (type_name, slot_names, finalizer);
79
80 cstr = make_cstr_from_static (type, "Hello, world!");
81 scm_assert_foreign_object_type (type, cstr);
82
83 if (!cstr_equals_static_p (cstr, "Hello, world!"))
84 {
85 fprintf (stderr, "fail: test-foreign-object 1\n");
86 exit (EXIT_FAILURE);
87 }
88
89 {
90 int i;
91 for (i = 0; i < 5000; i++)
92 cstr = make_cstr_from_static (type, "Hello, world!");
93 cstr = SCM_BOOL_F;
94 }
95
96 scm_gc ();
97 scm_gc ();
98 scm_gc ();
99
100 /* Allow time for the finalizer thread to run. */
101 scm_usleep (scm_from_uint (50 * 1000));
102 }
103
104 static void
105 tests (void *data, int argc, char **argv)
106 {
107 test_scm_foreign_object ();
108 }
109
110 int
111 main (int argc, char *argv[])
112 {
113 scm_boot_guile (argc, argv, tests, NULL);
114 return 0;
115 }