* * feature.c (scm_set_program_arguments): New function.
[bpt/guile.git] / libguile / fports.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"
20e6290e
JB
45#include "markers.h"
46
47#include "fports.h"
95b88819
GH
48
49#ifdef HAVE_STRING_H
50#include <string.h>
51#endif
0f2d19dd
JB
52#ifdef HAVE_UNISTD_H
53#include <unistd.h>
54#else
0f2d19dd
JB
55scm_sizet fwrite ();
56#endif
0f2d19dd
JB
57
58
59#ifdef __IBMC__
60#include <io.h>
61#include <direct.h>
0f2d19dd
JB
62#else
63#ifndef MSDOS
64#ifndef ultrix
65#ifndef vms
66#ifdef _DCC
67#include <ioctl.h>
68#define setbuf(stream, buf) setvbuf(stream, buf, _IONBF, 0)
69#else
70#ifdef MWC
71#include <sys/io.h>
72#else
73#ifndef THINK_C
74#ifndef ARM_ULIB
75#include <sys/ioctl.h>
76#endif
77#endif
78#endif
79#endif
80#endif
81#endif
82#endif
83#endif
84\f
85
86/* {Ports - file ports}
87 *
88 */
89
90/* should be called with SCM_DEFER_INTS active */
1717856b 91
0f2d19dd
JB
92SCM
93scm_setbuf0 (port)
94 SCM port;
0f2d19dd
JB
95{
96#ifndef NOSETBUF
97#ifndef MSDOS
98#ifdef FIONREAD
99#ifndef ultrix
100 SCM_SYSCALL (setbuf ((FILE *)SCM_STREAM (port), 0););
101#endif
102#endif
103#endif
104#endif
105 return SCM_UNSPECIFIED;
106}
107
108/* Return the flags that characterize a port based on the mode
109 * string used to open a file for that port.
110 *
111 * See PORT FLAGS in scm.h
112 */
1717856b 113
0f2d19dd
JB
114long
115scm_mode_bits (modes)
116 char *modes;
0f2d19dd
JB
117{
118 return (SCM_OPN
119 | (strchr (modes, 'r') || strchr (modes, '+') ? SCM_RDNG : 0)
120 | ( strchr (modes, 'w')
121 || strchr (modes, 'a')
122 || strchr (modes, '+') ? SCM_WRTNG : 0)
123 | (strchr (modes, '0') ? SCM_BUF0 : 0));
124}
125
126
127/* scm_open_file
128 * Return a new port open on a given file.
129 *
130 * The mode string must match the pattern: [rwa+]** which
131 * is interpreted in the usual unix way.
132 *
133 * Return the new port.
134 */
19639113 135SCM_PROC(s_open_file, "open-file", 2, 0, 0, scm_open_file);
1717856b 136
0f2d19dd 137SCM
19639113
GH
138scm_open_file (filename, modes)
139 SCM filename;
140 SCM modes;
0f2d19dd 141{
19639113 142 SCM port;
0f2d19dd 143 FILE *f;
19639113
GH
144 char *file;
145 char *mode;
146
147 SCM_ASSERT (SCM_NIMP (filename) && SCM_ROSTRINGP (filename), filename, SCM_ARG1, s_open_file);
148 SCM_ASSERT (SCM_NIMP (modes) && SCM_ROSTRINGP (modes), modes, SCM_ARG2, s_open_file);
149 if (SCM_SUBSTRP (filename))
150 filename = scm_makfromstr (SCM_ROCHARS (filename), SCM_ROLENGTH (filename), 0);
151 if (SCM_SUBSTRP (modes))
152 modes = scm_makfromstr (SCM_ROCHARS (modes), SCM_ROLENGTH (modes), 0);
153
154 file = SCM_ROCHARS (filename);
155 mode = SCM_ROCHARS (modes);
156
0f2d19dd
JB
157 SCM_NEWCELL (port);
158 SCM_DEFER_INTS;
19639113 159 SCM_SYSCALL (f = fopen (file, mode));
0f2d19dd
JB
160 if (!f)
161 {
f5bf2977 162 scm_syserror_msg (s_open_file, "%s: %S",
19639113
GH
163 scm_listify (scm_makfrom0str (strerror (errno)),
164 filename,
165 SCM_UNDEFINED));
0f2d19dd
JB
166 }
167 else
168 {
169 struct scm_port_table * pt;
19639113 170
0f2d19dd
JB
171 pt = scm_add_to_port_table (port);
172 SCM_SETPTAB_ENTRY (port, pt);
a6c64c3c
MD
173 SCM_SETCAR (port, scm_tc16_fport | scm_mode_bits (mode));
174 if (SCM_BUF0 & SCM_CAR (port))
0f2d19dd 175 scm_setbuf0 (port);
a6c64c3c 176 SCM_SETSTREAM (port, (SCM) f);
96937708 177 SCM_PTAB_ENTRY (port)->file_name = filename;
0f2d19dd 178 }
19639113 179 SCM_ALLOW_INTS;
0f2d19dd
JB
180 return port;
181}
182
183/* Return the mode flags from an open port.
184 * Some modes such as "append" are only used when opening
185 * a file and are not returned here.
186 */
187
188SCM_PROC(s_port_mode, "port-mode", 1, 0, 0, scm_port_mode);
1717856b 189
0f2d19dd
JB
190SCM
191scm_port_mode (port)
192 SCM port;
0f2d19dd
JB
193{
194 char modes[3];
195 modes[0] = '\0';
196 SCM_ASSERT (SCM_NIMP (port) && SCM_OPPORTP (port), port, SCM_ARG1, s_port_mode);
197 if (SCM_CAR (port) & SCM_RDNG) {
198 if (SCM_CAR (port) & SCM_WRTNG)
199 strcpy (modes, "r+");
200 else
201 strcpy (modes, "r");
202 }
203 else if (SCM_CAR (port) & SCM_WRTNG)
204 strcpy (modes, "w");
205 if (SCM_CAR (port) & SCM_BUF0)
206 strcat (modes, "0");
207 return scm_makfromstr (modes, strlen (modes), 0);
208}
209
210
1717856b
JB
211
212static int prinfport SCM_P ((SCM exp, SCM port, scm_print_state *pstate));
213
0f2d19dd 214static int
1717856b 215prinfport (exp, port, pstate)
0f2d19dd
JB
216 SCM exp;
217 SCM port;
1717856b 218 scm_print_state *pstate;
0f2d19dd
JB
219{
220 SCM name;
221 char * c;
222 if (SCM_CLOSEDP (exp))
223 {
224 c = "file";
225 }
226 else
227 {
228 name = SCM_PTAB_ENTRY (exp)->file_name;
229 if (SCM_NIMP (name) && SCM_ROSTRINGP (name))
230 c = SCM_ROCHARS (name);
231 else
232 c = "file";
233 }
19639113 234
0f2d19dd
JB
235 scm_prinport (exp, port, c);
236 return !0;
237}
238
239
1717856b
JB
240
241static int scm_fgetc SCM_P ((FILE * s));
242
0f2d19dd
JB
243static int
244scm_fgetc (s)
245 FILE * s;
0f2d19dd
JB
246{
247 if (feof (s))
248 return EOF;
249 else
250 return fgetc (s);
251}
252
253#ifdef vms
1717856b
JB
254
255static scm_sizet pwrite SCM_P ((char *ptr, scm_sizet size, nitems, FILE *port));
256
0f2d19dd
JB
257static scm_sizet
258pwrite (ptr, size, nitems, port)
259 char *ptr;
260 scm_sizet size, nitems;
261 FILE *port;
0f2d19dd
JB
262{
263 scm_sizet len = size * nitems;
264 scm_sizet i = 0;
265 for (; i < len; i++)
266 putc (ptr[i], port);
267 return len;
268}
269
270#define ffwrite pwrite
271#else
272#define ffwrite fwrite
273#endif
274
275\f
276/* This otherwise pointless code helps some poor
277 * crippled C compilers cope with life.
278 */
1717856b
JB
279
280static int local_fclose SCM_P ((FILE *fp));
281
0f2d19dd
JB
282static int
283local_fclose (fp)
284 FILE * fp;
285{
286 return fclose (fp);
287}
288
1717856b
JB
289static int local_fflush SCM_P ((FILE *fp));
290
0f2d19dd
JB
291static int
292local_fflush (fp)
293 FILE * fp;
294{
295 return fflush (fp);
296}
297
1717856b
JB
298static int local_fputc SCM_P ((int c, FILE *fp));
299
0f2d19dd
JB
300static int
301local_fputc (c, fp)
302 int c;
303 FILE * fp;
304{
305 return fputc (c, fp);
306}
307
1717856b
JB
308static int local_fputs SCM_P ((char *s, FILE *fp));
309
0f2d19dd
JB
310static int
311local_fputs (s, fp)
312 char * s;
313 FILE * fp;
314{
315 return fputs (s, fp);
316}
317
1717856b
JB
318static scm_sizet local_ffwrite SCM_P ((void *ptr, int size, int nitems, FILE *fp));
319
0f2d19dd
JB
320static scm_sizet
321local_ffwrite (ptr, size, nitems, fp)
322 void * ptr;
323 int size;
324 int nitems;
325 FILE * fp;
326{
327 return ffwrite (ptr, size, nitems, fp);
328}
329
330\f
331scm_ptobfuns scm_fptob =
332{
333 scm_mark0,
1717856b 334 (int (*) SCM_P ((SCM))) local_fclose,
0f2d19dd
JB
335 prinfport,
336 0,
1717856b
JB
337 (int (*) SCM_P ((int, SCM))) local_fputc,
338 (int (*) SCM_P ((char *, SCM))) local_fputs,
339 (scm_sizet (*) SCM_P ((char *, scm_sizet, scm_sizet, SCM))) local_ffwrite,
340 (int (*) SCM_P ((SCM))) local_fflush,
341 (int (*) SCM_P ((SCM))) scm_fgetc,
342 (int (*) SCM_P ((SCM))) local_fclose
0f2d19dd
JB
343};
344
345/* {Pipe ports}
346 */
347scm_ptobfuns scm_pipob =
348{
349 scm_mark0,
350 0, /* replaced by pclose in scm_init_ioext() */
351 0, /* replaced by prinpipe in scm_init_ioext() */
352 0,
1717856b
JB
353 (int (*) SCM_P ((int, SCM))) local_fputc,
354 (int (*) SCM_P ((char *, SCM))) local_fputs,
355 (scm_sizet (*) SCM_P ((char *, scm_sizet, scm_sizet, SCM))) local_ffwrite,
356 (int (*) SCM_P ((SCM))) local_fflush,
357 (int (*) SCM_P ((SCM))) scm_fgetc,
0f2d19dd
JB
358 0
359}; /* replaced by pclose in scm_init_ioext() */
360
0f2d19dd
JB
361void
362scm_init_fports ()
0f2d19dd
JB
363{
364#include "fports.x"
365}