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