1 /* Copyright (C) 1995,1996,1997,1998,1999 Free Software Foundation, Inc.
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)
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.
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, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
40 * If you do not wish that, delete this exception notice. */
42 /* Software engineering face-lift by Greg J. Badros, 11-Dec-1999,
43 gjb@cs.washington.edu, http://www.cs.washington.edu/homes/gjb */
56 #include "scm_validate.h"
67 #ifdef HAVE_SYS_IOCTL_H
68 #include <sys/ioctl.h>
72 /* The port kind table --- a dynamically resized array of port types. */
75 /* scm_ptobs scm_numptob
76 * implement a dynamicly resized array of ptob records.
77 * Indexes into this table are used when generating type
78 * tags for smobjects (if you know a tag you can get an index and conversely).
80 scm_ptob_descriptor
*scm_ptobs
;
83 /* GC marker for a port with stream of SCM type. */
85 scm_markstream (SCM ptr
)
88 openp
= SCM_CAR (ptr
) & SCM_OPN
;
90 return SCM_STREAM (ptr
);
96 * We choose to use an interface similar to the smob interface with
97 * fill_input and write as standard fields, passed to the port
98 * type constructor, and optional fields set by setters.
101 static void flush_void_port (SCM port
);
102 static void end_input_void_port (SCM port
, int offset
);
103 static void write_void_port (SCM port
, void *data
, size_t size
);
106 scm_make_port_type (char *name
,
107 int (*fill_input
) (SCM port
),
108 void (*write
) (SCM port
, void *data
, size_t size
))
111 if (255 <= scm_numptob
)
114 SCM_SYSCALL (tmp
= (char *) realloc ((char *) scm_ptobs
,
116 * sizeof (scm_ptob_descriptor
)));
119 scm_ptobs
= (scm_ptob_descriptor
*) tmp
;
121 scm_ptobs
[scm_numptob
].name
= name
;
122 scm_ptobs
[scm_numptob
].mark
= 0;
123 scm_ptobs
[scm_numptob
].free
= scm_free0
;
124 scm_ptobs
[scm_numptob
].print
= scm_port_print
;
125 scm_ptobs
[scm_numptob
].equalp
= 0;
126 scm_ptobs
[scm_numptob
].close
= 0;
128 scm_ptobs
[scm_numptob
].write
= write
;
129 scm_ptobs
[scm_numptob
].flush
= flush_void_port
;
131 scm_ptobs
[scm_numptob
].end_input
= end_input_void_port
;
132 scm_ptobs
[scm_numptob
].fill_input
= fill_input
;
133 scm_ptobs
[scm_numptob
].input_waiting
= 0;
135 scm_ptobs
[scm_numptob
].seek
= 0;
136 scm_ptobs
[scm_numptob
].truncate
= 0;
142 ptoberr
:scm_wta (SCM_MAKINUM ((long) scm_numptob
),
143 (char *) SCM_NALLOC
, "scm_make_port_type");
144 /* Make a class object if Goops is present */
146 scm_make_port_classes (scm_numptob
- 1, SCM_PTOBNAME (scm_numptob
- 1));
147 return scm_tc7_port
+ (scm_numptob
- 1) * 256;
151 scm_set_port_mark (long tc
, SCM (*mark
) (SCM
))
153 scm_ptobs
[SCM_TC2PTOBNUM (tc
)].mark
= mark
;
157 scm_set_port_free (long tc
, scm_sizet (*free
) (SCM
))
159 scm_ptobs
[SCM_TC2PTOBNUM (tc
)].free
= free
;
163 scm_set_port_print (long tc
, int (*print
) (SCM exp
, SCM port
,
164 scm_print_state
*pstate
))
166 scm_ptobs
[SCM_TC2PTOBNUM (tc
)].print
= print
;
170 scm_set_port_equalp (long tc
, SCM (*equalp
) (SCM
, SCM
))
172 scm_ptobs
[SCM_TC2PTOBNUM (tc
)].equalp
= equalp
;
176 scm_set_port_flush (long tc
, void (*flush
) (SCM port
))
178 scm_ptobs
[SCM_TC2PTOBNUM (tc
)].flush
= flush
;
182 scm_set_port_end_input (long tc
, void (*end_input
) (SCM port
, int offset
))
184 scm_ptobs
[SCM_TC2PTOBNUM (tc
)].end_input
= end_input
;
188 scm_set_port_close (long tc
, int (*close
) (SCM
))
190 scm_ptobs
[SCM_TC2PTOBNUM (tc
)].close
= close
;
194 scm_set_port_seek (long tc
, off_t (*seek
) (SCM port
,
198 scm_ptobs
[SCM_TC2PTOBNUM (tc
)].seek
= seek
;
202 scm_set_port_truncate (long tc
, void (*truncate
) (SCM port
, off_t length
))
204 scm_ptobs
[SCM_TC2PTOBNUM (tc
)].truncate
= truncate
;
208 scm_set_port_input_waiting (long tc
, int (*input_waiting
) (SCM
))
210 scm_ptobs
[SCM_TC2PTOBNUM (tc
)].input_waiting
= input_waiting
;
215 GUILE_PROC(scm_char_ready_p
, "char-ready?", 0, 1, 0,
218 #define FUNC_NAME s_scm_char_ready_p
222 if (SCM_UNBNDP (port
))
225 SCM_VALIDATE_OPINPORT(1,port
);
227 pt
= SCM_PTAB_ENTRY (port
);
229 /* if the current read buffer is filled, or the
230 last pushed-back char has been read and the saved buffer is
231 filled, result is true. */
232 if (pt
->read_pos
< pt
->read_end
233 || (pt
->read_buf
== pt
->putback_buf
234 && pt
->saved_read_pos
< pt
->saved_read_end
))
238 scm_ptob_descriptor
*ptob
= &scm_ptobs
[SCM_PTOBNUM (port
)];
240 if (ptob
->input_waiting
)
241 return SCM_BOOL(ptob
->input_waiting (port
));
248 /* Clear a port's read buffers, returning the contents. */
249 GUILE_PROC (scm_drain_input
, "drain-input", 1, 0, 0,
252 #define FUNC_NAME s_scm_drain_input
255 scm_port
*pt
= SCM_PTAB_ENTRY (port
);
259 SCM_VALIDATE_OPINPORT(1,port
);
261 count
= pt
->read_end
- pt
->read_pos
;
262 if (pt
->read_buf
== pt
->putback_buf
)
263 count
+= pt
->saved_read_end
- pt
->saved_read_pos
;
265 result
= scm_makstr (count
, 0);
266 dst
= SCM_CHARS (result
);
268 while (pt
->read_pos
< pt
->read_end
)
269 *dst
++ = *(pt
->read_pos
++);
271 if (pt
->read_buf
== pt
->putback_buf
)
273 while (pt
->saved_read_pos
< pt
->saved_read_end
)
274 *dst
++ = *(pt
->saved_read_pos
++);
282 /* Standard ports --- current input, output, error, and more(!). */
284 GUILE_PROC(scm_current_input_port
, "current-input-port", 0, 0, 0,
287 #define FUNC_NAME s_scm_current_input_port
293 GUILE_PROC(scm_current_output_port
, "current-output-port", 0, 0, 0,
296 #define FUNC_NAME s_scm_current_output_port
302 GUILE_PROC(scm_current_error_port
, "current-error-port", 0, 0, 0,
305 #define FUNC_NAME s_scm_current_error_port
311 GUILE_PROC(scm_current_load_port
, "current-load-port", 0, 0, 0,
314 #define FUNC_NAME s_scm_current_load_port
316 return scm_cur_loadp
;
320 GUILE_PROC(scm_set_current_input_port
, "set-current-input-port", 1, 0, 0,
323 #define FUNC_NAME s_scm_set_current_input_port
325 SCM oinp
= scm_cur_inp
;
326 SCM_VALIDATE_OPINPORT(1,port
);
333 GUILE_PROC(scm_set_current_output_port
, "set-current-output-port", 1, 0, 0,
336 #define FUNC_NAME s_scm_set_current_output_port
338 SCM ooutp
= scm_cur_outp
;
339 port
= SCM_COERCE_OUTPORT (port
);
340 SCM_VALIDATE_OPOUTPORT(1,port
);
347 GUILE_PROC(scm_set_current_error_port
, "set-current-error-port", 1, 0, 0,
350 #define FUNC_NAME s_scm_set_current_error_port
352 SCM oerrp
= scm_cur_errp
;
353 port
= SCM_COERCE_OUTPORT (port
);
354 SCM_VALIDATE_OPOUTPORT(1,port
);
361 /* The port table --- an array of pointers to ports. */
363 scm_port
**scm_port_table
;
365 int scm_port_table_size
= 0; /* Number of ports in scm_port_table. */
366 int scm_port_table_room
= 20; /* Size of the array. */
368 /* Add a port to the table. */
371 scm_add_to_port_table (SCM port
)
375 if (scm_port_table_size
== scm_port_table_room
)
377 void *newt
= realloc ((char *) scm_port_table
,
378 (scm_sizet
) (sizeof (scm_port
*)
379 * scm_port_table_room
* 2));
381 scm_memory_error ("scm_add_to_port_table");
382 scm_port_table
= (scm_port
**) newt
;
383 scm_port_table_room
*= 2;
385 entry
= (scm_port
*) malloc (sizeof (scm_port
));
387 scm_memory_error ("scm_add_to_port_table");
390 entry
->entry
= scm_port_table_size
;
393 entry
->file_name
= SCM_BOOL_F
;
394 entry
->line_number
= 0;
395 entry
->column_number
= 0;
396 entry
->putback_buf
= 0;
397 entry
->putback_buf_size
= 0;
398 entry
->rw_active
= SCM_PORT_NEITHER
;
399 entry
->rw_random
= 0;
401 scm_port_table
[scm_port_table_size
] = entry
;
402 scm_port_table_size
++;
407 /* Remove a port from the table and destroy it. */
410 scm_remove_from_port_table (SCM port
)
412 scm_port
*p
= SCM_PTAB_ENTRY (port
);
415 if (i
>= scm_port_table_size
)
416 scm_wta (port
, "Port not in table", "scm_remove_from_port_table");
418 free (p
->putback_buf
);
420 /* Since we have just freed slot i we can shrink the table by moving
421 the last entry to that slot... */
422 if (i
< scm_port_table_size
- 1)
424 scm_port_table
[i
] = scm_port_table
[scm_port_table_size
- 1];
425 scm_port_table
[i
]->entry
= i
;
427 SCM_SETPTAB_ENTRY (port
, 0);
428 scm_port_table_size
--;
432 /* Undocumented functions for debugging. */
433 /* Return the number of ports in the table. */
435 GUILE_PROC(scm_pt_size
, "pt-size", 0, 0, 0,
438 #define FUNC_NAME s_scm_pt_size
440 return SCM_MAKINUM (scm_port_table_size
);
444 /* Return the ith member of the port table. */
445 GUILE_PROC(scm_pt_member
, "pt-member", 1, 0, 0,
448 #define FUNC_NAME s_scm_pt_member
451 SCM_VALIDATE_INT_copy(1,member
,i
);
452 if (i
< 0 || i
>= scm_port_table_size
)
455 return scm_port_table
[i
]->port
;
462 /* Revealed counts --- an oddity inherited from SCSH. */
464 /* Find a port in the table and return its revealed count.
465 Also used by the garbage collector.
469 scm_revealed_count (SCM port
)
471 return SCM_REVEALED(port
);
476 /* Return the revealed count for a port. */
478 GUILE_PROC(scm_port_revealed
, "port-revealed", 1, 0, 0,
481 #define FUNC_NAME s_scm_port_revealed
483 port
= SCM_COERCE_OUTPORT (port
);
484 SCM_VALIDATE_PORT(1,port
);
485 return SCM_MAKINUM (scm_revealed_count (port
));
489 /* Set the revealed count for a port. */
490 GUILE_PROC(scm_set_port_revealed_x
, "set-port-revealed!", 2, 0, 0,
491 (SCM port
, SCM rcount
),
493 #define FUNC_NAME s_scm_set_port_revealed_x
495 port
= SCM_COERCE_OUTPORT (port
);
496 SCM_VALIDATE_PORT(1,port
);
497 SCM_VALIDATE_INT(2,rcount
);
498 SCM_REVEALED (port
) = SCM_INUM (rcount
);
499 return SCM_UNSPECIFIED
;
505 /* Retrieving a port's mode. */
507 /* Return the flags that characterize a port based on the mode
508 * string used to open a file for that port.
510 * See PORT FLAGS in scm.h
514 scm_mode_bits (char *modes
)
517 | (strchr (modes
, 'r') || strchr (modes
, '+') ? SCM_RDNG
: 0)
518 | ( strchr (modes
, 'w')
519 || strchr (modes
, 'a')
520 || strchr (modes
, '+') ? SCM_WRTNG
: 0)
521 | (strchr (modes
, '0') ? SCM_BUF0
: 0)
522 | (strchr (modes
, 'l') ? SCM_BUFLINE
: 0));
526 /* Return the mode flags from an open port.
527 * Some modes such as "append" are only used when opening
528 * a file and are not returned here. */
530 GUILE_PROC(scm_port_mode
, "port-mode", 1, 0, 0,
533 #define FUNC_NAME s_scm_port_mode
538 port
= SCM_COERCE_OUTPORT (port
);
539 SCM_VALIDATE_OPPORT(1,port
);
540 if (SCM_CAR (port
) & SCM_RDNG
) {
541 if (SCM_CAR (port
) & SCM_WRTNG
)
542 strcpy (modes
, "r+");
546 else if (SCM_CAR (port
) & SCM_WRTNG
)
548 if (SCM_CAR (port
) & SCM_BUF0
)
550 return scm_makfromstr (modes
, strlen (modes
), 0);
559 * Call the close operation on a port object.
560 * see also scm_close.
562 GUILE_PROC(scm_close_port
, "close-port", 1, 0, 0,
565 #define FUNC_NAME s_scm_close_port
570 port
= SCM_COERCE_OUTPORT (port
);
572 SCM_VALIDATE_PORT(1,port
);
573 if (SCM_CLOSEDP (port
))
575 i
= SCM_PTOBNUM (port
);
576 if (scm_ptobs
[i
].close
)
577 rv
= (scm_ptobs
[i
].close
) (port
);
580 scm_remove_from_port_table (port
);
581 SCM_SETAND_CAR (port
, ~SCM_OPN
);
582 return SCM_NEGATE_BOOL(rv
< 0);
586 GUILE_PROC(scm_close_all_ports_except
, "close-all-ports-except", 0, 0, 1,
589 #define FUNC_NAME s_scm_close_all_ports_except
592 SCM_VALIDATE_NIMCONS(1,ports
);
593 while (i
< scm_port_table_size
)
595 SCM thisport
= scm_port_table
[i
]->port
;
597 SCM ports_ptr
= ports
;
599 while (SCM_NNULLP (ports_ptr
))
601 SCM port
= SCM_COERCE_OUTPORT (SCM_CAR (ports_ptr
));
603 SCM_VALIDATE_OPPORT(1,port
);
604 if (port
== thisport
)
606 ports_ptr
= SCM_CDR (ports_ptr
);
611 /* i is not to be incremented here. */
612 scm_close_port (thisport
);
614 return SCM_UNSPECIFIED
;
620 /* Utter miscellany. Gosh, we should clean this up some time. */
622 GUILE_PROC(scm_input_port_p
, "input-port?", 1, 0, 0,
625 #define FUNC_NAME s_scm_input_port_p
629 return SCM_BOOL(SCM_INPORTP (x
));
633 GUILE_PROC(scm_output_port_p
, "output-port?", 1, 0, 0,
636 #define FUNC_NAME s_scm_output_port_p
640 if (SCM_PORT_WITH_PS_P (x
))
641 x
= SCM_PORT_WITH_PS_PORT (x
);
642 return SCM_BOOL(SCM_OUTPORTP (x
));
646 GUILE_PROC(scm_port_closed_p
, "port-closed?", 1, 0, 0,
649 #define FUNC_NAME s_scm_port_closed_p
651 SCM_VALIDATE_OPPORT(1,port
);
652 return SCM_NEGATE_BOOL(SCM_OPPORTP (port
));
656 GUILE_PROC(scm_eof_object_p
, "eof-object?", 1, 0, 0,
659 #define FUNC_NAME s_scm_eof_object_p
661 return SCM_BOOL(SCM_EOF_OBJECT_P (x
));
665 GUILE_PROC(scm_force_output
, "force-output", 0, 1, 0,
668 #define FUNC_NAME s_scm_force_output
670 if (SCM_UNBNDP (port
))
674 port
= SCM_COERCE_OUTPORT (port
);
675 SCM_VALIDATE_OPOUTPORT(1,port
);
678 return SCM_UNSPECIFIED
;
682 GUILE_PROC (scm_flush_all_ports
, "flush-all-ports", 0, 0, 0,
685 #define FUNC_NAME s_scm_flush_all_ports
689 for (i
= 0; i
< scm_port_table_size
; i
++)
691 if (SCM_OPOUTPORTP (scm_port_table
[i
]->port
))
692 scm_flush (scm_port_table
[i
]->port
);
694 return SCM_UNSPECIFIED
;
698 GUILE_PROC(scm_read_char
, "read-char", 0, 1, 0,
701 #define FUNC_NAME s_scm_read_char
704 if (SCM_UNBNDP (port
))
706 SCM_VALIDATE_OPINPORT(1,port
);
710 return SCM_MAKICHR (c
);
714 /* this should only be called when the read buffer is empty. it
715 tries to refill the read buffer. it returns the first char from
716 the port, which is either EOF or *(pt->read_pos). */
718 scm_fill_input (SCM port
)
720 scm_port
*pt
= SCM_PTAB_ENTRY (port
);
722 if (pt
->read_buf
== pt
->putback_buf
)
724 /* finished reading put-back chars. */
725 pt
->read_buf
= pt
->saved_read_buf
;
726 pt
->read_pos
= pt
->saved_read_pos
;
727 pt
->read_end
= pt
->saved_read_end
;
728 pt
->read_buf_size
= pt
->saved_read_buf_size
;
729 if (pt
->read_pos
< pt
->read_end
)
730 return *(pt
->read_pos
);
732 return scm_ptobs
[SCM_PTOBNUM (port
)].fill_input (port
);
739 scm_port
*pt
= SCM_PTAB_ENTRY (port
);
741 if (pt
->rw_active
== SCM_PORT_WRITE
)
743 /* may be marginally faster than calling scm_flush. */
744 scm_ptobs
[SCM_PTOBNUM (port
)].flush (port
);
748 pt
->rw_active
= SCM_PORT_READ
;
750 if (pt
->read_pos
>= pt
->read_end
)
752 if (scm_fill_input (port
) == EOF
)
756 c
= *(pt
->read_pos
++);
775 scm_putc (char c
, SCM port
)
777 scm_lfwrite (&c
, 1, port
);
781 scm_puts (char *s
, SCM port
)
783 scm_lfwrite (s
, strlen (s
), port
);
787 scm_lfwrite (char *ptr
, scm_sizet size
, SCM port
)
789 scm_port
*pt
= SCM_PTAB_ENTRY (port
);
790 scm_ptob_descriptor
*ptob
= &scm_ptobs
[SCM_PTOBNUM (port
)];
792 if (pt
->rw_active
== SCM_PORT_READ
)
793 scm_end_input (port
);
795 ptob
->write (port
, ptr
, size
);
798 pt
->rw_active
= SCM_PORT_WRITE
;
805 scm_sizet i
= SCM_PTOBNUM (port
);
806 (scm_ptobs
[i
].flush
) (port
);
810 scm_end_input (SCM port
)
813 scm_port
*pt
= SCM_PTAB_ENTRY (port
);
815 if (pt
->read_buf
== pt
->putback_buf
)
817 offset
= pt
->read_end
- pt
->read_pos
;
818 pt
->read_buf
= pt
->saved_read_buf
;
819 pt
->read_pos
= pt
->saved_read_pos
;
820 pt
->read_end
= pt
->saved_read_end
;
821 pt
->read_buf_size
= pt
->saved_read_buf_size
;
826 scm_ptobs
[SCM_PTOBNUM (port
)].end_input (port
, offset
);
833 scm_ungetc (int c
, SCM port
)
835 scm_port
*pt
= SCM_PTAB_ENTRY (port
);
837 if (pt
->read_buf
== pt
->putback_buf
)
838 /* already using the put-back buffer. */
840 /* enlarge putback_buf if necessary. */
841 if (pt
->read_end
== pt
->read_buf
+ pt
->read_buf_size
842 && pt
->read_buf
== pt
->read_pos
)
844 int new_size
= pt
->read_buf_size
* 2;
846 (unsigned char *) realloc (pt
->putback_buf
, new_size
);
849 scm_memory_error ("scm_ungetc");
850 pt
->read_pos
= pt
->read_buf
= pt
->putback_buf
= tmp
;
851 pt
->read_end
= pt
->read_buf
+ pt
->read_buf_size
;
852 pt
->read_buf_size
= pt
->putback_buf_size
= new_size
;
855 /* shift any existing bytes to buffer + 1. */
856 if (pt
->read_pos
== pt
->read_end
)
857 pt
->read_end
= pt
->read_buf
+ 1;
858 else if (pt
->read_pos
!= pt
->read_buf
+ 1)
860 int count
= pt
->read_end
- pt
->read_pos
;
862 memmove (pt
->read_buf
+ 1, pt
->read_pos
, count
);
863 pt
->read_end
= pt
->read_buf
+ 1 + count
;
866 pt
->read_pos
= pt
->read_buf
;
869 /* switch to the put-back buffer. */
871 if (pt
->putback_buf
== NULL
)
873 pt
->putback_buf
= (char *) malloc (SCM_INITIAL_PUTBACK_BUF_SIZE
);
874 if (pt
->putback_buf
== NULL
)
875 scm_memory_error ("scm_ungetc");
876 pt
->putback_buf_size
= SCM_INITIAL_PUTBACK_BUF_SIZE
;
879 pt
->saved_read_buf
= pt
->read_buf
;
880 pt
->saved_read_pos
= pt
->read_pos
;
881 pt
->saved_read_end
= pt
->read_end
;
882 pt
->saved_read_buf_size
= pt
->read_buf_size
;
884 pt
->read_pos
= pt
->read_buf
= pt
->putback_buf
;
885 pt
->read_end
= pt
->read_buf
+ 1;
886 pt
->read_buf_size
= pt
->putback_buf_size
;
892 pt
->rw_active
= SCM_PORT_READ
;
896 /* What should col be in this case?
897 * We'll leave it at -1.
899 SCM_LINUM (port
) -= 1;
907 scm_ungets (char *s
, int n
, SCM port
)
909 /* This is simple minded and inefficient, but unreading strings is
910 * probably not a common operation, and remember that line and
911 * column numbers have to be handled...
913 * Please feel free to write an optimized version!
916 scm_ungetc (s
[n
], port
);
920 GUILE_PROC(scm_peek_char
, "peek-char", 0, 1, 0,
923 #define FUNC_NAME s_scm_peek_char
926 if (SCM_UNBNDP (port
))
929 SCM_VALIDATE_OPINPORT(1,port
);
933 scm_ungetc (c
, port
);
934 return SCM_MAKICHR (c
);
938 GUILE_PROC (scm_unread_char
, "unread-char", 2, 0, 0,
939 (SCM cobj
, SCM port
),
941 #define FUNC_NAME s_scm_unread_char
945 SCM_VALIDATE_CHAR(1,cobj
);
946 if (SCM_UNBNDP (port
))
949 SCM_VALIDATE_OPINPORT(1,port
);
953 scm_ungetc (c
, port
);
958 GUILE_PROC (scm_unread_string
, "unread-string", 2, 0, 0,
961 #define FUNC_NAME s_scm_unread_string
963 SCM_VALIDATE_STRING(1,str
);
964 if (SCM_UNBNDP (port
))
967 SCM_VALIDATE_OPINPORT(1,port
);
969 scm_ungets (SCM_ROUCHARS (str
), SCM_LENGTH (str
), port
);
975 GUILE_PROC (scm_seek
, "seek", 3, 0, 0,
976 (SCM object
, SCM offset
, SCM whence
),
978 #define FUNC_NAME s_scm_seek
984 object
= SCM_COERCE_OUTPORT (object
);
986 off
= SCM_NUM2LONG (2,offset
);
987 SCM_VALIDATE_INT_COPY(3,whence
,how
);
988 if (how
!= SEEK_SET
&& how
!= SEEK_CUR
&& how
!= SEEK_END
)
989 SCM_OUT_OF_RANGE (3, whence
);
990 if (SCM_NIMP (object
) && SCM_OPPORTP (object
))
992 scm_ptob_descriptor
*ptob
= scm_ptobs
+ SCM_PTOBNUM (object
);
995 SCM_MISC_ERROR ("port is not seekable",
996 scm_cons (object
, SCM_EOL
));
998 rv
= ptob
->seek (object
, off
, how
);
1000 else /* file descriptor?. */
1002 SCM_VALIDATE_INT(1,object
);
1003 rv
= lseek (SCM_INUM (object
), off
, how
);
1007 return scm_long2num (rv
);
1011 GUILE_PROC (scm_truncate_file
, "truncate-file", 1, 1, 0,
1012 (SCM object
, SCM length
),
1014 #define FUNC_NAME s_scm_truncate_file
1019 /* object can be a port, fdes or filename. */
1021 if (SCM_UNBNDP (length
))
1023 /* must supply length if object is a filename. */
1024 if (SCM_NIMP (object
) && SCM_ROSTRINGP (object
))
1025 scm_wrong_num_args (SCM_FUNC_NAME
);
1027 length
= scm_seek (object
, SCM_INUM0
, SCM_MAKINUM (SEEK_CUR
));
1029 c_length
= SCM_NUM2LONG (2,length
);
1031 SCM_MISC_ERROR ("negative offset", SCM_EOL
);
1033 object
= SCM_COERCE_OUTPORT (object
);
1034 if (SCM_INUMP (object
))
1036 SCM_SYSCALL (rv
= ftruncate (SCM_INUM (object
), c_length
));
1038 else if (SCM_NIMP (object
) && SCM_OPOUTPORTP (object
))
1040 scm_port
*pt
= SCM_PTAB_ENTRY (object
);
1041 scm_ptob_descriptor
*ptob
= scm_ptobs
+ SCM_PTOBNUM (object
);
1043 if (!ptob
->truncate
)
1044 SCM_MISC_ERROR ("port is not truncatable", SCM_EOL
);
1045 if (pt
->rw_active
== SCM_PORT_READ
)
1046 scm_end_input (object
);
1047 else if (pt
->rw_active
== SCM_PORT_WRITE
)
1048 ptob
->flush (object
);
1050 ptob
->truncate (object
, c_length
);
1055 SCM_VALIDATE_ROSTRING(1,object
);
1056 SCM_COERCE_SUBSTR (object
);
1057 SCM_SYSCALL (rv
= truncate (SCM_ROCHARS (object
), c_length
));
1061 return SCM_UNSPECIFIED
;
1065 GUILE_PROC (scm_port_line
, "port-line", 1, 0, 0,
1068 #define FUNC_NAME s_scm_port_line
1070 port
= SCM_COERCE_OUTPORT (port
);
1071 SCM_VALIDATE_OPENPORT(1,port
);
1072 return SCM_MAKINUM (SCM_LINUM (port
));
1076 GUILE_PROC (scm_set_port_line_x
, "set-port-line!", 2, 0, 0,
1077 (SCM port
, SCM line
),
1079 #define FUNC_NAME s_scm_set_port_line_x
1081 port
= SCM_COERCE_OUTPORT (port
);
1082 SCM_VALIDATE_OPENPORT(1,port
);
1083 SCM_VALIDATE_INT(2,line
);
1084 return SCM_PTAB_ENTRY (port
)->line_number
= SCM_INUM (line
);
1088 GUILE_PROC (scm_port_column
, "port-column", 1, 0, 0,
1091 #define FUNC_NAME s_scm_port_column
1093 port
= SCM_COERCE_OUTPORT (port
);
1094 SCM_VALIDATE_OPENPORT(1,port
);
1095 return SCM_MAKINUM (SCM_COL (port
));
1099 GUILE_PROC (scm_set_port_column_x
, "set-port-column!", 2, 0, 0,
1100 (SCM port
, SCM column
),
1102 #define FUNC_NAME s_scm_set_port_column_x
1104 port
= SCM_COERCE_OUTPORT (port
);
1105 SCM_VALIDATE_OPENPORT(1,port
);
1106 SCM_VALIDATE_INT(2,column
);
1107 return SCM_PTAB_ENTRY (port
)->column_number
= SCM_INUM (column
);
1111 GUILE_PROC (scm_port_filename
, "port-filename", 1, 0, 0,
1114 #define FUNC_NAME s_scm_port_filename
1116 port
= SCM_COERCE_OUTPORT (port
);
1117 SCM_VALIDATE_OPENPORT(1,port
);
1118 return SCM_PTAB_ENTRY (port
)->file_name
;
1122 GUILE_PROC (scm_set_port_filename_x
, "set-port-filename!", 2, 0, 0,
1123 (SCM port
, SCM filename
),
1125 #define FUNC_NAME s_scm_set_port_filename_x
1127 port
= SCM_COERCE_OUTPORT (port
);
1128 SCM_VALIDATE_OPENPORT(1,port
);
1129 /* We allow the user to set the filename to whatever he likes. */
1130 return SCM_PTAB_ENTRY (port
)->file_name
= filename
;
1135 extern char * ttyname();
1139 scm_print_port_mode (SCM exp
, SCM port
)
1141 scm_puts (SCM_CLOSEDP (exp
)
1143 : (SCM_RDNG
& SCM_CAR (exp
)
1144 ? (SCM_WRTNG
& SCM_CAR (exp
)
1147 : (SCM_WRTNG
& SCM_CAR (exp
)
1154 scm_port_print (SCM exp
, SCM port
, scm_print_state
*pstate
)
1156 char *type
= SCM_PTOBNAME (SCM_PTOBNUM (exp
));
1159 scm_puts ("#<", port
);
1160 scm_print_port_mode (exp
, port
);
1161 scm_puts (type
, port
);
1162 scm_putc (' ', port
);
1163 scm_intprint (SCM_CDR (exp
), 16, port
);
1164 scm_putc ('>', port
);
1168 extern void scm_make_fptob ();
1169 extern void scm_make_stptob ();
1170 extern void scm_make_sfptob ();
1173 scm_ports_prehistory ()
1176 scm_ptobs
= (scm_ptob_descriptor
*) malloc (sizeof (scm_ptob_descriptor
));
1178 /* WARNING: These scm_newptob calls must be done in this order.
1179 * They must agree with the port declarations in tags.h.
1181 /* scm_tc16_fport = */ scm_make_fptob ();
1182 /* scm_tc16_pipe was here */ scm_make_fptob (); /* dummy. */
1183 /* scm_tc16_strport = */ scm_make_stptob ();
1184 /* scm_tc16_sfport = */ scm_make_sfptob ();
1191 long scm_tc16_void_port
= 0;
1194 flush_void_port (SCM port
)
1199 end_input_void_port (SCM port
, int offset
)
1204 write_void_port (SCM port
, void *data
, size_t size
)
1209 scm_void_port (char *mode_str
)
1215 SCM_NEWCELL (answer
);
1217 mode_bits
= scm_mode_bits (mode_str
);
1218 pt
= scm_add_to_port_table (answer
);
1219 SCM_SETPTAB_ENTRY (answer
, pt
);
1220 SCM_SETSTREAM (answer
, 0);
1221 SCM_SETCAR (answer
, scm_tc16_void_port
| mode_bits
);
1227 GUILE_PROC (scm_sys_make_void_port
, "%make-void-port", 1, 0, 0,
1230 #define FUNC_NAME s_scm_sys_make_void_port
1232 SCM_VALIDATE_ROSTRING(1,mode
);
1233 SCM_COERCE_SUBSTR (mode
);
1234 return scm_void_port (SCM_ROCHARS (mode
));
1239 /* Initialization. */
1244 /* lseek() symbols. */
1245 scm_sysintern ("SEEK_SET", SCM_MAKINUM (SEEK_SET
));
1246 scm_sysintern ("SEEK_CUR", SCM_MAKINUM (SEEK_CUR
));
1247 scm_sysintern ("SEEK_END", SCM_MAKINUM (SEEK_END
));
1249 scm_tc16_void_port
= scm_make_port_type ("void", 0, write_void_port
);