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 | |
840ae05d JB |
58 | /* C representation of a Scheme port. */ |
59 | ||
60 | typedef struct | |
0f2d19dd | 61 | { |
ee149d03 | 62 | SCM port; /* Link back to the port object. */ |
0855ef71 | 63 | int entry; /* Index in port table. */ |
0f2d19dd JB |
64 | int revealed; /* 0 not revealed, > 1 revealed. |
65 | * Revealed ports do not get GC'd. | |
66 | */ | |
840ae05d JB |
67 | /* data for the underlying port implementation. may be an SCM cell or |
68 | cast to a pointer to C data. */ | |
0f2d19dd | 69 | SCM stream; |
0f2d19dd | 70 | |
0855ef71 | 71 | SCM file_name; /* debugging support. */ |
ebf7394e GH |
72 | int line_number; /* debugging support. */ |
73 | int column_number; /* debugging support. */ | |
0855ef71 | 74 | |
ee149d03 JB |
75 | /* port buffers. the buffer(s) are set up for all ports. |
76 | in the case of string ports, the buffer is the string itself. | |
77 | in the case of unbuffered file ports, the buffer is a | |
78 | single char: shortbuf. */ | |
79 | ||
80 | /* this buffer is filled from read_buf to read_end using the ptob | |
81 | buffer_fill. then input requests are taken from read_pos until | |
82 | it reaches read_end. */ | |
83 | ||
84 | unsigned char *read_buf; /* buffer start. */ | |
840ae05d | 85 | const unsigned char *read_pos;/* the next unread char. */ |
ee149d03 | 86 | unsigned char *read_end; /* pointer to last buffered char + 1. */ |
840ae05d | 87 | off_t read_buf_size; /* size of the buffer. */ |
ee149d03 | 88 | |
6c951427 GH |
89 | /* when chars are put back into the buffer, e.g., using peek-char or |
90 | unread-string, the read-buffer pointers are switched to cbuf. | |
91 | the original pointers are saved here and restored when the put-back | |
92 | chars have been consumed. */ | |
93 | unsigned char *saved_read_buf; | |
94 | const unsigned char *saved_read_pos; | |
95 | unsigned char *saved_read_end; | |
96 | off_t saved_read_buf_size; | |
97 | ||
ee149d03 JB |
98 | /* write requests are saved into this buffer at write_pos until it |
99 | reaches write_buf + write_buf_size, then the ptob flush is | |
100 | called. */ | |
101 | ||
6c951427 | 102 | unsigned char *write_buf; /* buffer start. */ |
ee149d03 JB |
103 | unsigned char *write_pos; /* pointer to last buffered char + 1. */ |
104 | unsigned char *write_end; /* pointer to end of buffer + 1. */ | |
840ae05d | 105 | off_t write_buf_size; /* size of the buffer. */ |
ee149d03 JB |
106 | |
107 | unsigned char shortbuf; /* buffer for "unbuffered" streams. */ | |
108 | ||
840ae05d JB |
109 | int rw_random; /* true if the port is bidirectional and |
110 | random access. implies that the buffers | |
111 | must be flushed before switching between | |
112 | reading and writing. */ | |
113 | ||
114 | int rw_active; /* for bidirectional random ports, indicates | |
115 | which of the buffers is currently in use. | |
116 | can be SCM_PORT_WRITE, SCM_PORT_READ, | |
117 | or 0. */ | |
ee149d03 | 118 | |
6c951427 GH |
119 | /* a buffer for un-read chars and strings. */ |
120 | unsigned char *putback_buf; | |
121 | int putback_buf_size; /* allocated size of putback_buf. */ | |
840ae05d JB |
122 | } scm_port; |
123 | ||
124 | /* values for the rw_active flag. */ | |
125 | #define SCM_PORT_READ 1 | |
126 | #define SCM_PORT_WRITE 2 | |
0f2d19dd | 127 | |
840ae05d | 128 | extern scm_port **scm_port_table; |
0f82baf6 | 129 | extern int scm_port_table_size; /* Number of ports in scm_port_table. */ |
0f2d19dd JB |
130 | |
131 | ||
132 | \f | |
133 | ||
0c32d76c MD |
134 | #define SCM_EOF_OBJECT_P(x) ((x) == SCM_EOF_VAL) |
135 | ||
0f2d19dd | 136 | /* PORT FLAGS |
dbece3a2 | 137 | * A set of flags characterizes a port. |
571031dc JB |
138 | * Note that we reserve the bits 1 << 24 and above for use by the |
139 | * routines in the port's scm_ptobfuns structure. | |
0f2d19dd JB |
140 | */ |
141 | #define SCM_OPN (1L<<16) /* Is the port open? */ | |
142 | #define SCM_RDNG (2L<<16) /* Is it a readable port? */ | |
143 | #define SCM_WRTNG (4L<<16) /* Is it writable? */ | |
ee149d03 | 144 | #define SCM_BUF0 (8L<<16) /* Is it unbuffered? */ |
6c951427 | 145 | /* #define SCM_CRDY (32L<<16) obsolete, for pushed back characters */ |
ee149d03 | 146 | #define SCM_BUFLINE (64L<<16) /* Is it line-buffered? */ |
0f2d19dd | 147 | |
0f2d19dd JB |
148 | #define SCM_PORTP(x) (SCM_TYP7(x)==scm_tc7_port) |
149 | #define SCM_OPPORTP(x) (((0x7f | SCM_OPN) & SCM_CAR(x))==(scm_tc7_port | SCM_OPN)) | |
150 | #define SCM_OPINPORTP(x) (((0x7f | SCM_OPN | SCM_RDNG) & SCM_CAR(x))==(scm_tc7_port | SCM_OPN | SCM_RDNG)) | |
151 | #define SCM_OPOUTPORTP(x) (((0x7f | SCM_OPN | SCM_WRTNG) & SCM_CAR(x))==(scm_tc7_port | SCM_OPN | SCM_WRTNG)) | |
0f2d19dd JB |
152 | #define SCM_INPORTP(x) (((0x7f | SCM_RDNG) & SCM_CAR(x))==(scm_tc7_port | SCM_RDNG)) |
153 | #define SCM_OUTPORTP(x) (((0x7f | SCM_WRTNG) & SCM_CAR(x))==(scm_tc7_port | SCM_WRTNG)) | |
154 | #define SCM_OPENP(x) (SCM_OPN & SCM_CAR(x)) | |
155 | #define SCM_CLOSEDP(x) (!SCM_OPENP(x)) | |
840ae05d | 156 | #define SCM_PTAB_ENTRY(x) ((scm_port *) SCM_CDR(x)) |
0f2d19dd JB |
157 | #define SCM_SETPTAB_ENTRY(x,ent) SCM_SETCDR ((x), (SCM)(ent)) |
158 | #define SCM_STREAM(x) SCM_PTAB_ENTRY(x)->stream | |
ee149d03 | 159 | #define SCM_SETSTREAM(x,s) (SCM_PTAB_ENTRY(x)->stream = (SCM) s) |
d14af9f2 | 160 | #define SCM_FILENAME(x) SCM_PTAB_ENTRY(x)->file_name |
0f2d19dd JB |
161 | #define SCM_LINUM(x) SCM_PTAB_ENTRY(x)->line_number |
162 | #define SCM_COL(x) SCM_PTAB_ENTRY(x)->column_number | |
163 | #define SCM_REVEALED(x) SCM_PTAB_ENTRY(x)->revealed | |
164 | #define SCM_SETREVEALED(x,s) (SCM_PTAB_ENTRY(x)->revealed = s) | |
0f2d19dd JB |
165 | |
166 | #define SCM_INCLINE(port) {SCM_LINUM (port) += 1; SCM_COL (port) = 0;} | |
167 | #define SCM_INCCOL(port) {SCM_COL (port) += 1;} | |
d14af9f2 | 168 | #define SCM_TABCOL(port) {SCM_COL (port) += 8 - SCM_COL (port) % 8;} |
0f2d19dd | 169 | |
0f2d19dd JB |
170 | \f |
171 | ||
affc96b5 | 172 | /* port-type description. */ |
f12733c9 | 173 | typedef struct scm_ptob_descriptor |
0f82baf6 | 174 | { |
f12733c9 | 175 | char *name; |
0c0669cc | 176 | SCM (*mark) (SCM); |
f12733c9 | 177 | scm_sizet (*free) (SCM); |
0c0669cc JB |
178 | int (*print) (SCM exp, SCM port, scm_print_state *pstate); |
179 | SCM (*equalp) (SCM, SCM); | |
affc96b5 GH |
180 | int (*close) (SCM port); |
181 | ||
31703ab8 | 182 | void (*write) (SCM port, void *data, size_t size); |
affc96b5 GH |
183 | void (*flush) (SCM port); |
184 | ||
185 | void (*end_input) (SCM port, int offset); | |
186 | int (*fill_input) (SCM port); | |
187 | int (*input_waiting) (SCM port); | |
188 | ||
ee149d03 | 189 | off_t (*seek) (SCM port, off_t OFFSET, int WHENCE); |
affc96b5 GH |
190 | void (*truncate) (SCM port, off_t length); |
191 | ||
f12733c9 | 192 | } scm_ptob_descriptor; |
0f82baf6 | 193 | |
f12733c9 MD |
194 | #define SCM_TC2PTOBNUM(x) (0x0ff & ((x) >> 8)) |
195 | #define SCM_PTOBNUM(x) (SCM_TC2PTOBNUM (SCM_CAR (x))) | |
196 | /* SCM_PTOBNAME can be 0 if name is missing */ | |
197 | #define SCM_PTOBNAME(ptobnum) scm_ptobs[ptobnum].name | |
0f82baf6 JB |
198 | |
199 | \f | |
200 | ||
f12733c9 | 201 | extern scm_ptob_descriptor *scm_ptobs; |
a1c95c45 | 202 | extern int scm_numptob; |
0f2d19dd JB |
203 | extern int scm_port_table_room; |
204 | ||
205 | \f | |
0f2d19dd | 206 | |
1717856b | 207 | extern SCM scm_markstream SCM_P ((SCM ptr)); |
f12733c9 | 208 | extern long scm_make_port_type (char *name, |
affc96b5 GH |
209 | int (*fill_input) (SCM port), |
210 | void (*write) (SCM port, void *data, | |
211 | size_t size)); | |
6c747373 MD |
212 | extern void scm_set_port_mark (long tc, SCM (*mark) (SCM)); |
213 | extern void scm_set_port_free (long tc, scm_sizet (*free) (SCM)); | |
214 | extern void scm_set_port_print (long tc, | |
f12733c9 MD |
215 | int (*print) (SCM exp, |
216 | SCM port, | |
217 | scm_print_state *pstate)); | |
6c747373 | 218 | extern void scm_set_port_equalp (long tc, SCM (*equalp) (SCM, SCM)); |
6c747373 | 219 | extern void scm_set_port_close (long tc, int (*close) (SCM)); |
affc96b5 GH |
220 | |
221 | extern void scm_set_port_flush (long tc, | |
222 | void (*flush) (SCM port)); | |
223 | extern void scm_set_port_end_input (long tc, | |
224 | void (*end_input) (SCM port, | |
225 | int offset)); | |
6c747373 | 226 | extern void scm_set_port_seek (long tc, |
f12733c9 MD |
227 | off_t (*seek) (SCM port, |
228 | off_t OFFSET, | |
229 | int WHENCE)); | |
6c747373 | 230 | extern void scm_set_port_truncate (long tc, |
f12733c9 MD |
231 | void (*truncate) (SCM port, |
232 | off_t length)); | |
affc96b5 | 233 | extern void scm_set_port_input_waiting (long tc, int (*input_waiting) (SCM)); |
1717856b | 234 | extern SCM scm_char_ready_p SCM_P ((SCM port)); |
ee149d03 | 235 | extern SCM scm_drain_input (SCM port); |
1717856b JB |
236 | extern SCM scm_current_input_port SCM_P ((void)); |
237 | extern SCM scm_current_output_port SCM_P ((void)); | |
238 | extern SCM scm_current_error_port SCM_P ((void)); | |
a1c95c45 | 239 | extern SCM scm_current_load_port SCM_P ((void)); |
1717856b JB |
240 | extern SCM scm_set_current_input_port SCM_P ((SCM port)); |
241 | extern SCM scm_set_current_output_port SCM_P ((SCM port)); | |
242 | extern SCM scm_set_current_error_port SCM_P ((SCM port)); | |
840ae05d | 243 | extern scm_port * scm_add_to_port_table SCM_P ((SCM port)); |
1717856b | 244 | extern void scm_remove_from_port_table SCM_P ((SCM port)); |
0855ef71 | 245 | extern void scm_grow_port_cbuf SCM_P ((SCM port, size_t requested)); |
1717856b JB |
246 | extern SCM scm_pt_size SCM_P ((void)); |
247 | extern SCM scm_pt_member SCM_P ((SCM member)); | |
248 | extern int scm_revealed_count SCM_P ((SCM port)); | |
249 | extern SCM scm_port_revealed SCM_P ((SCM port)); | |
250 | extern SCM scm_set_port_revealed_x SCM_P ((SCM port, SCM rcount)); | |
eadd48de GH |
251 | extern long scm_mode_bits SCM_P ((char *modes)); |
252 | extern SCM scm_port_mode SCM_P ((SCM port)); | |
1717856b JB |
253 | extern SCM scm_close_port SCM_P ((SCM port)); |
254 | extern SCM scm_close_all_ports_except SCM_P ((SCM ports)); | |
255 | extern SCM scm_input_port_p SCM_P ((SCM x)); | |
256 | extern SCM scm_output_port_p SCM_P ((SCM x)); | |
257 | extern SCM scm_eof_object_p SCM_P ((SCM x)); | |
258 | extern SCM scm_force_output SCM_P ((SCM port)); | |
89ea5b7c | 259 | extern SCM scm_flush_all_ports SCM_P ((void)); |
1717856b | 260 | extern SCM scm_read_char SCM_P ((SCM port)); |
265e6a4d | 261 | extern void scm_putc SCM_P ((char c, SCM port)); |
ee149d03 JB |
262 | extern void scm_puts SCM_P ((char *str_data, SCM port)); |
263 | extern void scm_lfwrite SCM_P ((char *ptr, scm_sizet size, SCM port)); | |
affc96b5 GH |
264 | extern void scm_flush SCM_P ((SCM port)); |
265 | extern void scm_end_input (SCM port); | |
266 | extern int scm_fill_input (SCM port); | |
ee149d03 JB |
267 | extern int scm_getc SCM_P ((SCM port)); |
268 | extern void scm_ungetc SCM_P ((int c, SCM port)); | |
269 | extern void scm_ungets SCM_P ((char *s, int n, SCM port)); | |
1717856b JB |
270 | extern SCM scm_peek_char SCM_P ((SCM port)); |
271 | extern SCM scm_unread_char SCM_P ((SCM cobj, SCM port)); | |
0855ef71 | 272 | extern SCM scm_unread_string SCM_P ((SCM str, SCM port)); |
848f2a01 | 273 | extern char *scm_generic_fgets SCM_P ((SCM port, int *len)); |
840ae05d | 274 | extern SCM scm_lseek (SCM object, SCM offset, SCM whence); |
69bc9ff3 | 275 | extern SCM scm_truncate_file (SCM object, SCM length); |
1717856b | 276 | extern SCM scm_port_line SCM_P ((SCM port)); |
a1c95c45 | 277 | extern SCM scm_set_port_line_x SCM_P ((SCM port, SCM line)); |
1717856b | 278 | extern SCM scm_port_column SCM_P ((SCM port)); |
a1c95c45 | 279 | extern SCM scm_set_port_column_x SCM_P ((SCM port, SCM line)); |
1717856b JB |
280 | extern SCM scm_port_filename SCM_P ((SCM port)); |
281 | extern SCM scm_set_port_filename_x SCM_P ((SCM port, SCM filename)); | |
f12733c9 MD |
282 | extern int scm_port_print (SCM exp, SCM port, scm_print_state *); |
283 | extern void scm_print_port_mode (SCM exp, SCM port); | |
1717856b JB |
284 | extern void scm_ports_prehistory SCM_P ((void)); |
285 | extern SCM scm_void_port SCM_P ((char * mode_str)); | |
286 | extern SCM scm_sys_make_void_port SCM_P ((SCM mode)); | |
287 | extern void scm_init_ports SCM_P ((void)); | |
0f2d19dd | 288 | |
f3667f52 JB |
289 | #ifdef GUILE_DEBUG |
290 | extern SCM scm_pt_size SCM_P ((void)); | |
291 | extern SCM scm_pt_member SCM_P ((SCM member)); | |
be1cd096 | 292 | #endif /* GUILE_DEBUG */ |
f3667f52 | 293 | |
0f2d19dd | 294 | #endif /* PORTSH */ |