* COPYING, boot-9.scm, debug.scm, emacs.scm, expect.scm, gtcl.scm,
[bpt/guile.git] / libguile / ports.c
CommitLineData
1e598865 1/* Copyright (C) 1995,1996,1997 Free Software Foundation, Inc.
0f2d19dd
JB
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#include <stdio.h>
43#include "_scm.h"
20e6290e
JB
44#include "genio.h"
45#include "chars.h"
0f2d19dd 46
20e6290e 47#include "markers.h"
5d09ff4e 48#include "filesys.h"
20e6290e
JB
49#include "fports.h"
50#include "strports.h"
51#include "vports.h"
52
53#include "ports.h"
0f2d19dd
JB
54
55#ifdef HAVE_MALLOC_H
95b88819 56#include <malloc.h>
0f2d19dd
JB
57#endif
58
59#ifdef HAVE_UNISTD_H
60#include <unistd.h>
61#endif
62
95b88819
GH
63#ifdef HAVE_SYS_IOCTL_H
64#include <sys/ioctl.h>
65#endif
0f2d19dd
JB
66\f
67
68
69/* scm_ptobs scm_numptob
70 * implement a dynamicly resized array of ptob records.
71 * Indexes into this table are used when generating type
72 * tags for smobjects (if you know a tag you can get an index and conversely).
73 */
74scm_ptobfuns *scm_ptobs;
75scm_sizet scm_numptob;
76
1cc91f1b 77
0f2d19dd
JB
78SCM
79scm_markstream (ptr)
80 SCM ptr;
0f2d19dd
JB
81{
82 int openp;
83 if (SCM_GC8MARKP (ptr))
84 return SCM_BOOL_F;
85 openp = SCM_CAR (ptr) & SCM_OPN;
86 SCM_SETGC8MARK (ptr);
87 if (openp)
88 return SCM_STREAM (ptr);
89 else
90 return SCM_BOOL_F;
91}
92
93
1cc91f1b 94
0f2d19dd
JB
95long
96scm_newptob (ptob)
97 scm_ptobfuns *ptob;
0f2d19dd
JB
98{
99 char *tmp;
100 if (255 <= scm_numptob)
101 goto ptoberr;
102 SCM_DEFER_INTS;
103 SCM_SYSCALL (tmp = (char *) realloc ((char *) scm_ptobs, (1 + scm_numptob) * sizeof (scm_ptobfuns)));
104 if (tmp)
105 {
106 scm_ptobs = (scm_ptobfuns *) tmp;
107 scm_ptobs[scm_numptob].mark = ptob->mark;
108 scm_ptobs[scm_numptob].free = ptob->free;
109 scm_ptobs[scm_numptob].print = ptob->print;
110 scm_ptobs[scm_numptob].equalp = ptob->equalp;
111 scm_ptobs[scm_numptob].fputc = ptob->fputc;
112 scm_ptobs[scm_numptob].fputs = ptob->fputs;
113 scm_ptobs[scm_numptob].fwrite = ptob->fwrite;
114 scm_ptobs[scm_numptob].fflush = ptob->fflush;
115 scm_ptobs[scm_numptob].fgetc = ptob->fgetc;
116 scm_ptobs[scm_numptob].fclose = ptob->fclose;
117 scm_numptob++;
118 }
119 SCM_ALLOW_INTS;
120 if (!tmp)
121 ptoberr:scm_wta (SCM_MAKINUM ((long) scm_numptob), (char *) SCM_NALLOC, "newptob");
122 return scm_tc7_port + (scm_numptob - 1) * 256;
123}
124
125\f
126/* internal SCM call */
1cc91f1b 127
0f2d19dd
JB
128void
129scm_fflush (port)
130 SCM port;
0f2d19dd
JB
131{
132 scm_sizet i = SCM_PTOBNUM (port);
133 (scm_ptobs[i].fflush) (SCM_STREAM (port));
134}
135
136\f
137
44493941 138SCM_PROC(s_char_ready_p, "char-ready?", 0, 1, 0, scm_char_ready_p);
1cc91f1b 139
0f2d19dd
JB
140SCM
141scm_char_ready_p (port)
142 SCM port;
0f2d19dd
JB
143{
144 if (SCM_UNBNDP (port))
145 port = scm_cur_inp;
146 else
147 SCM_ASSERT (SCM_NIMP (port) && SCM_OPINPORTP (port), port, SCM_ARG1, s_char_ready_p);
148 if (SCM_CRDYP (port) || !SCM_FPORTP (port))
149 return SCM_BOOL_T;
5d09ff4e
MD
150 return (scm_input_waiting_p ((FILE *) SCM_STREAM (port), s_char_ready_p)
151 ? SCM_BOOL_T
152 : SCM_BOOL_F);
0f2d19dd 153}
0f2d19dd
JB
154
155
156\f
157
158
159/* {Standard Ports}
160 */
161SCM_PROC(s_current_input_port, "current-input-port", 0, 0, 0, scm_current_input_port);
1cc91f1b 162
0f2d19dd
JB
163SCM
164scm_current_input_port ()
0f2d19dd
JB
165{
166 return scm_cur_inp;
167}
168
169SCM_PROC(s_current_output_port, "current-output-port", 0, 0, 0, scm_current_output_port);
1cc91f1b 170
0f2d19dd
JB
171SCM
172scm_current_output_port ()
0f2d19dd
JB
173{
174 return scm_cur_outp;
175}
176
177SCM_PROC(s_current_error_port, "current-error-port", 0, 0, 0, scm_current_error_port);
1cc91f1b 178
0f2d19dd
JB
179SCM
180scm_current_error_port ()
0f2d19dd
JB
181{
182 return scm_cur_errp;
183}
184
185SCM_PROC(s_set_current_input_port, "set-current-input-port", 1, 0, 0, scm_set_current_input_port);
1cc91f1b 186
0f2d19dd
JB
187SCM
188scm_set_current_input_port (port)
189 SCM port;
0f2d19dd
JB
190{
191 SCM oinp = scm_cur_inp;
192 SCM_ASSERT (SCM_NIMP (port) && SCM_OPINPORTP (port), port, SCM_ARG1, s_set_current_input_port);
193 scm_cur_inp = port;
194 return oinp;
195}
196
197
198SCM_PROC(s_set_current_output_port, "set-current-output-port", 1, 0, 0, scm_set_current_output_port);
1cc91f1b 199
0f2d19dd
JB
200SCM
201scm_set_current_output_port (port)
202 SCM port;
0f2d19dd
JB
203{
204 SCM ooutp = scm_cur_outp;
205 SCM_ASSERT (SCM_NIMP (port) && SCM_OPOUTPORTP (port), port, SCM_ARG1, s_set_current_output_port);
206 scm_cur_outp = port;
207 return ooutp;
208}
209
210
211SCM_PROC(s_set_current_error_port, "set-current-error-port", 1, 0, 0, scm_set_current_error_port);
1cc91f1b 212
0f2d19dd
JB
213SCM
214scm_set_current_error_port (port)
215 SCM port;
0f2d19dd
JB
216{
217 SCM oerrp = scm_cur_errp;
218 SCM_ASSERT (SCM_NIMP (port) && SCM_OPOUTPORTP (port), port, SCM_ARG1, s_set_current_error_port);
219 scm_cur_errp = port;
220 return oerrp;
221}
222
223\f
224
225/* {Ports - in general}
226 *
227 */
228
229/* Array of open ports, required for reliable MOVE->FDES etc. */
230struct scm_port_table **scm_port_table;
231
232int scm_port_table_size = 0; /* Number of ports in scm_port_table. */
233int scm_port_table_room = 20; /* Size of the array. */
234
235/* Add a port to the table. Call with SCM_DEFER_INTS active. */
1cc91f1b 236
0f2d19dd
JB
237struct scm_port_table *
238scm_add_to_port_table (port)
239 SCM port;
0f2d19dd
JB
240{
241 if (scm_port_table_size == scm_port_table_room)
242 {
243 scm_port_table = ((struct scm_port_table **)
244 realloc ((char *) scm_port_table,
245 (long) (sizeof (struct scm_port_table)
246 * scm_port_table_room * 2)));
247 /* !!! error checking */
248 scm_port_table_room *= 2;
249 }
250 scm_port_table[scm_port_table_size] = ((struct scm_port_table *)
251 scm_must_malloc (sizeof (struct scm_port_table),
252 "system port table"));
253 scm_port_table[scm_port_table_size]->port = port;
254 scm_port_table[scm_port_table_size]->revealed = 0;
255 scm_port_table[scm_port_table_size]->stream = 0;
ebf7394e 256 scm_port_table[scm_port_table_size]->file_name = SCM_BOOL_F;
0f2d19dd
JB
257 scm_port_table[scm_port_table_size]->line_number = 1;
258 scm_port_table[scm_port_table_size]->column_number = 0;
259 scm_port_table[scm_port_table_size]->representation = scm_regular_port;
260 return scm_port_table[scm_port_table_size++];
261}
262
263/* Remove a port from the table. Call with SCM_DEFER_INTS active. */
1cc91f1b 264
0f2d19dd
JB
265void
266scm_remove_from_port_table (port)
267 SCM port;
0f2d19dd
JB
268{
269 int i = 0;
270 while (scm_port_table[i]->port != port)
271 {
272 i++;
273 /* Error if not found: too violent? May occur in GC. */
274 if (i >= scm_port_table_size)
275 scm_wta (port, "Port not in table", "scm_remove_from_port_table");
276 }
277 scm_must_free ((char *)scm_port_table[i]);
278 scm_mallocated -= sizeof (*scm_port_table[i]);
279 scm_port_table[i] = scm_port_table[scm_port_table_size - 1];
280 SCM_SETPTAB_ENTRY (port, 0);
281 scm_port_table_size--;
282}
283
fea6b4ea 284#ifdef GUILE_DEBUG
0f2d19dd
JB
285/* Undocumented functions for debugging. */
286/* Return the number of ports in the table. */
1cc91f1b 287
1146b6cd 288SCM_PROC(s_pt_size, "pt-size", 0, 0, 0, scm_pt_size);
0f2d19dd
JB
289SCM
290scm_pt_size ()
0f2d19dd
JB
291{
292 return SCM_MAKINUM (scm_port_table_size);
293}
294
295/* Return the ith member of the port table. */
1146b6cd 296SCM_PROC(s_pt_member, "pt-member", 1, 0, 0, scm_pt_member);
0f2d19dd
JB
297SCM
298scm_pt_member (member)
299 SCM member;
0f2d19dd
JB
300{
301 int i;
302 SCM_ASSERT (SCM_INUMP (member), member, SCM_ARG1, s_pt_member);
303 i = SCM_INUM (member);
304 if (i < 0 || i >= scm_port_table_size)
305 return SCM_BOOL_F;
306 else
307 return scm_port_table[i]->port;
308}
309#endif
310
311
8b13c6b3
GH
312/* Find a port in the table and return its revealed count.
313 Also used by the garbage collector.
0f2d19dd 314 */
1cc91f1b 315
0f2d19dd
JB
316int
317scm_revealed_count (port)
318 SCM port;
0f2d19dd
JB
319{
320 return SCM_REVEALED(port);
321}
322
323
324
325/* Return the revealed count for a port. */
326
327SCM_PROC(s_port_revealed, "port-revealed", 1, 0, 0, scm_port_revealed);
1cc91f1b 328
0f2d19dd
JB
329SCM
330scm_port_revealed (port)
331 SCM port;
0f2d19dd 332{
0f2d19dd 333 SCM_ASSERT (SCM_NIMP (port) && SCM_PORTP (port), port, SCM_ARG1, s_port_revealed);
8b13c6b3 334 return SCM_MAKINUM (scm_revealed_count (port));
0f2d19dd
JB
335}
336
337/* Set the revealed count for a port. */
338SCM_PROC(s_set_port_revealed_x, "set-port-revealed!", 2, 0, 0, scm_set_port_revealed_x);
1cc91f1b 339
0f2d19dd
JB
340SCM
341scm_set_port_revealed_x (port, rcount)
342 SCM port;
343 SCM rcount;
0f2d19dd
JB
344{
345 SCM_ASSERT (SCM_NIMP (port) && SCM_PORTP (port), port, SCM_ARG1, s_set_port_revealed_x);
346 SCM_ASSERT (SCM_INUMP (rcount), rcount, SCM_ARG2, s_set_port_revealed_x);
347 SCM_DEFER_INTS;
348 SCM_REVEALED (port) = SCM_INUM (rcount);
349 SCM_ALLOW_INTS;
8b13c6b3 350 return SCM_UNSPECIFIED;
0f2d19dd
JB
351}
352
353/* scm_close_port
354 * Call the close operation on a port object.
355 */
356SCM_PROC(s_close_port, "close-port", 1, 0, 0, scm_close_port);
1cc91f1b 357
0f2d19dd
JB
358SCM
359scm_close_port (port)
360 SCM port;
0f2d19dd
JB
361{
362 scm_sizet i;
363 SCM_ASSERT (SCM_NIMP (port) && SCM_PORTP (port), port, SCM_ARG1, s_close_port);
364 if (SCM_CLOSEDP (port))
365 return SCM_UNSPECIFIED;
366 i = SCM_PTOBNUM (port);
367 SCM_DEFER_INTS;
368 if (scm_ptobs[i].fclose)
369 SCM_SYSCALL ((scm_ptobs[i].fclose) (SCM_STREAM (port)));
370 scm_remove_from_port_table (port);
898a256f 371 SCM_SETAND_CAR (port, ~SCM_OPN);
0f2d19dd
JB
372 SCM_ALLOW_INTS;
373 return SCM_UNSPECIFIED;
374}
375
376SCM_PROC(s_close_all_ports_except, "close-all-ports-except", 0, 0, 1, scm_close_all_ports_except);
1cc91f1b 377
0f2d19dd
JB
378SCM
379scm_close_all_ports_except (ports)
380 SCM ports;
0f2d19dd
JB
381{
382 int i = 0;
383 SCM_ASSERT (SCM_NIMP (ports) && SCM_CONSP (ports), ports, SCM_ARG1, s_close_all_ports_except);
384 SCM_DEFER_INTS;
385 while (i < scm_port_table_size)
386 {
387 SCM thisport = scm_port_table[i]->port;
388 int found = 0;
389 SCM ports_ptr = ports;
390
391 while (SCM_NNULLP (ports_ptr))
392 {
393 SCM port = SCM_CAR (ports_ptr);
394 if (i == 0)
395 SCM_ASSERT (SCM_NIMP (port) && SCM_OPPORTP (port), port, SCM_ARG1, s_close_all_ports_except);
396 if (port == thisport)
397 found = 1;
398 ports_ptr = SCM_CDR (ports_ptr);
399 }
400 if (found)
401 i++;
402 else
403 /* i is not to be incremented here. */
404 scm_close_port (thisport);
405 }
406 SCM_ALLOW_INTS;
407 return SCM_UNSPECIFIED;
408}
409
410SCM_PROC(s_input_port_p, "input-port?", 1, 0, 0, scm_input_port_p);
1cc91f1b 411
0f2d19dd
JB
412SCM
413scm_input_port_p (x)
414 SCM x;
0f2d19dd
JB
415{
416 if (SCM_IMP (x))
417 return SCM_BOOL_F;
418 return SCM_INPORTP (x) ? SCM_BOOL_T : SCM_BOOL_F;
419}
420
421SCM_PROC(s_output_port_p, "output-port?", 1, 0, 0, scm_output_port_p);
1cc91f1b 422
0f2d19dd
JB
423SCM
424scm_output_port_p (x)
425 SCM x;
0f2d19dd
JB
426{
427 if (SCM_IMP (x))
428 return SCM_BOOL_F;
429 return SCM_OUTPORTP (x) ? SCM_BOOL_T : SCM_BOOL_F;
430}
431
432
433SCM_PROC(s_eof_object_p, "eof-object?", 1, 0, 0, scm_eof_object_p);
1cc91f1b 434
0f2d19dd
JB
435SCM
436scm_eof_object_p (x)
437 SCM x;
0f2d19dd
JB
438{
439 return (SCM_EOF_VAL == x) ? SCM_BOOL_T : SCM_BOOL_F;
440}
441
442SCM_PROC(s_force_output, "force-output", 0, 1, 0, scm_force_output);
1cc91f1b 443
0f2d19dd
JB
444SCM
445scm_force_output (port)
446 SCM port;
0f2d19dd
JB
447{
448 if (SCM_UNBNDP (port))
449 port = scm_cur_outp;
450 else
451 SCM_ASSERT (SCM_NIMP (port) && SCM_OPOUTPORTP (port), port, SCM_ARG1, s_force_output);
452 {
453 scm_sizet i = SCM_PTOBNUM (port);
454 SCM_SYSCALL ((scm_ptobs[i].fflush) (SCM_STREAM (port)));
455 return SCM_UNSPECIFIED;
456 }
457}
458
459
460SCM_PROC(s_read_char, "read-char", 0, 1, 0, scm_read_char);
1cc91f1b 461
0f2d19dd
JB
462SCM
463scm_read_char (port)
464 SCM port;
0f2d19dd
JB
465{
466 int c;
467 if (SCM_UNBNDP (port))
334341aa 468 port = scm_cur_inp;
0f2d19dd
JB
469 else
470 SCM_ASSERT (SCM_NIMP (port) && SCM_OPINPORTP (port), port, SCM_ARG1, s_read_char);
471 c = scm_gen_getc (port);
472 if (EOF == c)
473 return SCM_EOF_VAL;
474 return SCM_MAKICHR (c);
475}
476
477
478SCM_PROC(s_peek_char, "peek-char", 0, 1, 0, scm_peek_char);
1cc91f1b 479
0f2d19dd
JB
480SCM
481scm_peek_char (port)
482 SCM port;
0f2d19dd
JB
483{
484 int c;
485 if (SCM_UNBNDP (port))
486 port = scm_cur_inp;
487 else
488 SCM_ASSERT (SCM_NIMP (port) && SCM_OPINPORTP (port), port, SCM_ARG1, s_peek_char);
489 c = scm_gen_getc (port);
490 if (EOF == c)
491 return SCM_EOF_VAL;
492 scm_gen_ungetc (c, port);
493 return SCM_MAKICHR (c);
494}
495
496SCM_PROC (s_unread_char, "unread-char", 2, 0, 0, scm_unread_char);
1cc91f1b 497
0f2d19dd
JB
498SCM
499scm_unread_char (cobj, port)
500 SCM cobj;
501 SCM port;
0f2d19dd
JB
502{
503 int c;
504
505 SCM_ASSERT (SCM_ICHRP (cobj), cobj, SCM_ARG1, s_unread_char);
506
507 if (SCM_UNBNDP (port))
508 port = scm_cur_inp;
509 else
510 SCM_ASSERT (SCM_NIMP (port) && SCM_OPINPORTP (port), port, SCM_ARG2, s_unread_char);
511
512
513 c = SCM_ICHR (cobj);
514
515 scm_gen_ungetc (c, port);
516 return cobj;
517}
518
519
520
d14af9f2 521SCM_PROC (s_port_line, "port-line", 0, 1, 0, scm_port_line);
1cc91f1b 522
0f2d19dd 523SCM
d14af9f2 524scm_port_line (port)
0f2d19dd 525 SCM port;
0f2d19dd
JB
526{
527 SCM p;
528 p = ((port == SCM_UNDEFINED)
529 ? scm_cur_inp
530 : port);
531 if (!(SCM_NIMP (p) && SCM_PORTP (p)))
532 return SCM_BOOL_F;
533 else
534 return SCM_MAKINUM (SCM_LINUM (p));
535}
536
d043d8c2
MD
537SCM_PROC (s_set_port_line_x, "set-port-line!", 1, 1, 0, scm_set_port_line_x);
538
539SCM
540scm_set_port_line_x (port, line)
541 SCM port;
542 SCM line;
543{
544 if (line == SCM_UNDEFINED)
545 {
546 line = port;
547 port = scm_cur_inp;
548 }
549 else
550 SCM_ASSERT (SCM_NIMP (port) && SCM_PORTP (port) && SCM_OPENP (port),
551 port,
552 SCM_ARG1,
553 s_set_port_line_x);
554 return SCM_PTAB_ENTRY (port)->line_number = SCM_INUM (line);
555}
556
d14af9f2 557SCM_PROC (s_port_column, "port-column", 0, 1, 0, scm_port_column);
1cc91f1b 558
0f2d19dd 559SCM
d14af9f2 560scm_port_column (port)
0f2d19dd 561 SCM port;
0f2d19dd
JB
562{
563 SCM p;
564 p = ((port == SCM_UNDEFINED)
565 ? scm_cur_inp
566 : port);
567 if (!(SCM_NIMP (p) && SCM_PORTP (p)))
568 return SCM_BOOL_F;
569 else
570 return SCM_MAKINUM (SCM_COL (p));
571}
572
d043d8c2
MD
573SCM_PROC (s_set_port_column_x, "set-port-column!", 1, 1, 0, scm_set_port_column_x);
574
575SCM
576scm_set_port_column_x (port, column)
577 SCM port;
578 SCM column;
579{
580 if (column == SCM_UNDEFINED)
581 {
582 column = port;
583 port = scm_cur_inp;
584 }
585 else
586 SCM_ASSERT (SCM_NIMP (port) && SCM_PORTP (port) && SCM_OPENP (port),
587 port,
588 SCM_ARG1,
589 s_set_port_column_x);
590 return SCM_PTAB_ENTRY (port)->column_number = SCM_INUM (column);
591}
592
d14af9f2 593SCM_PROC (s_port_filename, "port-filename", 0, 1, 0, scm_port_filename);
1cc91f1b 594
0f2d19dd 595SCM
d14af9f2 596scm_port_filename (port)
0f2d19dd 597 SCM port;
0f2d19dd
JB
598{
599 SCM p;
600 p = ((port == SCM_UNDEFINED)
601 ? scm_cur_inp
602 : port);
603 if (!(SCM_NIMP (p) && SCM_PORTP (p)))
604 return SCM_BOOL_F;
605 else
606 return SCM_PTAB_ENTRY (p)->file_name;
607}
608
d14af9f2 609SCM_PROC (s_set_port_filename_x, "set-port-filename!", 1, 1, 0, scm_set_port_filename_x);
1cc91f1b 610
d14af9f2
MD
611SCM
612scm_set_port_filename_x (port, filename)
613 SCM port;
614 SCM filename;
d14af9f2
MD
615{
616 if (filename == SCM_UNDEFINED)
617 {
618 filename = port;
619 port = scm_cur_inp;
620 }
621 else
622 SCM_ASSERT (SCM_NIMP (port) && SCM_PORTP (port) && SCM_OPENP (port),
623 port,
624 SCM_ARG1,
625 s_set_port_filename_x);
626 return SCM_PTAB_ENTRY (port)->file_name = filename;
627}
628
0f2d19dd
JB
629#ifndef ttyname
630extern char * ttyname();
631#endif
632
1cc91f1b 633
0f2d19dd
JB
634void
635scm_prinport (exp, port, type)
636 SCM exp;
637 SCM port;
638 char *type;
0f2d19dd
JB
639{
640 scm_gen_puts (scm_regular_string, "#<", port);
641 if (SCM_CLOSEDP (exp))
642 scm_gen_puts (scm_regular_string, "closed: ", port);
643 else
644 {
645 if (SCM_RDNG & SCM_CAR (exp))
646 scm_gen_puts (scm_regular_string, "input: ", port);
647 if (SCM_WRTNG & SCM_CAR (exp))
648 scm_gen_puts (scm_regular_string, "output: ", port);
649 }
650 scm_gen_puts (scm_regular_string, type, port);
651 scm_gen_putc (' ', port);
652#ifndef MSDOS
653#ifndef __EMX__
654#ifndef _DCC
655#ifndef AMIGA
656#ifndef THINK_C
657 if (SCM_OPENP (exp) && scm_tc16_fport == SCM_TYP16 (exp) && isatty (fileno ((FILE *)SCM_STREAM (exp))))
658 scm_gen_puts (scm_regular_string, ttyname (fileno ((FILE *)SCM_STREAM (exp))), port);
659 else
660#endif
661#endif
662#endif
663#endif
664#endif
665 if (SCM_OPFPORTP (exp))
666 scm_intprint ((long) fileno ((FILE *)SCM_STREAM (exp)), 10, port);
667 else
668 scm_intprint (SCM_CDR (exp), 16, port);
669 scm_gen_putc ('>', port);
670}
671
1cc91f1b 672
0f2d19dd
JB
673void
674scm_ports_prehistory ()
0f2d19dd
JB
675{
676 scm_numptob = 0;
677 scm_ptobs = (scm_ptobfuns *) malloc (sizeof (scm_ptobfuns));
678
679 /* WARNING: These scm_newptob calls must be done in this order.
680 * They must agree with the port declarations in tags.h.
681 */
682 /* scm_tc16_fport = */ scm_newptob (&scm_fptob);
683 /* scm_tc16_pipe = */ scm_newptob (&scm_pipob);
684 /* scm_tc16_strport = */ scm_newptob (&scm_stptob);
685 /* scm_tc16_sfport = */ scm_newptob (&scm_sfptob);
686}
687\f
688
689\f
690/* {Void Ports}
691 */
692
693int scm_tc16_void_port = 0;
694
695static int
696print_void_port (exp, port, writing)
697 SCM exp;
698 SCM port;
699 int writing;
700{
701 scm_prinport (exp, port, "void");
702 return 1;
703}
704
705static int
706putc_void_port (c, strm)
707 int c;
708 SCM strm;
709{
710 return 0; /* vestigial return value */
711}
712
713static int
714puts_void_port (s, strm)
715 char * s;
716 SCM strm;
717{
718 return 0; /* vestigial return value */
719}
720
721static scm_sizet
722write_void_port (ptr, size, nitems, strm)
723 void * ptr;
724 int size;
725 int nitems;
726 SCM strm;
727{
728 int len;
729 len = size * nitems;
730 return len;
731}
732
1cc91f1b
JB
733
734static int flush_void_port SCM_P ((SCM strm));
735
0f2d19dd
JB
736static int
737flush_void_port (strm)
738 SCM strm;
0f2d19dd
JB
739{
740 return 0;
741}
742
1cc91f1b
JB
743
744static int getc_void_port SCM_P ((SCM strm));
745
0f2d19dd
JB
746static int
747getc_void_port (strm)
748 SCM strm;
0f2d19dd
JB
749{
750 return EOF;
751}
752
1cc91f1b
JB
753
754static int close_void_port SCM_P ((SCM strm));
755
0f2d19dd
JB
756static int
757close_void_port (strm)
758 SCM strm;
0f2d19dd
JB
759{
760 return 0; /* this is ignored by scm_close_port. */
761}
762
763
1cc91f1b
JB
764
765static int noop0 SCM_P ((SCM stream));
766
0f2d19dd
JB
767static int
768noop0 (stream)
1cc91f1b 769 SCM stream;
0f2d19dd
JB
770{
771 return 0;
772}
773
774
775static struct scm_ptobfuns void_port_ptob =
776{
777 scm_mark0,
778 noop0,
779 print_void_port,
780 0, /* equal? */
781 putc_void_port,
782 puts_void_port,
783 write_void_port,
784 flush_void_port,
785 getc_void_port,
786 close_void_port,
787};
788
789\f
790
1cc91f1b 791
0f2d19dd
JB
792SCM
793scm_void_port (mode_str)
794 char * mode_str;
0f2d19dd
JB
795{
796 int mode_bits;
797 SCM answer;
798 struct scm_port_table * pt;
799
800 SCM_NEWCELL (answer);
801 SCM_DEFER_INTS;
802 mode_bits = scm_mode_bits (mode_str);
803 pt = scm_add_to_port_table (answer);
898a256f 804 SCM_SETCAR (answer, scm_tc16_void_port | mode_bits);
0f2d19dd
JB
805 SCM_SETPTAB_ENTRY (answer, pt);
806 SCM_SETSTREAM (answer, SCM_BOOL_F);
807 SCM_ALLOW_INTS;
808 return answer;
809}
810
811
812SCM_PROC (s_sys_make_void_port, "%make-void-port", 1, 0, 0, scm_sys_make_void_port);
1cc91f1b 813
0f2d19dd
JB
814SCM
815scm_sys_make_void_port (mode)
816 SCM mode;
0f2d19dd 817{
89958ad0 818 SCM_ASSERT (SCM_NIMP (mode) && SCM_ROSTRINGP (mode), mode,
0f2d19dd
JB
819 SCM_ARG1, s_sys_make_void_port);
820
89958ad0 821 SCM_COERCE_SUBSTR (mode);
0f2d19dd
JB
822 return scm_void_port (SCM_ROCHARS (mode));
823}
824
825
826
827\f
828
1cc91f1b 829
0f2d19dd
JB
830void
831scm_init_ports ()
0f2d19dd
JB
832{
833 scm_tc16_void_port = scm_newptob (&void_port_ptob);
834#include "ports.x"
835}
836