.
[bpt/guile.git] / libguile / strports.c
CommitLineData
0f2d19dd
JB
1/* Copyright (C) 1995,1996 Free Software Foundation, Inc.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
15 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
16 *
17 * As a special exception, the Free Software Foundation gives permission
18 * for additional uses of the text contained in its release of GUILE.
19 *
20 * The exception is that, if you link the GUILE library with other files
21 * to produce an executable, this does not by itself cause the
22 * resulting executable to be covered by the GNU General Public License.
23 * Your use of that executable is in no way restricted on account of
24 * linking the GUILE library code into it.
25 *
26 * This exception does not however invalidate any other reasons why
27 * the executable file might be covered by the GNU General Public License.
28 *
29 * This exception applies only to the code released by the
30 * Free Software Foundation under the name GUILE. If you copy
31 * code from other Free Software Foundation releases into a copy of
32 * GUILE, as the General Public License permits, the exception does
33 * not apply to the code that you add in this way. To avoid misleading
34 * anyone as to the status of such modified files, you must delete
35 * this exception notice from them.
36 *
37 * If you write modifications of your own for GUILE, it is your choice
38 * whether to permit this exception to apply to your modifications.
39 * If you do not wish that, delete this exception notice.
40 */
41\f
42
43#include <stdio.h>
44#include "_scm.h"
45
46\f
47
48/* {Ports - string ports}
49 *
50 */
51
52#ifdef __STDC__
53static int
54prinstpt (SCM exp, SCM port, int writing)
55#else
56static int
57prinstpt (exp, port, writing)
58 SCM exp;
59 SCM port;
60 int writing;
61#endif
62{
63 scm_prinport (exp, port, "string");
64 return !0;
65}
66
67#ifdef __STDC__
68static int
69stputc (int c, SCM p)
70#else
71static int
72stputc (c, p)
73 int c;
74 SCM p;
75#endif
76{
77 scm_sizet ind = SCM_INUM (SCM_CAR (p));
78 SCM_DEFER_INTS;
79 if (ind >= SCM_LENGTH (SCM_CDR (p)))
80 scm_vector_set_length_x (SCM_CDR (p), SCM_MAKINUM (ind + (ind >> 1)));
81 SCM_ALLOW_INTS;
82 SCM_CHARS (SCM_CDR (p))[ind] = c;
83 SCM_CAR (p) = SCM_MAKINUM (ind + 1);
84 return c;
85}
86
87#ifdef __STDC__
88static scm_sizet
89stwrite (char *str, scm_sizet siz, scm_sizet num, SCM p)
90#else
91static scm_sizet
92stwrite (str, siz, num, p)
93 char *str;
94 scm_sizet siz;
95 scm_sizet num;
96 SCM p;
97#endif
98{
99 scm_sizet ind = SCM_INUM (SCM_CAR (p));
100 scm_sizet len = siz * num;
101 char *dst;
102 SCM_DEFER_INTS;
103 if (ind + len >= SCM_LENGTH (SCM_CDR (p)))
104 scm_vector_set_length_x (SCM_CDR (p), SCM_MAKINUM (ind + len + ((ind + len) >> 1)));
105 SCM_ALLOW_INTS;
106 dst = &(SCM_CHARS (SCM_CDR (p))[ind]);
107 while (len--)
108 dst[len] = str[len];
109 SCM_CAR (p) = SCM_MAKINUM (ind + siz * num);
110 return num;
111}
112
113#ifdef __STDC__
114static int
115stputs (char *s, SCM p)
116#else
117static int
118stputs (s, p)
119 char *s;
120 SCM p;
121#endif
122{
123 stwrite (s, 1, strlen (s), p);
124 return 0;
125}
126
127#ifdef __STDC__
128static int
129stgetc (SCM p)
130#else
131static int
132stgetc (p)
133 SCM p;
134#endif
135{
136 scm_sizet ind = SCM_INUM (SCM_CAR (p));
137 if (ind >= SCM_ROLENGTH (SCM_CDR (p)))
138 return EOF;
139 SCM_CAR (p) = SCM_MAKINUM (ind + 1);
140 return SCM_ROUCHARS (SCM_CDR (p))[ind];
141}
142
143#ifdef __STDC__
144SCM
145scm_mkstrport (SCM pos, SCM str, long modes, char * caller)
146#else
147SCM
148scm_mkstrport (pos, str, modes, caller)
149 SCM pos;
150 SCM str;
151 long modes;
152 char * caller;
153#endif
154{
155 SCM z;
156 SCM stream;
157 struct scm_port_table * pt;
158
159 SCM_ASSERT(SCM_INUMP(pos) && SCM_INUM(pos) >= 0, pos, SCM_ARG1, caller);
160 SCM_ASSERT(SCM_NIMP(str) && SCM_ROSTRINGP(str), str, SCM_ARG1, caller);
161 stream = scm_cons(pos, str);
162 SCM_NEWCELL (z);
163 SCM_DEFER_INTS;
164 pt = scm_add_to_port_table (z);
165 SCM_CAR (z) = scm_tc16_strport | modes;
166 SCM_SETPTAB_ENTRY (z, pt);
167 SCM_SETSTREAM (z, stream);
168 SCM_ALLOW_INTS;
169 return z;
170}
171
172SCM_PROC(s_call_with_output_string, "call-with-output-string", 1, 0, 0, scm_call_with_output_string);
173#ifdef __STDC__
174SCM
175scm_call_with_output_string (SCM proc)
176#else
177SCM
178scm_call_with_output_string (proc)
179 SCM proc;
180#endif
181{
182 SCM p;
183 p = scm_mkstrport(SCM_INUM0, scm_make_string(SCM_MAKINUM(30), SCM_UNDEFINED),
184 SCM_OPN | SCM_WRTNG,
185 s_call_with_output_string);
186 scm_apply (proc, p, scm_listofnull);
187 {
188 SCM answer;
189 SCM_DEFER_INTS;
190 answer = scm_makfromstr (SCM_CHARS (SCM_CDR (SCM_STREAM (p))),
191 SCM_INUM (SCM_CAR (SCM_STREAM (p))),
192 0);
193 SCM_ALLOW_INTS;
194 return answer;
195 }
196}
197
198
199
200/* Return a Scheme string obtained by printing a given object.
201 */
202
203#ifdef __STDC__
204SCM
205scm_strprint_obj (SCM obj)
206#else
207SCM
208scm_strprint_obj (obj)
209 SCM obj;
210#endif
211{
212 SCM str;
213 SCM port;
214
215 str = scm_makstr (64, 0);
216 port = scm_mkstrport (SCM_MAKINUM (0), str, SCM_OPN | SCM_WRTNG, "scm_strprint_obj");
217 scm_iprin1 (obj, port, 1);
218 {
219 SCM answer;
220 SCM_DEFER_INTS;
221 answer = scm_makfromstr (SCM_CHARS (SCM_CDR (SCM_STREAM (port))),
222 SCM_INUM (SCM_CAR (SCM_STREAM (port))),
223 0);
224 SCM_ALLOW_INTS;
225 return answer;
226 }
227}
228
229
230
231
232SCM_PROC(s_call_with_input_string, "call-with-input-string", 2, 0, 0, scm_call_with_input_string);
233#ifdef __STDC__
234SCM
235scm_call_with_input_string (SCM str, SCM proc)
236#else
237SCM
238scm_call_with_input_string (str, proc)
239 SCM str;
240 SCM proc;
241#endif
242{
243 SCM p = scm_mkstrport(SCM_INUM0, str, SCM_OPN | SCM_RDNG, s_call_with_input_string);
244 return scm_apply (proc, p, scm_listofnull);
245}
246
247#ifdef __STDC__
248static int
249noop0 (FILE *stream)
250#else
251static int
252noop0 (stream)
253 FILE *stream;
254#endif
255{
256 return 0;
257}
258
259
260scm_ptobfuns scm_stptob =
261{
262 scm_markstream,
263 noop0,
264 prinstpt,
265 0,
266 stputc,
267 stputs,
268 stwrite,
269 noop0,
270 stgetc,
271 0
272};
273
274
275#ifdef __STDC__
276void
277scm_init_strports (void)
278#else
279void
280scm_init_strports ()
281#endif
282{
283#include "strports.x"
284}
285