(close_port, delete_file, check_ports): New.
[bpt/guile.git] / test-suite / standalone / test-unwind.c
CommitLineData
3c8fb18e
MV
1#include <libguile.h>
2#include <stdlib.h>
3#include <stdio.h>
c05d0e8f 4#include <unistd.h>
3c8fb18e
MV
5
6void set_flag (void *data);
7void func1 (void);
8void func2 (void);
9void func3 (void);
10void func4 (void);
11void check_flag1 (const char *msg, void (*func)(void), int val);
12SCM check_flag1_body (void *data);
13SCM return_tag (void *data, SCM tag, SCM args);
14void check_cont (int rewindable);
15SCM check_cont_body (void *data);
c05d0e8f
MV
16void close_port (SCM port);
17void delete_file (void *data);
18void check_ports (void);
3c8fb18e
MV
19
20int flag1, flag2, flag3;
21
22void
23set_flag (void *data)
24{
25 int *f = (int *)data;
26 *f = 1;
27}
28
29/* FUNC1 should leave flag1 zero.
30 */
31
32void
33func1 ()
34{
35 scm_begin_frame (0);
36 flag1 = 0;
37 scm_on_unwind (set_flag, &flag1, 0);
38 scm_end_frame ();
39}
40
41/* FUNC2 should set flag1.
42 */
43
44void
45func2 ()
46{
47 scm_begin_frame (0);
48 flag1 = 0;
c05d0e8f 49 scm_on_unwind (set_flag, &flag1, SCM_F_WIND_EXPLICITLY);
3c8fb18e
MV
50 scm_end_frame ();
51}
52
53/* FUNC3 should set flag1.
54 */
55
56void
57func3 ()
58{
59 scm_begin_frame (0);
60 flag1 = 0;
61 scm_on_unwind (set_flag, &flag1, 0);
62 scm_misc_error ("func3", "gratuitous error", SCM_EOL);
63 scm_end_frame ();
64}
65
66/* FUNC4 should set flag1.
67 */
68
69void
70func4 ()
71{
72 scm_begin_frame (0);
73 flag1 = 0;
c05d0e8f 74 scm_on_unwind (set_flag, &flag1, SCM_F_WIND_EXPLICITLY);
3c8fb18e
MV
75 scm_misc_error ("func4", "gratuitous error", SCM_EOL);
76 scm_end_frame ();
77}
78
79SCM
80check_flag1_body (void *data)
81{
82 void (*f)(void) = (void (*)(void))data;
83 f ();
84 return SCM_UNSPECIFIED;
85}
86
87SCM
88return_tag (void *data, SCM tag, SCM args)
89{
90 return tag;
91}
92
93void
94check_flag1 (const char *tag, void (*func)(void), int val)
95{
96 scm_internal_catch (SCM_BOOL_T,
97 check_flag1_body, func,
98 return_tag, NULL);
99 if (flag1 != val)
100 {
101 printf ("%s failed\n", tag);
102 exit (1);
103 }
104}
105
106SCM
107check_cont_body (void *data)
108{
109 scm_t_frame_flags flags = (data? SCM_F_FRAME_REWINDABLE : 0);
110 int first;
111 SCM val;
112
113 scm_begin_frame (flags);
114
115 val = scm_make_continuation (&first);
116 scm_end_frame ();
117 return val;
118}
119
120void
121check_cont (int rewindable)
122{
123 SCM res;
124
125 res = scm_internal_catch (SCM_BOOL_T,
126 check_cont_body, (void *)rewindable,
127 return_tag, NULL);
128
129 /* RES is now either the created continuation, the value passed to
130 the continuation, or a catch-tag, such as 'misc-error.
131 */
132
133 if (SCM_NFALSEP (scm_procedure_p (res)))
134 {
135 /* a continuation, invoke it */
136 scm_call_1 (res, SCM_BOOL_F);
137 }
138 else if (SCM_FALSEP (res))
139 {
140 /* the result of invoking the continuation, frame must be
141 rewindable */
142 if (rewindable)
143 return;
144 printf ("continuation not blocked\n");
145 exit (1);
146 }
147 else
148 {
149 /* the catch tag, frame must not have been rewindable. */
150 if (!rewindable)
151 return;
152 printf ("continuation didn't work\n");
153 exit (1);
154 }
155}
c05d0e8f
MV
156
157void
158close_port (SCM port)
159{
160 scm_close_port (port);
161}
162
163void
164delete_file (void *data)
165{
166 unlink ((char *)data);
167}
168
169void
170check_ports ()
171{
172 char filename[] = "/tmp/check-ports.XXXXXX";
173
174 if (mktemp (filename) == NULL)
175 exit (1);
176
177 scm_begin_frame (0);
178 {
179 SCM port = scm_open_file (scm_str2string (filename),
180 scm_str2string ("w"));
181 scm_on_unwind_with_scm (close_port, port, SCM_F_WIND_EXPLICITLY);
182
183 scm_with_current_output_port (port);
184 scm_write (scm_version (), SCM_UNDEFINED);
185 }
186 scm_end_frame ();
187
188 scm_begin_frame (0);
189 {
190 SCM port = scm_open_file (scm_str2string (filename),
191 scm_str2string ("r"));
192 SCM res;
193 scm_on_unwind_with_scm (close_port, port, SCM_F_WIND_EXPLICITLY);
194 scm_on_unwind (delete_file, filename, SCM_F_WIND_EXPLICITLY);
195
196 scm_with_current_input_port (port);
197 res = scm_read (SCM_UNDEFINED);
198 if (SCM_FALSEP (scm_equal_p (res, scm_version ())))
199 {
200 printf ("ports didn't work\n");
201 exit (1);
202 }
203 }
204 scm_end_frame ();
205}
3c8fb18e
MV
206
207static void
208inner_main (void *data, int argc, char **argv)
209{
210 check_flag1 ("func1", func1, 0);
211 check_flag1 ("func2", func2, 1);
212 check_flag1 ("func3", func3, 1);
213 check_flag1 ("func4", func4, 1);
214
215 check_cont (0);
216 check_cont (1);
217
c05d0e8f
MV
218 check_ports ();
219
3c8fb18e
MV
220 exit (0);
221}
222
223int
224main (int argc, char **argv)
225{
226 scm_boot_guile (argc, argv, inner_main, 0);
227 return 0;
228}