Commit | Line | Data |
---|---|---|
0f2d19dd JB |
1 | /* classes: h_files */ |
2 | ||
3 | #ifndef PORTSH | |
4 | #define PORTSH | |
840ae05d | 5 | /* Copyright (C) 1995,1996,1997,1998,1999 Free Software Foundation, Inc. |
0f2d19dd JB |
6 | * |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2, or (at your option) | |
10 | * any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with this software; see the file COPYING. If not, write to | |
82892bed JB |
19 | * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, |
20 | * Boston, MA 02111-1307 USA | |
0f2d19dd JB |
21 | * |
22 | * As a special exception, the Free Software Foundation gives permission | |
23 | * for additional uses of the text contained in its release of GUILE. | |
24 | * | |
25 | * The exception is that, if you link the GUILE library with other files | |
26 | * to produce an executable, this does not by itself cause the | |
27 | * resulting executable to be covered by the GNU General Public License. | |
28 | * Your use of that executable is in no way restricted on account of | |
29 | * linking the GUILE library code into it. | |
30 | * | |
31 | * This exception does not however invalidate any other reasons why | |
32 | * the executable file might be covered by the GNU General Public License. | |
33 | * | |
34 | * This exception applies only to the code released by the | |
35 | * Free Software Foundation under the name GUILE. If you copy | |
36 | * code from other Free Software Foundation releases into a copy of | |
37 | * GUILE, as the General Public License permits, the exception does | |
38 | * not apply to the code that you add in this way. To avoid misleading | |
39 | * anyone as to the status of such modified files, you must delete | |
40 | * this exception notice from them. | |
41 | * | |
42 | * If you write modifications of your own for GUILE, it is your choice | |
43 | * whether to permit this exception to apply to your modifications. | |
82892bed | 44 | * If you do not wish that, delete this exception notice. */ |
0f2d19dd | 45 | \f |
b4309c3c | 46 | #include "libguile/__scm.h" |
0f2d19dd | 47 | |
e0d86ad2 | 48 | #include "libguile/print.h" |
78446828 | 49 | #include "libguile/struct.h" |
e0d86ad2 | 50 | |
acdb12da JB |
51 | /* Not sure if this is a good idea. We need it for off_t. */ |
52 | #include <sys/types.h> | |
53 | ||
0f2d19dd JB |
54 | \f |
55 | ||
6c951427 | 56 | #define SCM_INITIAL_PUTBACK_BUF_SIZE 4 |
0855ef71 | 57 | |
61e452ba JB |
58 | /* values for the rw_active flag. */ |
59 | enum scm_port_rw_active { | |
60 | SCM_PORT_NEITHER = 0, | |
61 | SCM_PORT_READ = 1, | |
62 | SCM_PORT_WRITE = 2 | |
63 | }; | |
64 | ||
840ae05d JB |
65 | /* C representation of a Scheme port. */ |
66 | ||
67 | typedef struct | |
0f2d19dd | 68 | { |
ee149d03 | 69 | SCM port; /* Link back to the port object. */ |
0855ef71 | 70 | int entry; /* Index in port table. */ |
0f2d19dd JB |
71 | int revealed; /* 0 not revealed, > 1 revealed. |
72 | * Revealed ports do not get GC'd. | |
73 | */ | |
840ae05d JB |
74 | /* data for the underlying port implementation. may be an SCM cell or |
75 | cast to a pointer to C data. */ | |
0f2d19dd | 76 | SCM stream; |
0f2d19dd | 77 | |
0855ef71 | 78 | SCM file_name; /* debugging support. */ |
ebf7394e GH |
79 | int line_number; /* debugging support. */ |
80 | int column_number; /* debugging support. */ | |
0855ef71 | 81 | |
ee149d03 JB |
82 | /* port buffers. the buffer(s) are set up for all ports. |
83 | in the case of string ports, the buffer is the string itself. | |
84 | in the case of unbuffered file ports, the buffer is a | |
85 | single char: shortbuf. */ | |
86 | ||
87 | /* this buffer is filled from read_buf to read_end using the ptob | |
88 | buffer_fill. then input requests are taken from read_pos until | |
89 | it reaches read_end. */ | |
90 | ||
91 | unsigned char *read_buf; /* buffer start. */ | |
840ae05d | 92 | const unsigned char *read_pos;/* the next unread char. */ |
ee149d03 | 93 | unsigned char *read_end; /* pointer to last buffered char + 1. */ |
840ae05d | 94 | off_t read_buf_size; /* size of the buffer. */ |
ee149d03 | 95 | |
6c951427 GH |
96 | /* when chars are put back into the buffer, e.g., using peek-char or |
97 | unread-string, the read-buffer pointers are switched to cbuf. | |
98 | the original pointers are saved here and restored when the put-back | |
99 | chars have been consumed. */ | |
100 | unsigned char *saved_read_buf; | |
101 | const unsigned char *saved_read_pos; | |
102 | unsigned char *saved_read_end; | |
103 | off_t saved_read_buf_size; | |
104 | ||
ee149d03 JB |
105 | /* write requests are saved into this buffer at write_pos until it |
106 | reaches write_buf + write_buf_size, then the ptob flush is | |
107 | called. */ | |
108 | ||
6c951427 | 109 | unsigned char *write_buf; /* buffer start. */ |
ee149d03 JB |
110 | unsigned char *write_pos; /* pointer to last buffered char + 1. */ |
111 | unsigned char *write_end; /* pointer to end of buffer + 1. */ | |
840ae05d | 112 | off_t write_buf_size; /* size of the buffer. */ |
ee149d03 JB |
113 | |
114 | unsigned char shortbuf; /* buffer for "unbuffered" streams. */ | |
115 | ||
840ae05d JB |
116 | int rw_random; /* true if the port is bidirectional and |
117 | random access. implies that the buffers | |
118 | must be flushed before switching between | |
119 | reading and writing. */ | |
120 | ||
61e452ba JB |
121 | enum scm_port_rw_active rw_active; /* for bidirectional random |
122 | ports, indicates which of the | |
123 | buffers is currently in use. can | |
124 | be SCM_PORT_WRITE, SCM_PORT_READ, | |
840ae05d | 125 | or 0. */ |
ee149d03 | 126 | |
61e452ba | 127 | |
6c951427 GH |
128 | /* a buffer for un-read chars and strings. */ |
129 | unsigned char *putback_buf; | |
130 | int putback_buf_size; /* allocated size of putback_buf. */ | |
840ae05d JB |
131 | } scm_port; |
132 | ||
840ae05d | 133 | extern scm_port **scm_port_table; |
0f82baf6 | 134 | extern int scm_port_table_size; /* Number of ports in scm_port_table. */ |
0f2d19dd JB |
135 | |
136 | ||
137 | \f | |
138 | ||
0c32d76c MD |
139 | #define SCM_EOF_OBJECT_P(x) ((x) == SCM_EOF_VAL) |
140 | ||
0f2d19dd | 141 | /* PORT FLAGS |
dbece3a2 | 142 | * A set of flags characterizes a port. |
571031dc JB |
143 | * Note that we reserve the bits 1 << 24 and above for use by the |
144 | * routines in the port's scm_ptobfuns structure. | |
0f2d19dd JB |
145 | */ |
146 | #define SCM_OPN (1L<<16) /* Is the port open? */ | |
147 | #define SCM_RDNG (2L<<16) /* Is it a readable port? */ | |
148 | #define SCM_WRTNG (4L<<16) /* Is it writable? */ | |
ee149d03 | 149 | #define SCM_BUF0 (8L<<16) /* Is it unbuffered? */ |
6c951427 | 150 | /* #define SCM_CRDY (32L<<16) obsolete, for pushed back characters */ |
ee149d03 | 151 | #define SCM_BUFLINE (64L<<16) /* Is it line-buffered? */ |
0f2d19dd | 152 | |
0f2d19dd JB |
153 | #define SCM_PORTP(x) (SCM_TYP7(x)==scm_tc7_port) |
154 | #define SCM_OPPORTP(x) (((0x7f | SCM_OPN) & SCM_CAR(x))==(scm_tc7_port | SCM_OPN)) | |
155 | #define SCM_OPINPORTP(x) (((0x7f | SCM_OPN | SCM_RDNG) & SCM_CAR(x))==(scm_tc7_port | SCM_OPN | SCM_RDNG)) | |
156 | #define SCM_OPOUTPORTP(x) (((0x7f | SCM_OPN | SCM_WRTNG) & SCM_CAR(x))==(scm_tc7_port | SCM_OPN | SCM_WRTNG)) | |
0f2d19dd JB |
157 | #define SCM_INPORTP(x) (((0x7f | SCM_RDNG) & SCM_CAR(x))==(scm_tc7_port | SCM_RDNG)) |
158 | #define SCM_OUTPORTP(x) (((0x7f | SCM_WRTNG) & SCM_CAR(x))==(scm_tc7_port | SCM_WRTNG)) | |
159 | #define SCM_OPENP(x) (SCM_OPN & SCM_CAR(x)) | |
160 | #define SCM_CLOSEDP(x) (!SCM_OPENP(x)) | |
840ae05d | 161 | #define SCM_PTAB_ENTRY(x) ((scm_port *) SCM_CDR(x)) |
0f2d19dd JB |
162 | #define SCM_SETPTAB_ENTRY(x,ent) SCM_SETCDR ((x), (SCM)(ent)) |
163 | #define SCM_STREAM(x) SCM_PTAB_ENTRY(x)->stream | |
ee149d03 | 164 | #define SCM_SETSTREAM(x,s) (SCM_PTAB_ENTRY(x)->stream = (SCM) s) |
d14af9f2 | 165 | #define SCM_FILENAME(x) SCM_PTAB_ENTRY(x)->file_name |
0f2d19dd JB |
166 | #define SCM_LINUM(x) SCM_PTAB_ENTRY(x)->line_number |
167 | #define SCM_COL(x) SCM_PTAB_ENTRY(x)->column_number | |
168 | #define SCM_REVEALED(x) SCM_PTAB_ENTRY(x)->revealed | |
169 | #define SCM_SETREVEALED(x,s) (SCM_PTAB_ENTRY(x)->revealed = s) | |
0f2d19dd JB |
170 | |
171 | #define SCM_INCLINE(port) {SCM_LINUM (port) += 1; SCM_COL (port) = 0;} | |
172 | #define SCM_INCCOL(port) {SCM_COL (port) += 1;} | |
d14af9f2 | 173 | #define SCM_TABCOL(port) {SCM_COL (port) += 8 - SCM_COL (port) % 8;} |
0f2d19dd | 174 | |
0f2d19dd JB |
175 | \f |
176 | ||
affc96b5 | 177 | /* port-type description. */ |
f12733c9 | 178 | typedef struct scm_ptob_descriptor |
0f82baf6 | 179 | { |
f12733c9 | 180 | char *name; |
0c0669cc | 181 | SCM (*mark) (SCM); |
f12733c9 | 182 | scm_sizet (*free) (SCM); |
0c0669cc JB |
183 | int (*print) (SCM exp, SCM port, scm_print_state *pstate); |
184 | SCM (*equalp) (SCM, SCM); | |
affc96b5 GH |
185 | int (*close) (SCM port); |
186 | ||
31703ab8 | 187 | void (*write) (SCM port, void *data, size_t size); |
affc96b5 GH |
188 | void (*flush) (SCM port); |
189 | ||
190 | void (*end_input) (SCM port, int offset); | |
191 | int (*fill_input) (SCM port); | |
192 | int (*input_waiting) (SCM port); | |
193 | ||
ee149d03 | 194 | off_t (*seek) (SCM port, off_t OFFSET, int WHENCE); |
affc96b5 GH |
195 | void (*truncate) (SCM port, off_t length); |
196 | ||
f12733c9 | 197 | } scm_ptob_descriptor; |
0f82baf6 | 198 | |
f12733c9 MD |
199 | #define SCM_TC2PTOBNUM(x) (0x0ff & ((x) >> 8)) |
200 | #define SCM_PTOBNUM(x) (SCM_TC2PTOBNUM (SCM_CAR (x))) | |
201 | /* SCM_PTOBNAME can be 0 if name is missing */ | |
202 | #define SCM_PTOBNAME(ptobnum) scm_ptobs[ptobnum].name | |
0f82baf6 JB |
203 | |
204 | \f | |
205 | ||
f12733c9 | 206 | extern scm_ptob_descriptor *scm_ptobs; |
a1c95c45 | 207 | extern int scm_numptob; |
0f2d19dd JB |
208 | extern int scm_port_table_room; |
209 | ||
210 | \f | |
0f2d19dd | 211 | |
1717856b | 212 | extern SCM scm_markstream SCM_P ((SCM ptr)); |
f12733c9 | 213 | extern long scm_make_port_type (char *name, |
affc96b5 GH |
214 | int (*fill_input) (SCM port), |
215 | void (*write) (SCM port, void *data, | |
216 | size_t size)); | |
6c747373 MD |
217 | extern void scm_set_port_mark (long tc, SCM (*mark) (SCM)); |
218 | extern void scm_set_port_free (long tc, scm_sizet (*free) (SCM)); | |
219 | extern void scm_set_port_print (long tc, | |
f12733c9 MD |
220 | int (*print) (SCM exp, |
221 | SCM port, | |
222 | scm_print_state *pstate)); | |
6c747373 | 223 | extern void scm_set_port_equalp (long tc, SCM (*equalp) (SCM, SCM)); |
6c747373 | 224 | extern void scm_set_port_close (long tc, int (*close) (SCM)); |
affc96b5 GH |
225 | |
226 | extern void scm_set_port_flush (long tc, | |
227 | void (*flush) (SCM port)); | |
228 | extern void scm_set_port_end_input (long tc, | |
229 | void (*end_input) (SCM port, | |
230 | int offset)); | |
6c747373 | 231 | extern void scm_set_port_seek (long tc, |
f12733c9 MD |
232 | off_t (*seek) (SCM port, |
233 | off_t OFFSET, | |
234 | int WHENCE)); | |
6c747373 | 235 | extern void scm_set_port_truncate (long tc, |
f12733c9 MD |
236 | void (*truncate) (SCM port, |
237 | off_t length)); | |
affc96b5 | 238 | extern void scm_set_port_input_waiting (long tc, int (*input_waiting) (SCM)); |
1717856b | 239 | extern SCM scm_char_ready_p SCM_P ((SCM port)); |
ee149d03 | 240 | extern SCM scm_drain_input (SCM port); |
1717856b JB |
241 | extern SCM scm_current_input_port SCM_P ((void)); |
242 | extern SCM scm_current_output_port SCM_P ((void)); | |
243 | extern SCM scm_current_error_port SCM_P ((void)); | |
a1c95c45 | 244 | extern SCM scm_current_load_port SCM_P ((void)); |
1717856b JB |
245 | extern SCM scm_set_current_input_port SCM_P ((SCM port)); |
246 | extern SCM scm_set_current_output_port SCM_P ((SCM port)); | |
247 | extern SCM scm_set_current_error_port SCM_P ((SCM port)); | |
840ae05d | 248 | extern scm_port * scm_add_to_port_table SCM_P ((SCM port)); |
1717856b | 249 | extern void scm_remove_from_port_table SCM_P ((SCM port)); |
0855ef71 | 250 | extern void scm_grow_port_cbuf SCM_P ((SCM port, size_t requested)); |
1717856b JB |
251 | extern SCM scm_pt_size SCM_P ((void)); |
252 | extern SCM scm_pt_member SCM_P ((SCM member)); | |
253 | extern int scm_revealed_count SCM_P ((SCM port)); | |
254 | extern SCM scm_port_revealed SCM_P ((SCM port)); | |
255 | extern SCM scm_set_port_revealed_x SCM_P ((SCM port, SCM rcount)); | |
eadd48de GH |
256 | extern long scm_mode_bits SCM_P ((char *modes)); |
257 | extern SCM scm_port_mode SCM_P ((SCM port)); | |
1717856b JB |
258 | extern SCM scm_close_port SCM_P ((SCM port)); |
259 | extern SCM scm_close_all_ports_except SCM_P ((SCM ports)); | |
260 | extern SCM scm_input_port_p SCM_P ((SCM x)); | |
261 | extern SCM scm_output_port_p SCM_P ((SCM x)); | |
262 | extern SCM scm_eof_object_p SCM_P ((SCM x)); | |
263 | extern SCM scm_force_output SCM_P ((SCM port)); | |
89ea5b7c | 264 | extern SCM scm_flush_all_ports SCM_P ((void)); |
1717856b | 265 | extern SCM scm_read_char SCM_P ((SCM port)); |
265e6a4d | 266 | extern void scm_putc SCM_P ((char c, SCM port)); |
ee149d03 JB |
267 | extern void scm_puts SCM_P ((char *str_data, SCM port)); |
268 | extern void scm_lfwrite SCM_P ((char *ptr, scm_sizet size, SCM port)); | |
affc96b5 GH |
269 | extern void scm_flush SCM_P ((SCM port)); |
270 | extern void scm_end_input (SCM port); | |
271 | extern int scm_fill_input (SCM port); | |
ee149d03 JB |
272 | extern int scm_getc SCM_P ((SCM port)); |
273 | extern void scm_ungetc SCM_P ((int c, SCM port)); | |
274 | extern void scm_ungets SCM_P ((char *s, int n, SCM port)); | |
1717856b JB |
275 | extern SCM scm_peek_char SCM_P ((SCM port)); |
276 | extern SCM scm_unread_char SCM_P ((SCM cobj, SCM port)); | |
0855ef71 | 277 | extern SCM scm_unread_string SCM_P ((SCM str, SCM port)); |
848f2a01 | 278 | extern char *scm_generic_fgets SCM_P ((SCM port, int *len)); |
9cd4dfbb | 279 | extern SCM scm_seek (SCM object, SCM offset, SCM whence); |
69bc9ff3 | 280 | extern SCM scm_truncate_file (SCM object, SCM length); |
1717856b | 281 | extern SCM scm_port_line SCM_P ((SCM port)); |
a1c95c45 | 282 | extern SCM scm_set_port_line_x SCM_P ((SCM port, SCM line)); |
1717856b | 283 | extern SCM scm_port_column SCM_P ((SCM port)); |
a1c95c45 | 284 | extern SCM scm_set_port_column_x SCM_P ((SCM port, SCM line)); |
1717856b JB |
285 | extern SCM scm_port_filename SCM_P ((SCM port)); |
286 | extern SCM scm_set_port_filename_x SCM_P ((SCM port, SCM filename)); | |
f12733c9 MD |
287 | extern int scm_port_print (SCM exp, SCM port, scm_print_state *); |
288 | extern void scm_print_port_mode (SCM exp, SCM port); | |
1717856b JB |
289 | extern void scm_ports_prehistory SCM_P ((void)); |
290 | extern SCM scm_void_port SCM_P ((char * mode_str)); | |
291 | extern SCM scm_sys_make_void_port SCM_P ((SCM mode)); | |
292 | extern void scm_init_ports SCM_P ((void)); | |
0f2d19dd | 293 | |
f3667f52 JB |
294 | #ifdef GUILE_DEBUG |
295 | extern SCM scm_pt_size SCM_P ((void)); | |
296 | extern SCM scm_pt_member SCM_P ((SCM member)); | |
be1cd096 | 297 | #endif /* GUILE_DEBUG */ |
f3667f52 | 298 | |
0f2d19dd | 299 | #endif /* PORTSH */ |