Merge commit '5b7632331e7551ac202bbaba37c572b96a791c6e'
[bpt/guile.git] / test-suite / standalone / test-foreign-object-c.c
CommitLineData
a7ee7f7c
AW
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
31enum
32 {
33 CSTR_SLOT_ADDR,
34 CSTR_SLOT_LEN,
35 CSTR_SLOT_COUNT
36 };
37
38static void
39finalizer (SCM obj)
40{
4b8ce7c7 41 free (scm_foreign_object_ref (obj, CSTR_SLOT_ADDR));
a7ee7f7c
AW
42}
43
44static SCM
45make_cstr_from_static (SCM type, const char *str)
46{
47 char *ours = strdup (str);
48
49 if (!ours)
50 abort ();
51
4b8ce7c7 52 return scm_make_foreign_object_2 (type, ours, (void *) strlen (ours));
a7ee7f7c
AW
53}
54
55static int
56cstr_equals_static_p (SCM cstr, const char *str)
57{
58 const char *addr;
59 size_t len;
60
4b8ce7c7
AW
61 addr = scm_foreign_object_ref (cstr, CSTR_SLOT_ADDR);
62 len = scm_foreign_object_unsigned_ref (cstr, CSTR_SLOT_LEN);
a7ee7f7c
AW
63
64 if (strlen (str) != len)
65 return 0;
66
67 return strncmp (addr, str, len) == 0;
68}
69
70static void
71test_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
104static void
105tests (void *data, int argc, char **argv)
106{
107 test_scm_foreign_object ();
108}
109
110int
111main (int argc, char *argv[])
112{
113 scm_boot_guile (argc, argv, tests, NULL);
114 return 0;
115}